Merge "DO NOT MERGE Test: .ActivityManagerAmStartOptionsTests: Waiting for SingleTaskActivity transition idle" into pie-cts-dev
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 9910810..ce2dc33 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1965,7 +1965,7 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_notifications" />
             <meta-data android:name="test_excluded_features"
-                       android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
+                       android:value="android.hardware.type.automotive:android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
         </activity>
 
         <activity android:name=".notifications.AttentionManagementVerifierActivity"
diff --git a/apps/CtsVerifier/proguard.flags b/apps/CtsVerifier/proguard.flags
index 1bf1a0b..2be1211 100644
--- a/apps/CtsVerifier/proguard.flags
+++ b/apps/CtsVerifier/proguard.flags
@@ -20,6 +20,9 @@
 
 -keepclasseswithmembers class * extends com.android.cts.verifier.location.LocationModeTestActivity
 
+-keepclasseswithmembers class * extends com.android.cts.verifier.audio.HifiUltrasoundSpeakerTestActivity
+-keepclasseswithmembers class * extends com.android.cts.verifier.audio.HifiUltrasoundTestActivity
+
 # keep mockito methods
 -keep class org.mockito.** { *; }
 -keep interface org.mockito.** { *; }
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 6d827eb..f0f0b7e 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -444,10 +444,7 @@
     <string name="ble_scan_stop">Stop scan</string>
 
     <!-- BLE connection priority test strings -->
-    <string name="ble_client_connection_priority">Testing priority: </string>
-    <string name="ble_connection_priority_balanced">BALANCED</string>
-    <string name="ble_connection_priority_high">HIGH</string>
-    <string name="ble_connection_priority_low">LOW</string>
+    <string name="ble_client_connection_priority">Testing connection priority switching </string>
     <string name="ble_server_connection_priority_result_passed">All test passed</string>
     <string name="ble_server_connection_priority_result_failed">Test failed.</string>
     <string name="ble_server_connection_priority_result_intervals">
@@ -470,9 +467,7 @@
     <string name="ble_write_authenticated_characteristic_name">Bluetooth LE Write Encrypted Characteristic</string>
     <string name="ble_read_authenticated_descriptor_name">Bluetooth LE Read Encrypted Descriptor</string>
     <string name="ble_write_authenticated_descriptor_name">Bluetooth LE Write Encrypted Descriptor</string>
-    <string name="ble_connection_priority_client_high">Bluetooth LE Send With CONNECTION_PRIORITY_HIGH</string>
-    <string name="ble_connection_priority_client_low">Bluetooth LE Send With CONNECTION_PRIORITY_LOW_POWER</string>
-    <string name="ble_connection_priority_client_balanced">Bluetooth LE Send With CONNECTION_PRIORITY_BALANCED</string>
+    <string name="ble_connection_priority_client_description">Client Switching Connection Priority</string>
     <string name="ble_indicate_characteristic_name">Bluetooth LE Indicate Characteristic</string>
     <string name="ble_encrypted_client_name">03 Bluetooth LE Encrypted Client Test</string>
     <string name="ble_encrypted_client_info">Bluetooth LE Encrypted Client read/write on characteristic and descriptor need encrypted.</string>
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml
index 9c6de77..dd18236 100644
--- a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml
@@ -3,4 +3,4 @@
         linePaint.strokeWidth="3dp"
         linePaint.color="#AA0000"
         vertexPaint.color="#770000"
-        fillPaint.color="#00000000" />
+        fillPaint.color="#770000" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml
index 8fb236e..0f27503 100644
--- a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml
@@ -3,4 +3,4 @@
         linePaint.strokeWidth="2dp"
         linePaint.color="#777777"
         vertexPaint.color="777777"
-        fillPaint.color="#00000000" />
+        fillPaint.color="#770000" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml
index 9a6c29a..011f20b 100644
--- a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml
@@ -3,4 +3,4 @@
         linePaint.strokeWidth="2dp"
         linePaint.color="#007700"
         vertexPaint.color="#007700"
-        fillPaint.color="#00000000" />
+        fillPaint.color="#880000" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml
index 3f9ffc2..ce09dfb 100644
--- a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <config
-        linePaint.strokeWidth="1dp"
-        linePaint.color="#AAAAAA"
-        vertexPaint.color="#777777"
-        fillPaint.color="#00000000" />
+        linePaint.strokeWidth="3dp"
+        linePaint.color="#00AA00"
+        vertexPaint.color="#007700"
+        fillPaint.color="#00ff00"
+        pointLabelFormatter.textPaint.color="#FFFFFF"/>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
index 1a9ffac..87618b1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
@@ -37,9 +37,12 @@
 import android.widget.TextView;
 import java.util.Arrays;
 
+import com.androidplot.xy.PointLabelFormatter;
+import com.androidplot.xy.LineAndPointFormatter;
 import com.androidplot.xy.SimpleXYSeries;
+import com.androidplot.xy.XYPlot;
 import com.androidplot.xy.XYSeries;
-import com.androidplot.xy.*;
+import com.androidplot.xy.XYStepMode;
 
 import com.android.compatibility.common.util.CddTest;
 
@@ -279,7 +282,7 @@
         LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
         seriesFormat.configure(getApplicationContext(),
             R.xml.ultrasound_line_formatter_trials);
-        seriesFormat.setPointLabelFormatter(null);
+        seriesFormat.setPointLabelFormatter(new PointLabelFormatter());
         plot.addSeries(series, seriesFormat);
       }
 
@@ -296,7 +299,7 @@
       LineAndPointFormatter noiseSeriesFormat = new LineAndPointFormatter();
       noiseSeriesFormat.configure(getApplicationContext(),
           R.xml.ultrasound_line_formatter_noise);
-      noiseSeriesFormat.setPointLabelFormatter(null);
+      noiseSeriesFormat.setPointLabelFormatter(new PointLabelFormatter());
       plot.addSeries(noiseSeries, noiseSeriesFormat);
 
       double[] dB = wavAnalyzerTask.getDB();
@@ -312,7 +315,7 @@
       LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
       seriesFormat.configure(getApplicationContext(),
           R.xml.ultrasound_line_formatter_median);
-      seriesFormat.setPointLabelFormatter(null);
+      seriesFormat.setPointLabelFormatter(new PointLabelFormatter());
       plot.addSeries(series, seriesFormat);
 
       Double[] passX = new Double[] {Common.MIN_FREQUENCY_HZ, Common.MAX_FREQUENCY_HZ};
@@ -322,7 +325,7 @@
       LineAndPointFormatter passSeriesFormat = new LineAndPointFormatter();
       passSeriesFormat.configure(getApplicationContext(),
           R.xml.ultrasound_line_formatter_pass);
-      passSeriesFormat.setPointLabelFormatter(null);
+      passSeriesFormat.setPointLabelFormatter(new PointLabelFormatter());
       plot.addSeries(passSeries, passSeriesFormat);
     }
   }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java
index 0276e60..9aebbc4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java
@@ -37,9 +37,12 @@
 import android.widget.TextView;
 import java.util.Arrays;
 
+import com.androidplot.xy.PointLabelFormatter;
+import com.androidplot.xy.LineAndPointFormatter;
 import com.androidplot.xy.SimpleXYSeries;
+import com.androidplot.xy.XYPlot;
 import com.androidplot.xy.XYSeries;
-import com.androidplot.xy.*;
+import com.androidplot.xy.XYStepMode;
 
 public class HifiUltrasoundTestActivity extends PassFailButtons.Activity {
 
@@ -236,9 +239,9 @@
             Arrays.asList(powerWrap),
             "");
         LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
+        seriesFormat.setPointLabelFormatter(new PointLabelFormatter());
         seriesFormat.configure(getApplicationContext(),
             R.xml.ultrasound_line_formatter_trials);
-        seriesFormat.setPointLabelFormatter(null);
         plot.addSeries(series, seriesFormat);
       }
 
@@ -253,9 +256,9 @@
           Arrays.asList(noiseDBWrap),
           "background noise");
       LineAndPointFormatter noiseSeriesFormat = new LineAndPointFormatter();
+      noiseSeriesFormat.setPointLabelFormatter(new PointLabelFormatter());
       noiseSeriesFormat.configure(getApplicationContext(),
           R.xml.ultrasound_line_formatter_noise);
-      noiseSeriesFormat.setPointLabelFormatter(null);
       plot.addSeries(noiseSeries, noiseSeriesFormat);
 
       double[] dB = wavAnalyzerTask.getDB();
@@ -269,9 +272,9 @@
           Arrays.asList(dBWrap),
           "median");
       LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
+      seriesFormat.setPointLabelFormatter(new PointLabelFormatter());
       seriesFormat.configure(getApplicationContext(),
           R.xml.ultrasound_line_formatter_median);
-      seriesFormat.setPointLabelFormatter(null);
       plot.addSeries(series, seriesFormat);
 
       Double[] passX = new Double[] {Common.MIN_FREQUENCY_HZ, Common.MAX_FREQUENCY_HZ};
@@ -279,9 +282,9 @@
       XYSeries passSeries = new SimpleXYSeries(
           Arrays.asList(passX), Arrays.asList(passY), "passing");
       LineAndPointFormatter passSeriesFormat = new LineAndPointFormatter();
+      passSeriesFormat.setPointLabelFormatter(new PointLabelFormatter());
       passSeriesFormat.configure(getApplicationContext(),
           R.xml.ultrasound_line_formatter_pass);
-      passSeriesFormat.setPointLabelFormatter(null);
       plot.addSeries(passSeries, passSeriesFormat);
     }
   }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientBaseActivity.java
index 47ea81f..9119aae 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientBaseActivity.java
@@ -40,17 +40,12 @@
 public class BleConnectionPriorityClientBaseActivity extends PassFailButtons.Activity {

 

     private TestAdapter mTestAdapter;

-    private int mPassed = 0;

+    private boolean mPassed = false;

     private Dialog mDialog;

 

-    private static final int BLE_CONNECTION_HIGH = 0;

-    private static final int BLE_CONNECTION_BALANCED = 1;

-    private static final int BLE_CONNECTION_LOW = 2;

+    private static final int BLE_CONNECTION_UPDATE = 0;

 

-    private static final int PASSED_HIGH = 0x1;

-    private static final int PASSED_BALANCED = 0x2;

-    private static final int PASSED_LOW = 0x4;

-    private static final int ALL_PASSED = 0x7;

+    private static final int ALL_PASSED = 0x1;

 

     private boolean mSecure;

 

@@ -80,9 +75,7 @@
         IntentFilter filter = new IntentFilter();

         filter.addAction(BleConnectionPriorityClientService.ACTION_BLUETOOTH_DISABLED);

         filter.addAction(BleConnectionPriorityClientService.ACTION_CONNECTION_SERVICES_DISCOVERED);

-        filter.addAction(BleConnectionPriorityClientService.ACTION_FINISH_CONNECTION_PRIORITY_HIGH);

-        filter.addAction(BleConnectionPriorityClientService.ACTION_FINISH_CONNECTION_PRIORITY_BALANCED);

-        filter.addAction(BleConnectionPriorityClientService.ACTION_FINISH_CONNECTION_PRIORITY_LOW_POWER);

+        filter.addAction(BleConnectionPriorityClientService.ACTION_CONNECTION_PRIORITY_FINISH);

         filter.addAction(BleConnectionPriorityClientService.ACTION_BLUETOOTH_MISMATCH_SECURE);

         filter.addAction(BleConnectionPriorityClientService.ACTION_BLUETOOTH_MISMATCH_INSECURE);

         filter.addAction(BleConnectionPriorityClientService.ACTION_FINISH_DISCONNECT);

@@ -140,9 +133,7 @@
 

     private List<Integer> setupTestList() {

         ArrayList<Integer> testList = new ArrayList<Integer>();

-        testList.add(R.string.ble_connection_priority_client_high);

-        testList.add(R.string.ble_connection_priority_client_balanced);

-        testList.add(R.string.ble_connection_priority_client_low);

+        testList.add(R.string.ble_connection_priority_client_description);

         return testList;

     }

 

@@ -157,44 +148,24 @@
     private void executeNextTestImpl() {

         switch (mCurrentTest) {

             case -1: {

-                mCurrentTest = BLE_CONNECTION_HIGH;

+                mCurrentTest = BLE_CONNECTION_UPDATE;

                 Intent intent = new Intent(this, BleConnectionPriorityClientService.class);

-                intent.setAction(BleConnectionPriorityClientService.ACTION_CONNECTION_PRIORITY_HIGH);

+                intent.setAction(BleConnectionPriorityClientService.ACTION_CONNECTION_PRIORITY_START);

                 startService(intent);

-                String msg = getString(R.string.ble_client_connection_priority)

-                        + getString(R.string.ble_connection_priority_high);

+                String msg = getString(R.string.ble_client_connection_priority);

                 Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();

             }

                 break;

-            case BLE_CONNECTION_BALANCED: {

-                mCurrentTest = BLE_CONNECTION_LOW;

-                Intent intent = new Intent(this, BleConnectionPriorityClientService.class);

-                intent.setAction(BleConnectionPriorityClientService.ACTION_CONNECTION_PRIORITY_LOW_POWER);

-                startService(intent);

-                String msg = getString(R.string.ble_client_connection_priority)

-                        + getString(R.string.ble_connection_priority_low);

-                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();

-            }

-                break;

-            case BLE_CONNECTION_HIGH: {

-                mCurrentTest = BLE_CONNECTION_BALANCED;

-                Intent intent = new Intent(this, BleConnectionPriorityClientService.class);

-                intent.setAction(BleConnectionPriorityClientService.ACTION_CONNECTION_PRIORITY_BALANCED);

-                startService(intent);

-                String msg = getString(R.string.ble_client_connection_priority)

-                        + getString(R.string.ble_connection_priority_balanced);

-                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();

-            }

-                break;

-            case BLE_CONNECTION_LOW:

+            case BLE_CONNECTION_UPDATE: {

                 // all test done

                 closeDialog();

-                if (mPassed == ALL_PASSED) {

+                if (mPassed == true) {

                     Intent intent = new Intent(this, BleConnectionPriorityClientService.class);

                     intent.setAction(BleConnectionPriorityClientService.ACTION_DISCONNECT);

                     startService(intent);

                 }

                 break;

+            }

             default:

                 // something went wrong

                 closeDialog();

@@ -227,21 +198,11 @@
                 showProgressDialog();

                 executeNextTest(3000);

                 break;

-            case BleConnectionPriorityClientService.ACTION_FINISH_CONNECTION_PRIORITY_HIGH:

-                mTestAdapter.setTestPass(BLE_CONNECTION_HIGH);

-                mPassed |= PASSED_HIGH;

+            case BleConnectionPriorityClientService.ACTION_CONNECTION_PRIORITY_FINISH:

+                mTestAdapter.setTestPass(BLE_CONNECTION_UPDATE);

+                mPassed = true;

                 executeNextTest(1000);

                 break;

-            case BleConnectionPriorityClientService.ACTION_FINISH_CONNECTION_PRIORITY_BALANCED:

-                mTestAdapter.setTestPass(BLE_CONNECTION_BALANCED);

-                mPassed |= PASSED_BALANCED;

-                executeNextTest(1000);

-                break;

-            case BleConnectionPriorityClientService.ACTION_FINISH_CONNECTION_PRIORITY_LOW_POWER:

-                mTestAdapter.setTestPass(BLE_CONNECTION_LOW);

-                mPassed |= PASSED_LOW;

-                executeNextTest(100);

-                break;

             case BleConnectionPriorityClientService.ACTION_BLUETOOTH_MISMATCH_SECURE:

                 showErrorDialog(R.string.ble_bluetooth_mismatch_title, R.string.ble_bluetooth_mismatch_secure_message, true);

                 break;

diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientService.java
index 38d37bd..1df40f5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityClientService.java
@@ -62,19 +62,11 @@
     public static final String ACTION_BLUETOOTH_MISMATCH_INSECURE =

             "com.android.cts.verifier.bluetooth.action.ACTION_BLUETOOTH_MISMATCH_INSECURE";

 

-    public static final String ACTION_CONNECTION_PRIORITY_BALANCED =

-            "com.android.cts.verifier.bluetooth.action.CONNECTION_PRIORITY_BALANCED";

-    public static final String ACTION_CONNECTION_PRIORITY_HIGH =

-            "com.android.cts.verifier.bluetooth.action.CONNECTION_PRIORITY_HIGH";

-    public static final String ACTION_CONNECTION_PRIORITY_LOW_POWER =

+    public static final String ACTION_CONNECTION_PRIORITY_START =

             "com.android.cts.verifier.bluetooth.action.CONNECTION_PRIORITY_LOW_POWER";

 

-    public static final String ACTION_FINISH_CONNECTION_PRIORITY_BALANCED =

-            "com.android.cts.verifier.bluetooth.action.FINISH_CONNECTION_PRIORITY_BALANCED";

-    public static final String ACTION_FINISH_CONNECTION_PRIORITY_HIGH =

-            "com.android.cts.verifier.bluetooth.action.FINISH_CONNECTION_PRIORITY_HIGH";

-    public static final String ACTION_FINISH_CONNECTION_PRIORITY_LOW_POWER =

-            "com.android.cts.verifier.bluetooth.action.FINISH_CONNECTION_PRIORITY_LOW_POWER";

+    public static final String ACTION_CONNECTION_PRIORITY_FINISH =

+            "com.android.cts.verifier.bluetooth.action.CONNECTION_PRIORITY_FINISH";

 

     public static final String ACTION_CLIENT_CONNECT_SECURE =

             "com.android.cts.verifier.bluetooth.action.CLIENT_CONNECT_SECURE";

@@ -84,20 +76,7 @@
     public static final String ACTION_FINISH_DISCONNECT =

             "com.android.cts.verifier.bluetooth.action.FINISH_DISCONNECT";

 

-    public static final long DEFAULT_INTERVAL = 100L;

-    public static final long DEFAULT_PERIOD = 10000L;

-

-    // this string will be used at writing test and connection priority test.

-    private static final String WRITE_VALUE = "TEST";

-

-    private static final UUID SERVICE_UUID =

-            UUID.fromString("00009999-0000-1000-8000-00805f9b34fb");

-    private static final UUID CHARACTERISTIC_UUID =

-            UUID.fromString("00009998-0000-1000-8000-00805f9b34fb");

-    private static final UUID START_CHARACTERISTIC_UUID =

-            UUID.fromString("00009997-0000-1000-8000-00805f9b34fb");

-    private static final UUID STOP_CHARACTERISTIC_UUID =

-            UUID.fromString("00009995-0000-1000-8000-00805f9b34fb");

+    public static final int NOT_UNDER_TEST = -1;

 

     private BluetoothManager mBluetoothManager;

     private BluetoothAdapter mBluetoothAdapter;

@@ -108,13 +87,12 @@
     private Context mContext;

 

     private String mAction;

-    private long mInterval;

-    private long mPeriod;

-    private Date mStartDate;

-    private int mWriteCount;

     private boolean mSecure;

 

-    private String mPriority;

+    private int mPriority = NOT_UNDER_TEST;

+    private int interval_low = 0;

+    private int interval_balanced = 0;

+    private int interval_high = 0;

 

     private TestTaskQueue mTaskQueue;

 

@@ -129,8 +107,6 @@
         mScanner = mBluetoothAdapter.getBluetoothLeScanner();

         mHandler = new Handler();

         mContext = this;

-        mInterval = DEFAULT_INTERVAL;

-        mPeriod = DEFAULT_PERIOD;

 

         startScan();

     }

@@ -171,15 +147,8 @@
                 case ACTION_CLIENT_CONNECT_SECURE:

                     mSecure = true;

                     break;

-                case ACTION_CONNECTION_PRIORITY_BALANCED:

-                case ACTION_CONNECTION_PRIORITY_HIGH:

-                case ACTION_CONNECTION_PRIORITY_LOW_POWER:

-                    mTaskQueue.addTask(new Runnable() {

-                        @Override

-                        public void run() {

-                            startPeriodicTransmission();

-                        }

-                    });

+                case ACTION_CONNECTION_PRIORITY_START:

+                    myRequestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER);

                     break;

                 case ACTION_DISCONNECT:

                     if (mBluetoothGatt != null) {

@@ -194,120 +163,17 @@
         return START_NOT_STICKY;

     }

 

-    private void startPeriodicTransmission() {

-        mWriteCount = 0;

-

-        // Set connection priority

-        switch (mAction) {

-        case ACTION_CONNECTION_PRIORITY_BALANCED:

-            mPriority = BleConnectionPriorityServerService.CONNECTION_PRIORITY_BALANCED;

-            mBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_BALANCED);

-            break;

-        case ACTION_CONNECTION_PRIORITY_HIGH:

-            mPriority = BleConnectionPriorityServerService.CONNECTION_PRIORITY_HIGH;

-            mBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);

-            break;

-        case ACTION_CONNECTION_PRIORITY_LOW_POWER:

-            mPriority = BleConnectionPriorityServerService.CONNECTION_PRIORITY_LOW_POWER;

-            mBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER);

-            break;

-        default:

-            mPriority = BleConnectionPriorityServerService.CONNECTION_PRIORITY_BALANCED;

-            mBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_BALANCED);

-            break;

-        }

-

-        // Create Timer for Periodic transmission

-        mStartDate = new Date();

-        TimerTask task = new TimerTask() {

-            @Override

-            public void run() {

-                if (mBluetoothGatt == null) {

-                    if (DEBUG) {

-                        Log.d(TAG, "BluetoothGatt is null, return");

-                    }

-                    return;

-                }

-

-                Date currentData = new Date();

-                if ((currentData.getTime() - mStartDate.getTime()) >= mPeriod) {

-                    if (mConnectionTimer != null) {

-                        mConnectionTimer.cancel();

-                        mConnectionTimer = null;

-                    }

-                    // The STOP_CHARACTERISTIC_UUID is critical in syncing the client and server

-                    // states.  Delay the write by 2 seconds to improve the chance of this

-                    // characteristic going through.  Consider changing the code to use callbacks

-                    // in the future to make it more robust.

-                    sleep(2000);

-                    // write termination data (contains current priority and number of messages wrote)

-                    String msg = "" + mPriority + "," + mWriteCount;

-                    writeCharacteristic(STOP_CHARACTERISTIC_UUID, msg);

-                    sleep(1000);

-                    Intent intent = new Intent();

-                    switch (mPriority) {

-                    case BleConnectionPriorityServerService.CONNECTION_PRIORITY_BALANCED:

-                        intent.setAction(ACTION_FINISH_CONNECTION_PRIORITY_BALANCED);

-                        break;

-                    case BleConnectionPriorityServerService.CONNECTION_PRIORITY_HIGH:

-                        intent.setAction(ACTION_FINISH_CONNECTION_PRIORITY_HIGH);

-                        break;

-                    case BleConnectionPriorityServerService.CONNECTION_PRIORITY_LOW_POWER:

-                        intent.setAction(ACTION_FINISH_CONNECTION_PRIORITY_LOW_POWER);

-                        break;

-                    }

-                    sendBroadcast(intent);

-                }

-

-                if (mConnectionTimer != null) {

-                    // write testing data

-                    ++mWriteCount;

-                    writeCharacteristic(CHARACTERISTIC_UUID, WRITE_VALUE);

-                }

-            }

-        };

-

-        // write starting data

-        writeCharacteristic(START_CHARACTERISTIC_UUID, mPriority);

-

-        // start sending

-        sleep(1000);

-        mConnectionTimer = new Timer();

-        mConnectionTimer.schedule(task, 0, mInterval);

+    private void myRequestConnectionPriority(final int priority) {

+        mTaskQueue.addTask(new Runnable() {

+                                @Override

+                                public void run() {

+                                    mPriority = priority;

+                                    mBluetoothGatt.requestConnectionPriority(mPriority);

+                                    //continue in onConnectionUpdated() callback

+                                }

+                            });

     }

 

-    private BluetoothGattService getService() {

-        BluetoothGattService service = null;

-

-        if (mBluetoothGatt != null) {

-            service = mBluetoothGatt.getService(SERVICE_UUID);

-            if (service == null) {

-                showMessage("Service not found");

-            }

-        }

-        return service;

-    }

-

-    private BluetoothGattCharacteristic getCharacteristic(UUID uuid) {

-        BluetoothGattCharacteristic characteristic = null;

-

-        BluetoothGattService service = getService();

-        if (service != null) {

-            characteristic = service.getCharacteristic(uuid);

-            if (characteristic == null) {

-                showMessage("Characteristic not found");

-            }

-        }

-        return characteristic;

-    }

-

-    private void writeCharacteristic(UUID uid, String writeValue) {

-        BluetoothGattCharacteristic characteristic = getCharacteristic(uid);

-        if (characteristic != null){

-            characteristic.setValue(writeValue);

-            mBluetoothGatt.writeCharacteristic(characteristic);

-        }

-    }

 

     private void sleep(int millis) {

         try {

@@ -372,19 +238,56 @@
             if (DEBUG){

                 Log.d(TAG, "onServiceDiscovered");

             }

-            if ((status == BluetoothGatt.GATT_SUCCESS) && (mBluetoothGatt.getService(SERVICE_UUID) != null)) {

+            if (status == BluetoothGatt.GATT_SUCCESS) {

                 showMessage("Service discovered");

                 Intent intent = new Intent(ACTION_CONNECTION_SERVICES_DISCOVERED);

                 sendBroadcast(intent);

             }

-        }

 

-        @Override

-        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {

-            String value = characteristic.getStringValue(0);

-            UUID uid = characteristic.getUuid();

-            if (DEBUG) {

-                Log.d(TAG, "onCharacteristicWrite: characteristic.val=" + value + " status=" + status + " uid=" + uid);

+            //onConnectionUpdated is hidden callback, can't be marked as @Override.

+            // We must have a call to it, otherwise compiler will delete it during optimization.

+            if (status == 0xFFEFFEE) {

+                // This should never execute, but will make compiler not remove onConnectionUpdated 

+                onConnectionUpdated(null, 0, 0, 0, 0);

+                throw new IllegalStateException("This should never happen!");

+            }

+        }

+ 

+        // @Override uncomment once this becomes public API

+        public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency, int timeout,

+            int status) {

+            if (mPriority == NOT_UNDER_TEST) return;

+

+            if (status != 0) {

+                showMessage("onConnectionUpdated() error, status=" + status );

+                Log.e(TAG, "onConnectionUpdated() status=" + status);

+                return;

+            }

+

+            Log.i(TAG, "onConnectionUpdated() status=" + status + ", interval=" + interval);

+            if (mPriority == BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER) {

+                interval_low = interval;

+                myRequestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_BALANCED);

+            } else if (mPriority == BluetoothGatt.CONNECTION_PRIORITY_BALANCED) {

+                interval_balanced = interval;

+                myRequestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);

+            } else if (mPriority == BluetoothGatt.CONNECTION_PRIORITY_HIGH) {

+                interval_high = interval;

+

+                if (interval_low < interval_balanced || interval_balanced < interval_high) {

+                   showMessage("interval value should be descending - failure!");

+                   Log.e(TAG, "interval values should be descending: interval_low=" + interval_low +

+                            ", interval_balanced=" + interval_balanced + ", interval_high=" + interval_high);

+                   return;

+                }

+

+                showMessage("intervals: " + interval_low +" > " + interval_balanced + " > " + interval_high);

+         

+                Intent intent = new Intent();

+                intent.setAction(ACTION_CONNECTION_PRIORITY_FINISH);

+                sendBroadcast(intent);

+        

+                mPriority = NOT_UNDER_TEST;

             }

         }

     };

diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityServerBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityServerBaseActivity.java
index c0a2f09..66e068e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityServerBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityServerBaseActivity.java
@@ -37,12 +37,6 @@
 public class BleConnectionPriorityServerBaseActivity extends PassFailButtons.Activity {

 

     public static final int CONNECTION_PRIORITY_HIGH = 0;

-    public static final int CONNECTION_PRIORITY_BALANCED = 1;

-    public static final int CONNECTION_PRIORITY_LOW_POWER = 2;

-

-    private long mAverageBalanced = -1;

-    private long mAverageHigh = -1;

-    private long mAverageLow = -1;

 

     private TestAdapter mTestAdapter;

 

@@ -71,10 +65,7 @@
 

         IntentFilter filter = new IntentFilter();

         filter.addAction(BleConnectionPriorityServerService.ACTION_BLUETOOTH_DISABLED);

-        filter.addAction(BleConnectionPriorityServerService.ACTION_CONNECTION_WRITE_REQUEST);

-        filter.addAction(BleConnectionPriorityServerService.ACTION_FINICH_CONNECTION_PRIORITY_HIGHT);

-        filter.addAction(BleConnectionPriorityServerService.ACTION_FINICH_CONNECTION_PRIORITY_BALANCED);

-        filter.addAction(BleConnectionPriorityServerService.ACTION_FINICH_CONNECTION_PRIORITY_LOW);

+        filter.addAction(BleConnectionPriorityServerService.ACTION_CONNECTION_PRIORITY_FINISH);

         filter.addAction(BleServerService.BLE_ADVERTISE_UNSUPPORTED);

         filter.addAction(BleServerService.BLE_OPEN_FAIL);

         filter.addAction(BleConnectionPriorityServerService.ACTION_START_CONNECTION_PRIORITY_TEST);

@@ -90,9 +81,7 @@
 

     private List<Integer> setupTestList() {

         ArrayList<Integer> testList = new ArrayList<Integer>();

-        testList.add(R.string.ble_connection_priority_client_high);

-        testList.add(R.string.ble_connection_priority_client_balanced);

-        testList.add(R.string.ble_connection_priority_client_low);

+        testList.add(R.string.ble_connection_priority_client_description);

         return testList;

     }

 

@@ -130,8 +119,8 @@
     private BroadcastReceiver mBroadcast = new BroadcastReceiver() {

         @Override

         public void onReceive(Context context, Intent intent) {

+            boolean passedAll = false;

             String action = intent.getAction();

-            long average = intent.getLongExtra(BleConnectionPriorityServerService.EXTRA_AVERAGE, -1);

             switch (action) {

             case BleConnectionPriorityServerService.ACTION_BLUETOOTH_DISABLED:

                 new AlertDialog.Builder(context)

@@ -148,64 +137,12 @@
             case BleConnectionPriorityServerService.ACTION_START_CONNECTION_PRIORITY_TEST:

                 showProgressDialog();

                 break;

-            case BleConnectionPriorityServerService.ACTION_FINICH_CONNECTION_PRIORITY_HIGHT:

-                mAverageHigh = average;

-                mAverageBalanced = -1;

-                mAverageLow = -1;

-                break;

-            case BleConnectionPriorityServerService.ACTION_FINICH_CONNECTION_PRIORITY_BALANCED:

-                mAverageBalanced = average;

-                break;

-            case BleConnectionPriorityServerService.ACTION_FINICH_CONNECTION_PRIORITY_LOW:

-                mAverageLow = average;

-                break;

-            case BleServerService.BLE_OPEN_FAIL:

-                setTestResultAndFinish(false);

-                runOnUiThread(new Runnable() {

-                    @Override

-                    public void run() {

-                        Toast.makeText(BleConnectionPriorityServerBaseActivity.this, R.string.bt_open_failed_message, Toast.LENGTH_SHORT).show();

-                    }

-                });

-                break;

-            case BleServerService.BLE_ADVERTISE_UNSUPPORTED:

-                showErrorDialog(R.string.bt_advertise_unsupported_title, R.string.bt_advertise_unsupported_message, true);

-                break;

-            }

-

-            boolean passedHigh = (mAverageHigh >= 0);

-            boolean passedAll = false;

-

-            if (passedHigh) {

-                mTestAdapter.setTestPass(CONNECTION_PRIORITY_HIGH);

-            }

-

-            if (passedHigh && (mAverageLow >= 0) && (mAverageBalanced >= 0)) {

-                boolean passedBalanced = (mAverageHigh <= mAverageBalanced);

-                boolean passedLow = (mAverageBalanced <= mAverageLow);

-

-                if (passedBalanced) {

-                    mTestAdapter.setTestPass(CONNECTION_PRIORITY_BALANCED);

-                }

-                if (passedLow) {

-                    mTestAdapter.setTestPass(CONNECTION_PRIORITY_LOW_POWER);

-                }

-

-                String resultMsg;

-                if (passedBalanced && passedLow) {

-                    resultMsg = getString(R.string.ble_server_connection_priority_result_passed);

-                    passedAll = true;

-                } else {

-                    String detailsMsg = String.format(getString(R.string.ble_server_connection_priority_result_intervals),

-                            mAverageHigh,

-                            mAverageBalanced,

-                            mAverageLow);

-                    resultMsg = getString(R.string.ble_server_connection_priority_result_failed)

-                            + "\n\n"

-                            + detailsMsg;

-                }

+            case BleConnectionPriorityServerService.ACTION_CONNECTION_PRIORITY_FINISH:

+                String resultMsg = getString(R.string.ble_server_connection_priority_result_passed);

 

                 closeDialog();

+

+                mTestAdapter.setTestPass(CONNECTION_PRIORITY_HIGH);

                 mDialog = new AlertDialog.Builder(BleConnectionPriorityServerBaseActivity.this)

                         .setMessage(resultMsg)

                         .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

@@ -222,10 +159,25 @@
                         })

                         .create();

                 mDialog.show();

+

+                getPassButton().setEnabled(true);

+                mTestAdapter.notifyDataSetChanged();

+                break;

+

+            case BleServerService.BLE_OPEN_FAIL:

+                setTestResultAndFinish(false);

+                runOnUiThread(new Runnable() {

+                    @Override

+                    public void run() {

+                        Toast.makeText(BleConnectionPriorityServerBaseActivity.this, R.string.bt_open_failed_message, Toast.LENGTH_SHORT).show();

+                    }

+                });

+                break;

+            case BleServerService.BLE_ADVERTISE_UNSUPPORTED:

+                showErrorDialog(R.string.bt_advertise_unsupported_title, R.string.bt_advertise_unsupported_message, true);

+                break;

             }

 

-            getPassButton().setEnabled(passedAll);

-            mTestAdapter.notifyDataSetChanged();

         }

     };

 

diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityServerService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityServerService.java
index e1e4eed..ccffcdb 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityServerService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleConnectionPriorityServerService.java
@@ -45,43 +45,16 @@
 public class BleConnectionPriorityServerService extends Service {

     public static final boolean DEBUG = true;

     public static final String TAG = "BlePriorityServer";

-    private static final String RESET_COUNT_VALUE = "RESET";

-    private static final String START_VALUE = "START";

-    private static final String STOP_VALUE = "STOP";

-    public static final String CONNECTION_PRIORITY_HIGH = "PR_H";

-    public static final String CONNECTION_PRIORITY_BALANCED = "PR_B";

-    public static final String CONNECTION_PRIORITY_LOW_POWER = "PR_L";

 

     public static final String ACTION_BLUETOOTH_DISABLED =

             "com.android.cts.verifier.bluetooth.action.BLUETOOTH_DISABLED";

 

-    public static final String ACTION_CONNECTION_WRITE_REQUEST =

-            "com.android.cts.verifier.bluetooth.action.CONNECTION_WRITE_REQUEST";

-    public static final String EXTRA_REQUEST_COUNT =

-            "com.android.cts.verifier.bluetooth.intent.EXTRA_REQUEST_COUNT";

-    public static final String ACTION_FINICH_CONNECTION_PRIORITY_HIGHT =

-            "com.android.cts.verifier.bluetooth.action.ACTION_FINICH_CONNECTION_PRIORITY_HIGHT";

-    public static final String ACTION_FINICH_CONNECTION_PRIORITY_BALANCED =

-            "com.android.cts.verifier.bluetooth.action.ACTION_FINICH_CONNECTION_PRIORITY_BALANCED";

-    public static final String ACTION_FINICH_CONNECTION_PRIORITY_LOW =

-            "com.android.cts.verifier.bluetooth.action.ACTION_FINICH_CONNECTION_PRIORITY_LOW";

+    public static final String ACTION_CONNECTION_PRIORITY_FINISH =

+            "com.android.cts.verifier.bluetooth.action.ACTION_CONNECTION_PRIORITY_FINISH";

 

     public static final String ACTION_START_CONNECTION_PRIORITY_TEST =

             "com.android.cts.verifier.bluetooth.action.ACTION_START_CONNECTION_PRIORITY_TEST";

 

-    public static final String EXTRA_AVERAGE =

-            "com.android.cts.verifier.bluetooth.intent.EXTRA_AVERAGE";

-

-    private static final UUID SERVICE_UUID =

-            UUID.fromString("00009999-0000-1000-8000-00805f9b34fb");

-    private static final UUID CHARACTERISTIC_UUID =

-            UUID.fromString("00009998-0000-1000-8000-00805f9b34fb");

-    private static final UUID START_CHARACTERISTIC_UUID =

-            UUID.fromString("00009997-0000-1000-8000-00805f9b34fb");

-    private static final UUID STOP_CHARACTERISTIC_UUID =

-            UUID.fromString("00009995-0000-1000-8000-00805f9b34fb");

-    private static final UUID DESCRIPTOR_UUID =

-            UUID.fromString("00009996-0000-1000-8000-00805f9b34fb");

     public static final UUID ADV_SERVICE_UUID=

             UUID.fromString("00002222-0000-1000-8000-00805f9b34fb");

 

@@ -92,8 +65,10 @@
     private Handler mHandler;

     private BluetoothLeAdvertiser mAdvertiser;

     private long mReceiveWriteCount;

-    private Timer mTimeoutTimer;

-    private TimerTask mTimeoutTimerTask;

+

+    private int interval_low = 0;

+    private int interval_balanced = 0;

+    private int interval_high = 0;

 

     @Override

     public void onCreate() {

@@ -102,10 +77,6 @@
         mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

         mAdvertiser = mBluetoothManager.getAdapter().getBluetoothLeAdvertiser();

         mGattServer = mBluetoothManager.openGattServer(this, mCallbacks);

-        mService = createService();

-        if ((mGattServer != null) && (mAdvertiser != null)) {

-            mGattServer.addService(mService);

-        }

         mDevice = null;

         mHandler = new Handler();

 

@@ -124,14 +95,6 @@
     public void onDestroy() {

         super.onDestroy();

 

-        cancelTimeoutTimer(false);

-

-        if (mTimeoutTimer != null) {

-            mTimeoutTimer.cancel();

-            mTimeoutTimer = null;

-        }

-        mTimeoutTimerTask = null;

-

         stopAdvertise();

         if (mGattServer == null) {

             return;

@@ -194,21 +157,6 @@
         }

     }

 

-    private void notifyServiceAdded() {

-        if (DEBUG) {

-            Log.d(TAG, "notifyServiceAdded");

-        }

-    }

-

-    private void notifyCharacteristicWriteRequest() {

-        if (DEBUG) {

-            Log.d(TAG, "notifyCharacteristicWriteRequest");

-        }

-        Intent intent = new Intent(ACTION_CONNECTION_WRITE_REQUEST);

-        intent.putExtra(EXTRA_REQUEST_COUNT, String.valueOf(mReceiveWriteCount));

-        sendBroadcast(intent);

-    }

-

     private void showMessage(final String msg) {

         mHandler.post(new Runnable() {

             @Override

@@ -218,38 +166,6 @@
         });

     }

 

-    private synchronized void cancelTimeoutTimer(boolean runTimeout) {

-        if (mTimeoutTimerTask != null) {

-            mTimeoutTimer.cancel();

-            if (runTimeout) {

-                mTimeoutTimerTask.run();

-            }

-            mTimeoutTimerTask = null;

-            mTimeoutTimer = null;

-        }

-    }

-

-    private BluetoothGattService createService() {

-        BluetoothGattService service =

-                new BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY);

-        // add characteristic to service

-        //   property: 0x0A (read, write)

-        //   permission: 0x11 (read, write)

-        BluetoothGattCharacteristic characteristic =

-                new BluetoothGattCharacteristic(CHARACTERISTIC_UUID, 0x0A, 0x11);

-        BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(DESCRIPTOR_UUID, 0x11);

-        characteristic.addDescriptor(descriptor);

-        service.addCharacteristic(characteristic);

-        characteristic = new BluetoothGattCharacteristic(START_CHARACTERISTIC_UUID, 0x0A, 0x11);

-        characteristic.addDescriptor(descriptor);

-        service.addCharacteristic(characteristic);

-        characteristic = new BluetoothGattCharacteristic(STOP_CHARACTERISTIC_UUID, 0x0A, 0x11);

-        characteristic.addDescriptor(descriptor);

-        service.addCharacteristic(characteristic);

-

-        return service;

-    }

-

     private final BluetoothGattServerCallback mCallbacks = new BluetoothGattServerCallback() {

         @Override

         public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {

@@ -261,120 +177,50 @@
                     mDevice = device;

                     notifyConnected();

                 } else if (status == BluetoothProfile.STATE_DISCONNECTED) {

-                    cancelTimeoutTimer(true);

                     notifyDisconnected();

                     mDevice = null;

                 }

             }

+

+            //onConnectionUpdated is hidden callback, can't be marked as @Override.

+            // We must have a call to it, otherwise compiler will delete it during optimization.

+            if (status == 0xFFEFFEE) {

+                // This should never execute, but will make compiler not remove onConnectionUpdated 

+                onConnectionUpdated(null, 0, 0, 0, 0);

+                throw new IllegalStateException("This should never happen!");

+            }

+

         }

 

-        @Override

-        public void onServiceAdded(int status, BluetoothGattService service) {

-            if (DEBUG) {

-                Log.d(TAG, "onServiceAdded()");

-            }

-            if (status == BluetoothGatt.GATT_SUCCESS) {

-                notifyServiceAdded();

-            }

-        }

+        // @Override uncomment once this becomes public API

+        public void onConnectionUpdated(BluetoothDevice device, int interval, int latency, int timeout, int status) {

+            Log.i(TAG, "onConnectionUpdated() status=" + status + ", interval=" + interval);

 

-        String mPriority = null;

-

-        @Override

-        public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,

-                                                 BluetoothGattCharacteristic characteristic,

-                                                 boolean preparedWrite, boolean responseNeeded,

-                                                 int offset, byte[] value) {

-            if (mGattServer == null) {

-                if (DEBUG) {

-                    Log.d(TAG, "GattServer is null, return");

-                }

-                return;

-            }

-            if (DEBUG) {

-                Log.d(TAG, "onCharacteristicWriteRequest: preparedWrite=" + preparedWrite);

+            if (status != 0) {

+               interval_low = interval_balanced = interval_high = 0;

+               return;

             }

 

-            if (characteristic.getUuid().equals(START_CHARACTERISTIC_UUID)) {

-                // time out if previous measurement is running

-                cancelTimeoutTimer(true);

+            // since we don't know when the test started, wait for three descending interval values.

+            // Even though conneciton is updated by service discovery, it never happen three times

+            // descending in any scenario. 

 

-                mPriority = new String(value);

-                Log.d(TAG, "Start Count Up. Priority is " + mPriority);

-                if (BleConnectionPriorityServerService.CONNECTION_PRIORITY_HIGH.equals(mPriority)) {

-                    notifyTestStart();

-                }

+            // shift all values

+            interval_low = interval_balanced;

+            interval_balanced = interval_high;

+            interval_high = interval;

 

-                // start timeout timer

-                mTimeoutTimer = new Timer(getClass().getName() + "_TimeoutTimer");

-                mTimeoutTimerTask = new TimerTask() {

-                    @Override

-                    public void run() {

-                        // measurement timed out

-                        mTimeoutTimerTask = null;

-                        mTimeoutTimer = null;

-                        mReceiveWriteCount = 0;

-                        notifyMeasurementFinished(mPriority, Long.MAX_VALUE);

-                    }

-                };

-                mTimeoutTimer.schedule(mTimeoutTimerTask, (BleConnectionPriorityClientService.DEFAULT_PERIOD * 2));

-

-                mReceiveWriteCount = 0;

-            } else if (characteristic.getUuid().equals(STOP_CHARACTERISTIC_UUID)) {

-                boolean isRunning = (mTimeoutTimerTask != null);

-                cancelTimeoutTimer(false);

-

-                String valeStr = new String(value);

-                String priority = null;

-                int writeCount = -1;

-                int sep = valeStr.indexOf(",");

-                if (sep > 0) {

-                    priority = valeStr.substring(0, sep);

-                    writeCount = Integer.valueOf(valeStr.substring(sep + 1));

-                }

-

-                if ((mPriority != null) && isRunning) {

-                    if (mPriority.equals(priority)) {

-                        long averageTime = BleConnectionPriorityClientService.DEFAULT_PERIOD / mReceiveWriteCount;

-                        notifyMeasurementFinished(mPriority, averageTime);

-                        Log.d(TAG, "Received " + mReceiveWriteCount + " of " + writeCount + " messages");

-                    } else {

-                        Log.d(TAG, "Connection priority does not match");

-                        showMessage("Connection priority does not match");

-                    }

-                } else {

-                    Log.d(TAG, "Not Start Count UP.");

-                }

-                mReceiveWriteCount = 0;

-            } else {

-                if (mTimeoutTimerTask != null) {

-                    ++mReceiveWriteCount;

-                }

-                if (!preparedWrite) {

-                    characteristic.setValue(value);

-                }

-            }

-

-            if (responseNeeded) {

-                mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null);

+            // If we end up with three descending values, test is passed.

+            if (interval_low > interval_balanced && interval_balanced > interval_high) {

+                showMessage("intervals: " + interval_low +" > " + interval_balanced + " > " + interval_high);

+                notifyMeasurementFinished();

             }

         }

     };

 

-    private void notifyMeasurementFinished(String priority, long averageTime) {

+    private void notifyMeasurementFinished() {

         Intent intent = new Intent();

-        intent.putExtra(EXTRA_AVERAGE, averageTime);

-        switch (priority) {

-            case CONNECTION_PRIORITY_HIGH:

-                intent.setAction(ACTION_FINICH_CONNECTION_PRIORITY_HIGHT);

-                break;

-            case CONNECTION_PRIORITY_BALANCED:

-                intent.setAction(ACTION_FINICH_CONNECTION_PRIORITY_BALANCED);

-                break;

-            case CONNECTION_PRIORITY_LOW_POWER:

-                intent.setAction(ACTION_FINICH_CONNECTION_PRIORITY_LOW);

-                break;

-        }

+        intent.setAction(ACTION_CONNECTION_PRIORITY_FINISH);

         sendBroadcast(intent);

     }

 

diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
index 6a3678d..2fd2521 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationListenerVerifierActivity.java
@@ -42,6 +42,7 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
@@ -121,8 +122,10 @@
             tests.add(new EnableHintsTest());
             tests.add(new ReceiveAppBlockNoticeTest());
             tests.add(new ReceiveAppUnblockNoticeTest());
-            tests.add(new ReceiveChannelBlockNoticeTest());
-            tests.add(new ReceiveGroupBlockNoticeTest());
+            if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                tests.add(new ReceiveChannelBlockNoticeTest());
+                tests.add(new ReceiveGroupBlockNoticeTest());
+            }
             tests.add(new RequestUnbindTest());
             tests.add(new RequestBindTest());
             tests.add(new MessageBundleTest());
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
index e04bf0a..d4abbf1 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
@@ -71,6 +71,18 @@
         mBuildHelper = new CompatibilityBuildHelper(buildInfo);
     }
 
+    /**
+     * Approve the review permission prompt
+     */
+    private void approveReviewPermissionDialog() throws Exception {
+        assertNull(getDevice().installPackage(
+                mBuildHelper.getTestFile("ReviewPermissionHelper.apk"), true, true));
+
+        runDeviceTests("com.android.cts.reviewpermissionhelper",
+                "com.android.cts.reviewpermissionhelper.ReviewPermissionsTest",
+                "approveReviewPermissions");
+    }
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -139,12 +151,18 @@
 
     public void testCompatDefault22() throws Exception {
         assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false));
+
+        approveReviewPermissionDialog();
+
         runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22",
                 "testCompatDefault");
     }
 
     public void testCompatRevoked22() throws Exception {
         assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false));
+
+        approveReviewPermissionDialog();
+
         boolean didThrow = false;
         try {
             runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22",
@@ -161,6 +179,9 @@
 
     public void testNoRuntimePrompt22() throws Exception {
         assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false));
+
+        approveReviewPermissionDialog();
+
         runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22",
                 "testNoRuntimePrompt");
     }
@@ -284,6 +305,9 @@
 
     public void testUpgradeKeepsPermissions() throws Exception {
         assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false));
+
+        approveReviewPermissionDialog();
+
         runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22",
                 "testAllPermissionsGrantedByDefault");
         assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), true, false));
@@ -316,6 +340,9 @@
 
     public void testRevokePropagatedOnUpgradeOldToNewModel() throws Exception {
         assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false));
+
+        approveReviewPermissionDialog();
+
         boolean didThrow = false;
         try {
             runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22",
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 afcaae0..6188303 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
@@ -138,7 +138,8 @@
     protected boolean supportedHardware() {
         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
         if (pm.hasSystemFeature("android.hardware.type.television")
-                || pm.hasSystemFeature("android.hardware.type.watch")) {
+                || pm.hasSystemFeature("android.hardware.type.watch")
+                || pm.hasSystemFeature("android.hardware.type.automotive")) {
             return false;
         }
         return true;
diff --git a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/Android.mk b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/Android.mk
new file mode 100644
index 0000000..182ff82
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/Android.mk
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    androidx.test.rules \
+    android-support-test \
+    compatibility-device-util-axt \
+    ub-uiautomator
+
+LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := ReviewPermissionHelper
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/AndroidManifest.xml
new file mode 100644
index 0000000..f5cc0d0
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.reviewpermissionhelper">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+            android:name="androidx.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.cts.reviewpermissionhelper" />
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ReviewPermissionsTest.java b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ReviewPermissionsTest.java
new file mode 100644
index 0000000..d2ff472
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ReviewPermissionsTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.cts.reviewpermissionhelper;
+
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+import android.widget.ListView;
+import android.widget.Switch;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public final class ReviewPermissionsTest {
+    private static final long UI_TIMEOUT = 5000L;
+    private static final BySelector CONTINUE_BUTTON = By.text("Continue");
+
+    @Test
+    public void approveReviewPermissions() throws Exception {
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        PackageManager packageManager = instrumentation.getTargetContext().getPackageManager();
+        boolean isWatch = packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH);
+        if (!isWatch || !packageManager.isPermissionReviewModeEnabled()) return;
+
+        Intent startAutoClosingActivity = new Intent();
+        startAutoClosingActivity.setComponent(
+                new ComponentName(
+                        "com.android.cts.usepermission",
+                        "com.android.cts.usepermission.AutoClosingActivity"));
+        startAutoClosingActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        instrumentation.getTargetContext().startActivity(startAutoClosingActivity);
+
+        UiDevice device = UiDevice.getInstance(instrumentation);
+
+        UiObject2 listView = device.wait(Until.findObject(By.clazz(ListView.class)), UI_TIMEOUT);
+        List<UiObject2> permissionSwitches = new ArrayList<>();
+        UiObject2 continueButton;
+        do {
+            permissionSwitches = device.findObjects(By.clazz(Switch.class).checked(false));
+            for (UiObject2 permissionSwitch : permissionSwitches) {
+                permissionSwitch.click();
+            }
+            listView.scroll(Direction.DOWN, 0.5f);
+            continueButton = device.findObject(CONTINUE_BUTTON);
+        } while (!permissionSwitches.isEmpty() || continueButton == null);
+        device.wait(Until.findObject(CONTINUE_BUTTON), UI_TIMEOUT).click();
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/AndroidManifest.xml
index 1424c7c..f87a7da 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/AndroidManifest.xml
@@ -68,6 +68,7 @@
     <application>
         <uses-library android:name="android.test.runner" />
         <activity android:name=".BasePermissionActivity" />
+        <activity android:name=".AutoClosingActivity" android:exported="true" />
     </application>
 
     <instrumentation
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/AutoClosingActivity.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/AutoClosingActivity.java
new file mode 100644
index 0000000..5ee3aeb
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/AutoClosingActivity.java
@@ -0,0 +1,29 @@
+/*
+ * 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.cts.usepermission;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class AutoClosingActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        finish();
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
old mode 100755
new mode 100644
index d6b39fd..2c412e7
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
@@ -33,6 +33,7 @@
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Direction;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObject2;
@@ -45,6 +46,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.ScrollView;
+import android.widget.ListView;
 import android.widget.Switch;
 
 import androidx.test.InstrumentationRegistry;
@@ -294,25 +296,33 @@
 
     protected void clickAllowButton() throws Exception {
         scrollToBottomIfWatch();
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.packageinstaller:id/permission_allow_button")).click();
+        getUiDevice().wait(
+            Until.findObject(
+                By.res("com.android.packageinstaller:id/permission_allow_button")),
+            GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void clickDenyButton() throws Exception {
         scrollToBottomIfWatch();
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.packageinstaller:id/permission_deny_button")).click();
+        getUiDevice().wait(
+            Until.findObject(
+                By.res("com.android.packageinstaller:id/permission_deny_button")),
+            GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void clickDontAskAgainCheckbox() throws Exception {
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.packageinstaller:id/do_not_ask_checkbox")).click();
+        getUiDevice().wait(
+            Until.findObject(
+                By.res("com.android.packageinstaller:id/do_not_ask_checkbox")),
+            GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void clickDontAskAgainButton() throws Exception {
         scrollToBottomIfWatch();
-        getUiDevice().findObject(new UiSelector().resourceId(
-                "com.android.packageinstaller:id/permission_deny_dont_ask_again_button")).click();
+        getUiDevice().wait(
+            Until.findObject(
+                By.res("com.android.packageinstaller:id/permission_deny_dont_ask_again_button")),
+            GLOBAL_TIMEOUT_MILLIS).click();
     }
 
     protected void grantPermission(String permission) throws Exception {
@@ -333,12 +343,9 @@
 
     private void scrollToBottomIfWatch() throws Exception {
         if (mWatch) {
-            getUiDevice().wait(Until.findObject(By.clazz(ScrollView.class)), GLOBAL_TIMEOUT_MILLIS);
-            UiScrollable scrollable =
-                    new UiScrollable(new UiSelector().className(ScrollView.class));
-            if (scrollable.exists()) {
-                scrollable.flingToEnd(10);
-            }
+            UiObject2 scrollable = getUiDevice().wait(
+                Until.findObject(By.clazz(ScrollView.class)), GLOBAL_TIMEOUT_MILLIS);
+            if (scrollable != null) scrollable.fling(Direction.DOWN);
         }
     }
 
@@ -394,15 +401,24 @@
             if (granted != wasGranted) {
                 // Toggle the permission
 
-                if (!itemView.getActionList().contains(AccessibilityAction.ACTION_CLICK)) {
-                    click(toggleView, false);
+                boolean willShowPopup = (wasGranted && legacyApp);
+                if (mWatch) {
+                  if (!itemView.getActionList().contains(AccessibilityAction.ACTION_CLICK)) {
+                    toggleView.performAction(AccessibilityNodeInfo.ACTION_CLICK);
+                  } else {
+                    itemView.performAction(AccessibilityNodeInfo.ACTION_CLICK);
+                  }
                 } else {
-                    click(itemView, false);
+                  if (!itemView.getActionList().contains(AccessibilityAction.ACTION_CLICK)) {
+                      click(toggleView, willShowPopup);
+                  } else {
+                      click(itemView, willShowPopup);
+                  }
                 }
 
                 waitForIdle();
 
-                if (wasGranted && legacyApp) {
+                if (willShowPopup) {
                     scrollToBottomIfWatch();
                     String packageName = getInstrumentation().getContext().getPackageManager()
                             .getPermissionControllerPackageName();
@@ -458,7 +474,15 @@
     }
 
     private static AccessibilityNodeInfo findByText(AccessibilityNodeInfo root, String text) {
+        if (root == null) {
+            return null;
+        }
         List<AccessibilityNodeInfo> nodes = root.findAccessibilityNodeInfosByText(text);
+        PackageManager packageManager = InstrumentationRegistry.getTargetContext().getPackageManager();
+        boolean isWatch = packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH);
+        if (isWatch) {
+            return findByTextForWatch(root, text);
+        }
         for (AccessibilityNodeInfo node : nodes) {
             if (node.getText().toString().equals(text)) {
                 return node;
@@ -467,6 +491,21 @@
         return null;
     }
 
+    private static AccessibilityNodeInfo findByTextForWatch(AccessibilityNodeInfo root, String text) {
+        String trimmedText = trimText(text);
+        List<AccessibilityNodeInfo> nodes = root.findAccessibilityNodeInfosByText(trimmedText);
+        for (AccessibilityNodeInfo node : nodes) {
+            if (trimText(node.getText().toString()).equals(trimmedText)) {
+                return node;
+            }
+        }
+        return null;
+    }
+
+    private static String trimText(String text) {
+        return text != null ? text.substring(0, Math.min(text.length(), 20)) : null;
+    }
+
     private static AccessibilityNodeInfo findByTextInCollection(AccessibilityNodeInfo root,
             String text)  throws Exception {
         AccessibilityNodeInfo result;
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
index 79c03fb..5ddd2da 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
@@ -489,7 +489,20 @@
     @Test
     public void testNoResidualPermissionsOnUninstall_part1() throws Exception {
         // Grant all permissions
-        grantPermissions(new String[] {
+        String[] permissions;
+        if (mWatch) {
+          // The permission labels of READ_SMS and CALL_PHONE are too long to display on watches,
+          // and thus they got truncated there and can't be matched by grantPermissions().
+          permissions = new String[] {
+                Manifest.permission.WRITE_CALENDAR,
+                Manifest.permission.WRITE_CONTACTS,
+                Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                Manifest.permission.RECORD_AUDIO,
+                Manifest.permission.BODY_SENSORS,
+                Manifest.permission.ACCESS_COARSE_LOCATION,
+                Manifest.permission.CAMERA};
+        } else {
+          permissions = new String[] {
                 Manifest.permission.WRITE_CALENDAR,
                 Manifest.permission.WRITE_CONTACTS,
                 Manifest.permission.WRITE_EXTERNAL_STORAGE,
@@ -498,8 +511,9 @@
                 Manifest.permission.RECORD_AUDIO,
                 Manifest.permission.BODY_SENSORS,
                 Manifest.permission.ACCESS_COARSE_LOCATION,
-                Manifest.permission.CAMERA
-        });
+                Manifest.permission.CAMERA};
+        }
+        grantPermissions(permissions);
     }
 
     @Test
@@ -656,8 +670,9 @@
 
     private void assertPermissionsGrantState(String[] permissions, int grantState) {
         for (String permission : permissions) {
-            assertEquals(grantState, getInstrumentation().getContext()
-                    .checkSelfPermission(permission));
+            assertEquals(
+                "Permission [" + permission + "]", grantState,
+                getInstrumentation().getContext().checkSelfPermission(permission));
         }
     }
 
diff --git a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
index bbdcb08..e35841b 100644
--- a/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
@@ -42,7 +42,6 @@
 
     // These constants are those in PackageManager.
     public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
-    public static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
     public static final String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
 
     private static final int STATE_TIME_TOP_INDEX = 4;
@@ -136,6 +135,9 @@
     }
 
     public void testAlarms() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
 
         installPackage(DEVICE_SIDE_TEST_APK, /* grantPermissions= */ true);
@@ -149,6 +151,9 @@
     }
 
     public void testWakeLockDuration() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
 
         installPackage(DEVICE_SIDE_TEST_APK, /* grantPermissions= */ true);
@@ -171,6 +176,9 @@
     }
 
     public void testServiceForegroundDuration() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
 
@@ -186,6 +194,9 @@
     }
 
     public void testUidForegroundDuration() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
         // No foreground time before test
@@ -199,6 +210,9 @@
     }
 
     public void testUidBackgroundDuration() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
         // No background time before test
@@ -209,6 +223,9 @@
     }
 
     public void testTopDuration() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
         // No top time before test
@@ -221,6 +238,9 @@
     }
 
     public void testCachedDuration() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
         installPackage(DEVICE_SIDE_TEST_APK, true);
         // No cached time before test
@@ -271,7 +291,7 @@
     }
 
     public void testBleScans() throws Exception {
-        if (isTV() || !hasFeature(FEATURE_BLUETOOTH_LE, true)) {
+        if (noBattery() || !hasFeature(FEATURE_BLUETOOTH_LE, true)) {
             return;
         }
 
@@ -295,7 +315,7 @@
 
 
     public void testUnoptimizedBleScans() throws Exception {
-        if (isTV() || !hasFeature(FEATURE_BLUETOOTH_LE, true)) {
+        if (noBattery() || !hasFeature(FEATURE_BLUETOOTH_LE, true)) {
             return;
         }
         batteryOnScreenOff();
@@ -346,7 +366,7 @@
     }
 
     public void testGpsUpdates() throws Exception {
-        if (isTV() || !hasFeature(FEATURE_LOCATION_GPS, true)) {
+        if (noBattery() || !hasFeature(FEATURE_LOCATION_GPS, true)) {
             return;
         }
 
@@ -373,7 +393,7 @@
     }
 
     public void testJobBgVsFg() throws Exception {
-        if (isTV()) {
+        if (noBattery()) {
             return;
         }
         batteryOnScreenOff();
@@ -396,7 +416,7 @@
     }
 
     public void testSyncBgVsFg() throws Exception {
-        if (isTV()) {
+        if (noBattery()) {
             return;
         }
         batteryOnScreenOff();
@@ -424,6 +444,9 @@
      * are properly updated in battery stats.
      */
     public void testRealtime() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
         long startingValueRealtime = getLongValue(0, "bt", "", 7);
         long startingValueBatteryRealtime = getLongValue(0, "bt", "", 5);
@@ -449,6 +472,9 @@
      * Tests the total duration reported for jobs run on the job scheduler.
      */
     public void testJobDuration() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
 
         installPackage(DEVICE_SIDE_TEST_APK, true);
@@ -467,6 +493,9 @@
      * Tests the total duration and # of syncs reported for sync activities.
      */
     public void testSyncs() throws Exception {
+        if (noBattery()) {
+            return;
+        }
         batteryOnScreenOff();
 
         installPackage(DEVICE_SIDE_TEST_APK, true);
@@ -624,9 +653,14 @@
         return String.format("Completed performing %s for request %s", actionValue, requestCode);
     }
 
-    /** Determine if device is just a TV and is not expected to have proper batterystats. */
-    private boolean isTV() throws Exception {
-        return hasFeature(FEATURE_LEANBACK_ONLY, false);
+    /** Determine if device has no battery and is not expected to have proper batterystats. */
+    private boolean noBattery() throws Exception {
+        final String batteryinfo = getDevice().executeShellCommand("dumpsys battery");
+        boolean hasBattery = batteryinfo.contains("present: true");
+        if (!hasBattery) {
+            LogUtil.CLog.w("Device does not have a battery");
+        }
+        return !hasBattery;
     }
 
     /**
diff --git a/hostsidetests/incident/src/com/android/server/cts/NotificationIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/NotificationIncidentTest.java
index 7ed16e1..6c59282 100644
--- a/hostsidetests/incident/src/com/android/server/cts/NotificationIncidentTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/NotificationIncidentTest.java
@@ -27,6 +27,8 @@
 import android.service.notification.ZenModeProto;
 import android.service.notification.ZenRuleProto;
 
+import com.android.tradefed.device.ITestDevice;
+
 import java.util.List;
 
 /**
@@ -55,43 +57,51 @@
     private static final String TEST_ACTIVITY =
             "com.android.server.cts.notifications/.NotificationIncidentTestActivity";
     private static final int WAIT_MS = 1000;
+    private static final String DEVICE_SIDE_TEST_PKG = "com.android.server.cts.notifications";
 
     /**
      * Tests that at least one notification is posted, and verify its properties are plausible.
      */
     public void testNotificationRecords() throws Exception {
-        installPackage(DEVICE_SIDE_TEST_APK, /* grantPermissions= */ true);
-        int retries = 3;
-        do {
-            getDevice().executeShellCommand("am start -n " + TEST_ACTIVITY);
-        } while (!checkLogcatForText(TEST_APP_TAG, TEST_APP_LOG, WAIT_MS) && retries-- > 0);
+        ITestDevice device = getDevice();
+        try {
+            installPackage(DEVICE_SIDE_TEST_APK, /* grantPermissions= */ true);
+            int retries = 3;
+            do {
+                device.executeShellCommand("am start -n " + TEST_ACTIVITY);
+            } while (!checkLogcatForText(TEST_APP_TAG, TEST_APP_LOG, WAIT_MS) && retries-- > 0);
 
-        final NotificationServiceDumpProto dump = getDump(NotificationServiceDumpProto.parser(),
-                "dumpsys notification --proto");
+            final NotificationServiceDumpProto dump = getDump(NotificationServiceDumpProto.parser(),
+                    "dumpsys notification --proto");
 
-        assertTrue(dump.getRecordsCount() > 0);
-        boolean found = false;
-        for (NotificationRecordProto record : dump.getRecordsList()) {
-            if (record.getKey().contains("android")) {
-                found = true;
-                assertTrue(record.getImportance() > IMPORTANCE_NONE);
+            assertTrue(dump.getRecordsCount() > 0);
+            boolean found = false;
+            for (NotificationRecordProto record : dump.getRecordsList()) {
+                if (record.getKey().contains("android")) {
+                    found = true;
+                    assertTrue(record.getImportance() > IMPORTANCE_NONE);
 
-                // Ensure these fields exist, at least
-                record.getFlags();
-                record.getChannelId();
-                record.getSound();
-                record.getAudioAttributes();
-                record.getCanVibrate();
-                record.getCanShowLight();
-                record.getGroupKey();
+                    // Ensure these fields exist, at least
+                    record.getFlags();
+                    record.getChannelId();
+                    record.getSound();
+                    record.getAudioAttributes();
+                    record.getCanVibrate();
+                    record.getCanShowLight();
+                    record.getGroupKey();
+                }
+                assertTrue(
+                        NotificationRecordProto.State.getDescriptor()
+                                .getValues()
+                                .contains(record.getState().getValueDescriptor()));
             }
-            assertTrue(
-                NotificationRecordProto.State.getDescriptor()
-                        .getValues()
-                        .contains(record.getState().getValueDescriptor()));
-        }
 
-        assertTrue(found);
+            assertTrue(found);
+        } finally {
+            if (device.getInstalledPackageNames().contains(DEVICE_SIDE_TEST_PKG)) {
+                device.uninstallPackage(DEVICE_SIDE_TEST_PKG);
+            }
+        }
     }
 
     /** Test valid values from the RankingHelper. */
diff --git a/hostsidetests/net/app/Android.mk b/hostsidetests/net/app/Android.mk
index 6d89e58..11f6bb1 100644
--- a/hostsidetests/net/app/Android.mk
+++ b/hostsidetests/net/app/Android.mk
@@ -19,7 +19,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
+#LOCAL_SDK_VERSION := current
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt ctstestrunner-axt ub-uiautomator \
         CtsHostsideNetworkTestsAidl
 
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
index bc982ce..b3f61c4 100755
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -29,6 +29,7 @@
 import android.net.VpnService;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
+import android.os.SystemProperties;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObjectNotFoundException;
@@ -537,6 +538,14 @@
 
     public void testDefault() throws Exception {
         if (!supportedHardware()) return;
+        // If adb TCP port opened, this test may running by adb over network.
+        // All of socket would be destroyed in this test. So this test don't
+        // support adb over network, see b/119382723.
+        if (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1
+                || SystemProperties.getInt("service.adb.tcp.port", -1) > -1) {
+            Log.i(TAG, "adb is running over the network, so skip this test");
+            return;
+        }
 
         FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
 
@@ -554,6 +563,7 @@
 
         FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
 
+        // Shell app must not be put in here or it would kill the ADB-over-network use case
         String allowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName;
         startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
                  new String[] {"192.0.2.0/24", "2001:db8::/32"},
@@ -571,6 +581,12 @@
         FileDescriptor remoteFd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS);
 
         String disallowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName;
+        // If adb TCP port opened, this test may running by adb over TCP.
+        // Add com.android.shell appllication into blacklist to exclude adb socket for VPN test,
+        // see b/119382723.
+        // Note: The test don't support running adb over network for root device
+        disallowedApps = disallowedApps + ",com.android.shell";
+        Log.i(TAG, "Append shell app to disallowedApps: " + disallowedApps);
         startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
                  new String[] {"192.0.2.0/24", "2001:db8::/32"},
                  "", disallowedApps);
diff --git a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/BaseShortcutManagerHostTest.java b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/BaseShortcutManagerHostTest.java
index 863f51b..0931792 100644
--- a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/BaseShortcutManagerHostTest.java
+++ b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/BaseShortcutManagerHostTest.java
@@ -50,6 +50,7 @@
     protected boolean mIsMultiuserSupported;
     protected boolean mIsManagedUserSupported;
 
+    private int mInitialUserId;
     private ArrayList<Integer> mOriginalUsers;
 
     @Override
@@ -72,6 +73,7 @@
         }
 
         if (mIsMultiuserSupported) {
+            mInitialUserId = getDevice().getCurrentUser();
             mOriginalUsers = new ArrayList<>(getDevice().listUsers());
         }
     }
@@ -183,7 +185,7 @@
         if (!mIsMultiuserSupported) {
             return;
         }
-        getDevice().switchUser(getPrimaryUserId());
+        getDevice().switchUser(mInitialUserId);
         for (int userId : getDevice().listUsers()) {
             if (!mOriginalUsers.contains(userId)) {
                 getDevice().removeUser(userId);
@@ -191,6 +193,18 @@
         }
     }
 
+    protected int getOrCreateSecondaryUser() throws Exception {
+        if (getDevice().isUserSecondary(mInitialUserId)) {
+            return mInitialUserId;
+        }
+        for (int userId : getDevice().listUsers()) {
+            if (getDevice().isUserSecondary(userId)) {
+                return userId;
+            }
+        }
+        return createUser();
+    }
+
     protected int createUser() throws Exception{
         return getDevice().createUser("TestUser_" + System.currentTimeMillis());
     }
diff --git a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java
index 72c6a44..9549eb0 100644
--- a/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java
+++ b/hostsidetests/shortcuts/hostside/src/android/content/pm/cts/shortcuthost/ShortcutManagerMultiuserTest.java
@@ -62,7 +62,7 @@
         if (!mIsMultiuserSupported) {
             return;
         }
-        final int secondUserID = createUser();
+        final int secondUserID = getOrCreateSecondaryUser();
 
         getDevice().startUser(secondUserID);
         getDevice().switchUser(secondUserID);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
index 34adcd1..c0663ad 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
@@ -44,6 +44,7 @@
 
     private static final String TAG = "Statsd.HostAtomTests";
 
+    private static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
     private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
     private static final String FEATURE_WIFI = "android.hardware.wifi";
     private static final String FEATURE_TELEPHONY = "android.hardware.telephony";
@@ -111,6 +112,7 @@
         if (statsdDisabled()) {
             return;
         }
+        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
         // Setup, set charging state to full.
         setChargingState(5);
         Thread.sleep(WAIT_TIME_SHORT);
@@ -163,6 +165,7 @@
         if (statsdDisabled()) {
             return;
         }
+        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
         // Setup, unplug device.
         unplugDevice();
         Thread.sleep(WAIT_TIME_SHORT);
@@ -215,6 +218,7 @@
         if (statsdDisabled()) {
             return;
         }
+        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
         // Setup, set battery level to full.
         setBatteryLevel(100);
         Thread.sleep(WAIT_TIME_SHORT);
@@ -301,6 +305,7 @@
         if (statsdDisabled()) {
             return;
         }
+        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
         // Setup, turn off battery saver.
         turnBatterySaverOff();
         Thread.sleep(WAIT_TIME_SHORT);
@@ -338,6 +343,7 @@
             return;
         }
         if (!hasFeature(FEATURE_WATCH, false)) return;
+        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
         if (!hasBattery()) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
@@ -366,6 +372,7 @@
             return;
         }
         if (!hasFeature(FEATURE_WATCH, false)) return;
+        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
         if (!hasBattery()) return;
         StatsdConfig.Builder config = getPulledConfig();
         FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index c937e30..ff50691 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -61,6 +61,7 @@
     private static final String TAG = "Statsd.UidAtomTests";
 
     // These constants are those in PackageManager.
+    private static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
     private static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
     private static final String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
     private static final String FEATURE_WIFI = "android.hardware.wifi";
@@ -550,6 +551,9 @@
         if (statsdDisabled()) {
             return;
         }
+        // For automotive, all wakeup alarm becomes normal alarm. So this
+        // test does not work.
+        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
         final int atomTag = Atom.WAKEUP_ALARM_OCCURRED_FIELD_NUMBER;
 
         StatsdConfig.Builder config = createConfigBuilder();
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
index 8fe6965..5eb19c3 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
@@ -63,6 +63,7 @@
 public class ValidationTests extends DeviceAtomTestCase {
 
     private static final String TAG = "Statsd.ValidationTests";
+    private static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
     private static final boolean ENABLE_LOAD_TEST = false;
 
     @Override
@@ -81,6 +82,7 @@
         if (statsdDisabled()) {
             return;
         }
+        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
         resetBatteryStats();
         unplugDevice();
         // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
@@ -146,6 +148,7 @@
         if (statsdDisabled()) {
             return;
         }
+        if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
         turnScreenOn(); // To ensure that the ScreenOff later gets logged.
         // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
         // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/DeviceStatesTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/DeviceStatesTest.java
index 8fc13be..67d147e 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/DeviceStatesTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/DeviceStatesTest.java
@@ -18,6 +18,7 @@
 
 import android.annotation.TargetApi;
 import android.app.job.JobInfo;
+import android.content.pm.PackageManager;
 import android.os.SystemClock;
 import android.support.test.uiautomator.UiDevice;
 
@@ -148,9 +149,21 @@
     }
 
     /**
+     * Check if dock state is supported.
+     */
+    private boolean isDockStateSupported() {
+        // Car does not support dock state.
+        return !getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUTOMOTIVE);
+    }
+
+    /**
      * Ensure that device can switch state on dock normally.
      */
     public void testScreenOnDeviceOnDockChangeState() throws Exception {
+        if (!isDockStateSupported()) {
+            return;
+        }
         toggleScreenOn(true /* screen on */);
         verifyActiveState();
 
@@ -168,6 +181,9 @@
      *  Ensure that ignores this dock intent during screen off.
      */
     public void testScreenOffDeviceOnDockNoChangeState() throws Exception {
+        if (!isDockStateSupported()) {
+            return;
+        }
         toggleScreenOn(false /* screen off */);
         triggerIdleMaintenance();
         verifyIdleState();
diff --git a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
index 4ce31a3..9edfd09 100644
--- a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
@@ -1129,6 +1129,10 @@
                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE-1,
                 WAIT_TIME);
         uidBackgroundListener.register();
+        UidImportanceListener uidCachedListener = new UidImportanceListener(mContext,
+                appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE + 1,
+                WAIT_TIME);
+        uidCachedListener.register();
 
         WatchUidRunner uidWatcher = new WatchUidRunner(getInstrumentation(), appInfo.uid,
                 WAIT_TIME);
@@ -1202,7 +1206,7 @@
                     am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME));
 
             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
-            uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
+            uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
 
             // While in background, should go in to normal idle state.
             // Force app to go idle now
@@ -1214,6 +1218,7 @@
             uidWatcher.finish();
             uidForegroundListener.unregister();
             uidBackgroundListener.unregister();
+            uidCachedListener.unregister();
         }
     }
 
@@ -1358,7 +1363,7 @@
             getInstrumentation().getUiAutomation().performGlobalAction(
                     AccessibilityService.GLOBAL_ACTION_BACK);
             uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null);
-            uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
+            uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
 
             // Make both apps idle for cleanliness.
             cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index c208917..2adb512 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -2210,6 +2210,9 @@
                 assertTextAndValue(passwordNode, password);
 
                 waitUntilDisconnected();
+
+                // Wait and check if the save window is correctly hidden.
+                mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD);
             } catch (RetryableException e) {
                 throw new RetryableException(e, "on step %d", i);
             } catch (Throwable t) {
diff --git a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
index defc04a..84a22d7 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -68,7 +68,7 @@
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
 
     private static final int CONFIGURE_TIMEOUT = 5000; //ms
-    private static final int CAPTURE_TIMEOUT = 1000; //ms
+    private static final int CAPTURE_TIMEOUT = 1500; //ms
 
     // For testTriggerInteractions
     private static final int PREVIEW_WARMUP_FRAMES = 60;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
index dbc08b3..655d866 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -492,6 +492,7 @@
                         TRANSIT_WALLPAPER_OPEN, mAmWmState.getWmState().getLastTransition());
                 pressHomeButton();
                 mAmWmState.waitForHomeActivityVisible();
+                mAmWmState.waitForAppTransitionIdle();
 
                 assertEquals(TRANSIT_WALLPAPER_OPEN, mAmWmState.getWmState().getLastTransition());
             }
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index 192a1ac..9ea3825 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -244,7 +244,11 @@
 
         pressWakeupButton();
         pressUnlockButton();
-        pressHomeButton();
+        // Using launchHomeActivity to replace pressHomeButton here.
+        // pressHomeButton will trigger AMS.stopAppSwitches, if we using instrumentation to launch
+        // test activity, then the activity would be launched after 5 seconds, which may cause some
+        // tests failed.
+        launchHomeActivity();
         removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
     }
 
@@ -257,7 +261,7 @@
         executeShellCommand(AM_FORCE_STOP_TEST_PACKAGE);
         executeShellCommand(AM_FORCE_STOP_SECOND_TEST_PACKAGE);
         executeShellCommand(AM_FORCE_STOP_THIRD_TEST_PACKAGE);
-        pressHomeButton();
+        launchHomeActivity();
     }
 
     protected void removeStacksWithActivityTypes(int... activityTypes) {
diff --git a/tests/signature/api-check/system-annotation/AndroidTest.xml b/tests/signature/api-check/system-annotation/AndroidTest.xml
index 5d2f13f..2b01af4 100644
--- a/tests/signature/api-check/system-annotation/AndroidTest.xml
+++ b/tests/signature/api-check/system-annotation/AndroidTest.xml
@@ -44,4 +44,8 @@
         <option name="instrumentation-arg" key="annotation-for-exact-match" value="android.annotation.SystemApi" />
         <option name="runtime-hint" value="30s" />
     </test>
+
+    <!-- Controller that will skip the module if a native bridge situation is detected -->
+    <!-- For example: module wants to run arm32 and device is x86 -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
 </configuration>
diff --git a/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java b/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java
index 69f19b9..b94f9db 100644
--- a/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java
+++ b/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java
@@ -79,8 +79,9 @@
     private boolean isIntentSupported(TestcaseType testCaseType) {
         final PackageManager manager = mContext.getPackageManager();
         assertNotNull(manager);
-        // If TV then not supported.
-        if (manager.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)) {
+        // If TV or Automotive, then not supported.
+        if (manager.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY) ||
+                manager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
             return false;
         }
         Intent intent;
diff --git a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
index 5f391e4..357f985 100644
--- a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
@@ -22,6 +22,7 @@
 import android.car.Car;
 import android.car.CarNotConnectedException;
 import android.car.content.pm.CarPackageManager;
+import android.os.Build;
 import android.platform.test.annotations.RequiresDevice;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -77,6 +78,10 @@
     @Test
     public void testDistractionOptimizedActivityIsAllowed() throws CarNotConnectedException {
         // This test relies on test activity in installed apk, and AndroidManifest declaration.
+        if (Build.TYPE.equalsIgnoreCase("user")) {
+            // Skip this test on user build, which checks the install source for DO activity list.
+            return;
+        }
         assertTrue(mCarPm.isActivityDistractionOptimized("android.car.cts",
                 "android.car.cts.drivingstate.DistractionOptimizedActivity"));
     }
@@ -84,6 +89,10 @@
     @Test
     public void testNonDistractionOptimizedActivityNotAllowed() throws CarNotConnectedException {
         // This test relies on test activity in installed apk, and AndroidManifest declaration.
+        if (Build.TYPE.equalsIgnoreCase("user")) {
+            // Skip this test on user build, which checks the install source for DO activity list.
+            return;
+        }
         assertFalse(mCarPm.isActivityDistractionOptimized("android.car.cts",
                 "android.car.cts.drivingstate.NonDistractionOptimizedActivity"));
     }
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
index ee35eed..0a198f2 100644
--- a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
@@ -108,10 +108,8 @@
      * Checks whether the cellular stack should be running on this device.
      */
     private boolean hasCellular() {
-        ConnectivityManager mgr =
-                (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
-        return mgr.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) &&
-               mTelephonyManager.isVoiceCapable();
+        return mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) &&
+                mTelephonyManager.getPhoneCount() > 0;
     }
 
     private boolean isSimCardPresent() {
diff --git a/tests/tests/graphics/res/raw/f16.png b/tests/tests/graphics/res/raw/f16.png
new file mode 100644
index 0000000..2c3aed2
--- /dev/null
+++ b/tests/tests/graphics/res/raw/f16.png
Binary files differ
diff --git a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
index be5f331..ce8f26a 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
@@ -1679,7 +1679,7 @@
         };
         Listener l = new Listener();
         SourceCreator f = mCreators[0];
-        for (int resId : new int[] { R.drawable.png_test, R.raw.basi6a16 }) {
+        for (int resId : new int[] { R.drawable.png_test, R.raw.f16 }) {
             Bitmap normal = null;
             try {
                 normal = ImageDecoder.decodeBitmap(f.apply(resId));
@@ -1705,7 +1705,7 @@
                         // We do not support 565 in HARDWARE, so no RAM savings
                         // are possible.
                         assertEquals(normalByteCount, byteCount);
-                    } else { // R.raw.basi6a16
+                    } else { // R.raw.f16
                         // This image defaults to F16. MEMORY_POLICY_LOW_RAM
                         // forces "test" to decode to 8888. But if the device
                         // does not support F16 in HARDWARE, "normal" is also
@@ -1759,8 +1759,8 @@
                                    // If this were stored in drawable/, it would
                                    // be converted from 16-bit to 8. FIXME: Is
                                    // behavior still desirable now that we have
-                                   // F16?
-                                   R.raw.basi6a16 };
+                                   // F16? b/119760146
+                                   R.raw.f16 };
         // An opaque image can be converted to 565, but postProcess will promote
         // to 8888 in case alpha is added. The third image defaults to F16, so
         // even with postProcess it will only be promoted to 8888.
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordTest.java b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
index 089f914..88c5c3a 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
@@ -37,7 +37,9 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.SystemClock;
+import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
 import android.util.Log;
 
@@ -1492,24 +1494,55 @@
     }
 
     private static void makeMyUidStateActive() throws IOException {
-        final String command = "cmd media.audio_policy set-uid-state "
-                + InstrumentationRegistry.getTargetContext().getPackageName() + " active";
+        String command = String.format("cmd media.audio_policy set-uid-state %s active",
+                getContext().getPackageName());
+
+        if (!isSystemUser()) {
+            // --user parameter is not supported on all devices - only those that will run CTS in
+            // secondary users.
+            // For System User - Command defaults to system user, no need to explicitly specify.
+            // For Secondary User - Have to specify the user explicitly, otherwise the test fails.
+            command += " --user " + Process.myUserHandle().getIdentifier();
+        }
+
         SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
     }
 
     private static void makeMyUidStateIdle() throws IOException {
-        final String command = "cmd media.audio_policy set-uid-state "
-                + InstrumentationRegistry.getTargetContext().getPackageName() + " idle";
+        String command = String.format("cmd media.audio_policy set-uid-state %s idle",
+                getContext().getPackageName());
+
+        if (!isSystemUser()) {
+            // --user parameter is not supported on all devices - only those that will run CTS in
+            // secondary users.
+            // For System User - Command defaults to system user, no need to explicitly specify.
+            // For Secondary User - Have to specify the user explicitly, otherwise the test fails.
+            command += " --user " + Process.myUserHandle().getIdentifier();
+        }
+
         SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
     }
 
     private static void resetMyUidState() throws IOException {
-        final String command = "cmd media.audio_policy reset-uid-state "
-                +  InstrumentationRegistry.getTargetContext().getPackageName();
+        String command = "cmd media.audio_policy reset-uid-state "
+                + getContext().getPackageName();
+
+        if (!isSystemUser()) {
+            // --user parameter is not supported on all devices - only those that will run CTS in
+            // secondary users.
+            // For System User - Command defaults to system user, no need to explicitly specify.
+            // For Secondary User - Have to specify the user explicitly, otherwise the test fails.
+            command += " --user " + Process.myUserHandle().getIdentifier();
+        }
+
         SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
     }
 
     private static Context getContext() {
         return InstrumentationRegistry.getInstrumentation().getTargetContext();
     }
+
+    private static boolean isSystemUser() {
+        return getContext().getSystemService(UserManager.class).isSystemUser();
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
index 311c791..c085117 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -306,6 +306,11 @@
                 && !pm.hasSystemFeature(pm.FEATURE_TELEVISION);
     }
 
+    private boolean isAutomotive() {
+        PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(pm.FEATURE_AUTOMOTIVE);
+    }
+
     // Find whether the given codec can be found using MediaCodecList.find methods.
     private boolean codecCanBeFound(boolean isEncoder, MediaFormat format) {
         String codecName = isEncoder
@@ -399,7 +404,11 @@
             list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_VP8, false));   // vp8 decoder
             list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_VP8, true));    // vp8 encoder
             list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_VP9, false));   // vp9 decoder
-            list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_HEVC, false));  // hevc decoder
+
+            //According to CDD, hevc decoding is not mandatory for automotive devices
+            if (!isAutomotive()) {
+                list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_HEVC, false));  // hevc decoder
+            }
             list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_MPEG4, false)); // m4v decoder
             list.add(new VideoCodec(MediaFormat.MIMETYPE_VIDEO_H263, false));  // h263 decoder
             if (hasCamera()) {
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index 0b075e2..b500375 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -482,6 +482,12 @@
         // parsing String location and recover the location information in floats
         // Make sure the tolerance is very small - due to rounding errors.
 
+        // Trim the trailing slash, if any.
+        int lastIndex = location.lastIndexOf('/');
+        if (lastIndex != -1) {
+            location = location.substring(0, lastIndex);
+        }
+
         // Get the position of the -/+ sign in location String, which indicates
         // the beginning of the longitude.
         int minusIndex = location.lastIndexOf('-');
@@ -491,12 +497,8 @@
                 (minusIndex > 0 || plusIndex > 0));
         int index = Math.max(minusIndex, plusIndex);
 
-        float latitude = Float.parseFloat(location.substring(0, index - 1));
-        int lastIndex = location.lastIndexOf('/', index);
-        if (lastIndex == -1) {
-            lastIndex = location.length();
-        }
-        float longitude = Float.parseFloat(location.substring(index, lastIndex - 1));
+        float latitude = Float.parseFloat(location.substring(0, index));
+        float longitude = Float.parseFloat(location.substring(index));
         assertTrue("Incorrect latitude: " + latitude + " [" + location + "]",
                 Math.abs(latitude - LATITUDE) <= TOLERANCE);
         assertTrue("Incorrect longitude: " + longitude + " [" + location + "]",
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index 6c712ee..3412b21 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -507,6 +507,12 @@
         // Make sure the tolerance is very small - due to rounding errors?.
         Log.v(TAG, "location: " + location);
 
+        // Trim the trailing slash, if any.
+        int lastIndex = location.lastIndexOf('/');
+        if (lastIndex != -1) {
+            location = location.substring(0, lastIndex);
+        }
+
         // Get the position of the -/+ sign in location String, which indicates
         // the beginning of the longtitude.
         int index = location.lastIndexOf('-');
@@ -515,12 +521,8 @@
         }
         assertTrue("+ or - is not found", index != -1);
         assertTrue("+ or - is only found at the beginning", index != 0);
-        float latitude = Float.parseFloat(location.substring(0, index - 1));
-        int lastIndex = location.lastIndexOf('/', index);
-        if (lastIndex == -1) {
-            lastIndex = location.length();
-        }
-        float longitude = Float.parseFloat(location.substring(index, lastIndex - 1));
+        float latitude = Float.parseFloat(location.substring(0, index));
+        float longitude = Float.parseFloat(location.substring(index));
         assertTrue("Incorrect latitude: " + latitude, Math.abs(latitude - LATITUDE) <= TOLERANCE);
         assertTrue("Incorrect longitude: " + longitude, Math.abs(longitude - LONGITUDE) <= TOLERANCE);
         retriever.release();
diff --git a/tests/tests/net/jni/NativeMultinetworkJni.c b/tests/tests/net/jni/NativeMultinetworkJni.c
index 2fa5291..69238cf 100644
--- a/tests/tests/net/jni/NativeMultinetworkJni.c
+++ b/tests/tests/net/jni/NativeMultinetworkJni.c
@@ -179,13 +179,17 @@
     setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
 
     // For reference see:
-    //     https://tools.ietf.org/html/draft-tsvwg-quic-protocol-01#section-6.1
-    uint8_t quic_packet[] = {
-        0x0c,                    // public flags: 64bit conn ID, 8bit sequence number
+    //     https://tools.ietf.org/html/draft-tsvwg-quic-protocol#section-6.1
+    uint8_t quic_packet[1200] = {
+        0x0d,                    // public flags:
+                                 //   - version present (0x01),
+                                 //   - 64bit connection ID (0x0c),
+                                 //   - 1 byte packet number (0x00)
         0, 0, 0, 0, 0, 0, 0, 0,  // 64bit connection ID
-        0x01,                    // sequence number
+        0xaa, 0xda, 0xca, 0xaa,  // reserved-space version number
+        1,                       // 1 byte packet number
         0x00,                    // private flags
-        0x07,                    // type: regular frame type "PING"
+        0x07,                    // PING frame (cuz why not)
     };
 
     arc4random_buf(quic_packet + 1, 8);  // random connection ID
@@ -213,7 +217,7 @@
                   i + 1, MAX_RETRIES, rcvd, errnum);
         }
     }
-    if (rcvd < sent) {
+    if (rcvd < 9) {
         ALOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum);
         if (rcvd <= 0) {
             ALOGD("Does this network block UDP port %s?", kPort);
@@ -229,8 +233,7 @@
         return -EPROTO;
     }
 
-    // TODO: log, and compare to the IP address encoded in the
-    // response, since this should be a public reset packet.
+    // TODO: Replace this quick 'n' dirty test with proper QUIC-capable code.
 
     close(fd);
     return 0;
diff --git a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
index d7f0853..cdd2588 100644
--- a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
+++ b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
@@ -27,6 +27,7 @@
 import android.os.ProxyFileDescriptorCallback;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
+import android.os.UserManager;
 import android.os.storage.OnObbStateChangeListener;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
@@ -69,15 +70,22 @@
     private static final String TEST1_NEW_CONTENTS = "1\n";
 
     private StorageManager mStorageManager;
+    private UserManager mUserManager;
     private final Handler mHandler = new Handler(Looper.getMainLooper());
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
     }
 
     public void testMountAndUnmountObbNormal() throws IOException {
+        // Mount obb only works for system user. Skip for secondary users.
+        if (!mUserManager.isSystemUser()) {
+            return;
+        }
+
         for (File target : getTargetFiles()) {
             target = new File(target, "test1_new.obb");
             Log.d(TAG, "Testing path " + target);
@@ -104,6 +112,11 @@
     }
 
     public void testAttemptMountNonObb() {
+        // Mount obb only works for system user. Skip for secondary users.
+        if (!mUserManager.isSystemUser()) {
+            return;
+        }
+
         for (File target : getTargetFiles()) {
             target = new File(target, "test1_nosig.obb");
             Log.d(TAG, "Testing path " + target);
@@ -141,6 +154,11 @@
     }
 
     public void testMountAndUnmountTwoObbs() throws IOException {
+        // Mount obb only works for system user. Skip for secondary users.
+        if (!mUserManager.isSystemUser()) {
+            return;
+        }
+
         for (File target : getTargetFiles()) {
             Log.d(TAG, "Testing target " + target);
             final File test1 = new File(target, "test1.obb");
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index b20bd67..a83e567 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1472,9 +1472,9 @@
         android:protectionLevel="signature|privileged" />
 
     <!-- @hide Allows internal management of Wi-Fi connectivity state when on
-         permission review mode.
+         wireless consent mode.
          <p>Not for use by third-party applications. -->
-    <permission android:name="android.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED"
+    <permission android:name="android.permission.MANAGE_WIFI_WHEN_WIRELESS_CONSENT_REQUIRED"
         android:protectionLevel="signature" />
 
     <!-- @hide Allows an app to bypass Private DNS.
@@ -1580,9 +1580,9 @@
     <permission android:name="android.permission.NFC_HANDOVER_STATUS"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @hide Allows internal management of Bluetooth state when on permission review mode.
+    <!-- @hide Allows internal management of Bluetooth state when on wireless consnet mode.
          <p>Not for use by third-party applications. -->
-    <permission android:name="android.permission.MANAGE_BLUETOOTH_WHEN_PERMISSION_REVIEW_REQUIRED"
+    <permission android:name="android.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED"
         android:protectionLevel="signature" />
 
     <!-- ================================== -->
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
index 9ed199e..9e65d0b 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
@@ -267,7 +267,8 @@
 
     private boolean supportsHardware() {
         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
-        return !pm.hasSystemFeature("android.hardware.type.television")
+        return !pm.hasSystemFeature("android.hardware.type.automotive")
+                && !pm.hasSystemFeature("android.hardware.type.television")
                 && !pm.hasSystemFeature("android.hardware.type.watch");
     }
 
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index f4ae8a7..3d4498d 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -27,6 +27,7 @@
     ctstestserver \
     ctstestrunner-axt \
     compatibility-device-util-axt \
+    compatibility-common-util-devicesidelib \
     guava \
     platform-test-annotations
 
diff --git a/tests/tests/security/res/raw/bug_73552574_avc.mp4 b/tests/tests/security/res/raw/bug_73552574_avc.mp4
new file mode 100644
index 0000000..1cca70c
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_73552574_avc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_73552574_framelen.mp4 b/tests/tests/security/res/raw/bug_73552574_framelen.mp4
new file mode 100644
index 0000000..36728cc
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_73552574_framelen.mp4
@@ -0,0 +1,93 @@
+48
+4
+28
+208
+0
+10
+39
+386
+8
+70
+6
+32
+31
+4
+8
+24
+10
+22
+12
+108
+9
+229
+38
+12
+10
+166
+39
+250
+43
+8
+70
+6
+29
+12
+4
+8
+33
+12
+0
+10
+156
+10
+39
+94
+10
+39
+386
+8
+70
+6
+10
+31
+4
+8
+24
+10
+22
+12
+70
+9
+420
+0
+8
+36
+6
+12
+20
+31
+102
+229
+38
+12
+10
+156
+10
+39
+197
+251
+38
+12
+10
+156
+10
+180
+10
+39
+386
+8
+70
+6
+32
+31
+6441
diff --git a/tests/tests/security/src/android/security/cts/EncryptionTest.java b/tests/tests/security/src/android/security/cts/EncryptionTest.java
index 07b39de..ed6cf5c 100644
--- a/tests/tests/security/src/android/security/cts/EncryptionTest.java
+++ b/tests/tests/security/src/android/security/cts/EncryptionTest.java
@@ -22,6 +22,7 @@
 import android.test.AndroidTestCase;
 import junit.framework.TestCase;
 
+import android.content.pm.PackageManager;
 import android.content.Context;
 import android.util.Log;
 import java.io.BufferedReader;
@@ -46,7 +47,13 @@
 
     private boolean isRequired() {
         // Optional before MIN_API_LEVEL
-        return PropertyUtil.getFirstApiLevel() >= MIN_API_LEVEL;
+        return PropertyUtil.getFirstApiLevel() >= MIN_API_LEVEL && !isTelevision();
+    }
+
+    private boolean isTelevision() {
+        PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
+                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
     }
 
     public void testEncryption() throws Exception {
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index adf8131..627fc27 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -62,6 +62,7 @@
 import java.util.HashMap;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Pattern;
 
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -731,6 +732,12 @@
      ***********************************************************/
 
     @SecurityTest
+    public void testBug_73552574() throws Exception {
+        int[] frameSizes = getFrameSizes(R.raw.bug_73552574_framelen);
+        doStagefrightTestRawBlob(R.raw.bug_73552574_avc, "video/avc", 320, 240, frameSizes);
+    }
+
+    @SecurityTest
     public void testStagefright_cve_2017_0474() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0474, 120000);
     }
@@ -939,8 +946,23 @@
         MediaPlayer.OnPreparedListener,
         MediaPlayer.OnCompletionListener {
 
-        private final String[] validProcessNames = {
-            "mediaserver", "mediadrmserver", "media.extractor", "media.codec", "media.metrics"
+        private final Pattern[] validProcessPatterns = {
+            Pattern.compile("adsprpcd"),
+            Pattern.compile("android\\.hardware\\.cas@\\d+?\\.\\d+?-service"),
+            Pattern.compile("android\\.hardware\\.drm@\\d+?\\.\\d+?-service"),
+            Pattern.compile("android\\.hardware\\.drm@\\d+?\\.\\d+?-service\\.clearkey"),
+            Pattern.compile("android\\.hardware\\.drm@\\d+?\\.\\d+?-service\\.widevine"),
+            Pattern.compile("android\\.process\\.media"),
+            Pattern.compile("mediadrmserver"),
+            Pattern.compile("media\\.extractor"),
+            Pattern.compile("media\\.metrics"),
+            Pattern.compile("mediaserver"),
+            Pattern.compile("media\\.codec"),
+            Pattern.compile("media\\.swcodec"),
+            Pattern.compile("\\[?sdcard\\]?"), // name:/system/bin/sdcard, user:media_rw
+            // Match any vendor processes.
+            // It should only catch crashes that happen during the test.
+            Pattern.compile("vendor.*"),
         };
 
         @Override
@@ -988,7 +1010,7 @@
                 if (crashes == null) {
                     Log.e(TAG, "Crash results not found for test " + getName());
                     return what;
-                } else if (CrashUtils.detectCrash(validProcessNames, true, crashes)) {
+                } else if (CrashUtils.securityCrashDetected(crashes, true, validProcessPatterns)) {
                     return what;
                 } else {
                     Log.i(TAG, "Crash ignored due to no security crash found for test " +
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java
index 7628c82..79b6bd1 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerThrottlingTest.java
@@ -18,7 +18,7 @@
 
 import static android.content.pm.cts.shortcutmanager.common.Constants.INLINE_REPLY_REMOTE_INPUT_CAPTION;
 
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resetThrottling;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resetAllThrottling;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.runCommandForNoOutput;
 
 import android.content.ComponentName;
@@ -64,7 +64,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
-        resetThrottling(getInstrumentation());
+        resetAllThrottling(getInstrumentation());
 
         UiDevice.getInstance(getInstrumentation()).pressHome();
 
diff --git a/tests/tests/text/src/android/text/format/cts/TimeTest.java b/tests/tests/text/src/android/text/format/cts/TimeTest.java
index 267b705..6112b73 100644
--- a/tests/tests/text/src/android/text/format/cts/TimeTest.java
+++ b/tests/tests/text/src/android/text/format/cts/TimeTest.java
@@ -2824,6 +2824,13 @@
         Fields.verifyTimeEquals(expected, t);
     }
 
+    @Test
+    public void test_bug118835133() {
+        Time t = new Time("Asia/Singapore");
+        Fields.set(t, 2018, 9, 30, 12, 48, 32, 0 /* isDst */, 0, 0, 0);
+        // With http://b/118835133 toMillis() returns -1.
+        assertEquals(1540874912000L, t.toMillis(true /* ignoreDst */));
+    }
     private static void verifyNormalizeResult(boolean normalizeArgument, Time toNormalize,
             Time expectedTime, long expectedTimeMillis) {
         long actualTimeMillis = toNormalize.normalize(normalizeArgument /* ignore isDst */);
diff --git a/tests/tests/transition/res/values/styles.xml b/tests/tests/transition/res/values/styles.xml
index 00303c9..be2272e 100644
--- a/tests/tests/transition/res/values/styles.xml
+++ b/tests/tests/transition/res/values/styles.xml
@@ -14,7 +14,7 @@
      limitations under the License.
      -->
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-  <style name="Theme_NoSwipeDismiss">
+  <style name="Theme_NoSwipeDismiss" parent="android:Theme.DeviceDefault">
     <item name="android:windowSwipeToDismiss">false</item>
   </style>
 </resources>
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index f69e961..acd6849 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -119,7 +119,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -2946,6 +2948,92 @@
         assertFalse(mockView1.hasCalledOnTouchEvent());
     }
 
+    /**
+     * Ensure two MotionEvents are equal, for the purposes of this test only.
+     * Only compare actions, source, and times.
+     * Do not compare coordinates, because the injected event has coordinates relative to
+     * the screen, while the event received by view will be adjusted relative to the parent.
+     *
+     * Due to event batching, if two or more input events are injected / occur between two
+     * consecutive vsync's, they might end up getting combined into a single MotionEvent.
+     * It is caller's responsibility to ensure that the events were injected with a gap that's
+     * larger than time between two vsyncs, in order for this function to behave predictably.
+     *
+     * Recycle both MotionEvents.
+     */
+    private static void compareAndRecycleMotionEvents(MotionEvent event1, MotionEvent event2) {
+        if (event1 == null && event2 == null) {
+            return;
+        }
+
+        if (event1 == null) {
+            event2.recycle();
+            fail("Expected non-null event in first position");
+        }
+        if (event2 == null) {
+            event1.recycle();
+            fail("Expected non-null event in second position");
+        }
+
+        assertEquals(event1.getAction(), event2.getAction());
+        assertEquals(event1.getPointerCount(), event2.getPointerCount());
+        assertEquals(event1.getSource(), event2.getSource());
+        assertEquals(event1.getDownTime(), event2.getDownTime());
+        // If resampling occurs, the "real" (injected) events will become historical data,
+        // and resampled events will be inserted into MotionEvent and returned by the standard api.
+        // Since the injected event should contain no history, but the event received by
+        // the view might, we could distinguish them. But for simplicity, only require that
+        // the events are close in time if historical data is present.
+        if (event1.getHistorySize() == 0 && event2.getHistorySize() == 0) {
+            assertEquals(event1.getEventTime(), event2.getEventTime());
+        } else {
+            assertEquals(event1.getEventTime(), event2.getEventTime(), 20 /*delta*/);
+        }
+
+        event1.recycle();
+        event2.recycle();
+    }
+
+    @Test
+    public void testOnTouchListener() {
+        BlockingQueue<MotionEvent> events = new LinkedBlockingQueue<>();
+        class TestTouchListener implements View.OnTouchListener {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                events.add(MotionEvent.obtain(event));
+                return true;
+            }
+        }
+
+        // Inject some touch events
+        TestTouchListener listener = new TestTouchListener();
+        View view = mActivity.findViewById(R.id.mock_view);
+        view.setOnTouchListener(listener);
+
+        int[] xy = new int[2];
+        view.getLocationOnScreen(xy);
+
+        final int viewWidth = view.getWidth();
+        final int viewHeight = view.getHeight();
+        final float x = xy[0] + viewWidth / 2.0f;
+        final float y = xy[1] + viewHeight / 2.0f;
+
+        final long downTime = SystemClock.uptimeMillis();
+        MotionEvent downEvent =
+                MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN, x, y, 0);
+        downEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        mInstrumentation.getUiAutomation().injectInputEvent(downEvent, true);
+        final long eventTime = SystemClock.uptimeMillis();
+        MotionEvent upEvent =
+                MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
+        upEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        mInstrumentation.getUiAutomation().injectInputEvent(upEvent, true);
+
+        compareAndRecycleMotionEvents(downEvent, events.poll());
+        compareAndRecycleMotionEvents(upEvent, events.poll());
+        assertTrue(events.isEmpty());
+    }
+
     @Test
     public void testInvalidate1() throws Throwable {
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
diff --git a/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java b/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java
index 4cc5ec6..606bde9 100644
--- a/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java
@@ -30,6 +30,7 @@
 import android.app.Instrumentation;
 import android.app.UiAutomation;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.text.TextUtils;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.NumberPicker;
@@ -340,11 +341,15 @@
         final int[] numberPickerLocationOnScreen = new int[2];
         mNumberPicker.getLocationOnScreen(numberPickerLocationOnScreen);
 
+        int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
+        int numberPickerMiddleX = numberPickerLocationOnScreen[0] + mNumberPicker.getWidth() / 2;
+        int numberPickerStartY = numberPickerLocationOnScreen[1] + 1;
+
         CtsTouchUtils.emulateDragGesture(mInstrumentation,
-                numberPickerLocationOnScreen[0] + mNumberPicker.getWidth() / 2,
-                numberPickerLocationOnScreen[1] + 1,
+                numberPickerMiddleX,
+                numberPickerStartY,
                 0,
-                mNumberPicker.getHeight() - 2);
+                screenHeight - numberPickerStartY); // drag down to the bottom of the screen.
 
         // At this point we expect that the drag-down gesture has selected the value
         // that was "above" the previously selected one, and that our value change listener
@@ -389,12 +394,15 @@
         final int[] numberPickerLocationOnScreen = new int[2];
         mNumberPicker.getLocationOnScreen(numberPickerLocationOnScreen);
 
+        int numberPickerMiddleX = numberPickerLocationOnScreen[0] + mNumberPicker.getWidth() / 2;
+        int numberPickerEndY = numberPickerLocationOnScreen[1] + mNumberPicker.getHeight() - 1;
+
         mUiAutomation.executeAndWaitForEvent(() ->
                         CtsTouchUtils.emulateDragGesture(mInstrumentation,
-                                numberPickerLocationOnScreen[0] + mNumberPicker.getWidth() / 2,
-                                numberPickerLocationOnScreen[1] + mNumberPicker.getHeight() - 1,
+                                numberPickerMiddleX,
+                                numberPickerEndY,
                                 0,
-                                -(mNumberPicker.getHeight() - 2)),
+                                -(numberPickerEndY)), // drag up to the top of the screen.
                 (AccessibilityEvent event) ->
                         event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED,
                 TIMEOUT_ACCESSIBILITY_EVENT);
@@ -434,4 +442,5 @@
         mNumberPicker.setWrapSelectorWheel(true);
         assertTrue(mNumberPicker.getWrapSelectorWheel());
     }
+
 }
diff --git a/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java b/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java
index 54d7c22..15bcb3bd 100644
--- a/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ZoomButtonTest.java
@@ -160,7 +160,7 @@
             assertTrue("First callback should have happened sooner than "
                             + actualTimeUntilFirstInvocationNs / NANOS_IN_MILLI,
                     (callbackFirstInvocationTime - startTime)
-                            <= (minTimeUntilFirstInvocationMs + 100) * NANOS_IN_MILLI);
+                            <= (minTimeUntilFirstInvocationMs + 200) * NANOS_IN_MILLI);
         }
     }