Merge "Revert "Add cts to test unwanted capabilities api"" into pi-dev
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index 920d40c..d212680 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -25,8 +25,9 @@
 
 import numpy as np
 
-ALIGN_THRESH = 0.005
+ALIGN_TOL_PERCENT = 1
 CHART_DISTANCE_CM = 22  # cm
+CIRCLE_TOL_PERCENT = 10
 NAME = os.path.basename(__file__).split('.')[0]
 ROTATE_REF_MATRIX = np.array([0, 0, 0, 1])
 TRANS_REF_MATRIX = np.array([0, 0, 0])
@@ -56,22 +57,22 @@
         gray:           gray scale image array [0,255]
         name:           string of file name
     Returns:
-        center:         circle center location (x, y)
+        circle:         (circle_center_x, circle_center_y, radius)
     """
 
     cv2_version = cv2.__version__
     try:
         if cv2_version.startswith('2.4.'):
-            center = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT,
+            circle = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT,
                                       1, 20)[0][0]
         elif cv2_version.startswith('3.2.'):
-            center = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT,
+            circle = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT,
                                       1, 20)[0][0]
     except TypeError:
-        center = None
+        circle = None
         its.image.write_image(gray[..., np.newaxis]/255.0, name)
-    assert center is not None, 'No circle found!'
-    return center
+    assert circle is not None, 'No circle found!'
+    return circle
 
 
 def main():
@@ -89,8 +90,8 @@
                              its.caps.logical_multi_camera(props) and
                              its.caps.raw16(props) and
                              its.caps.manual_sensor(props))
-        props = cam.get_camera_properties()
         debug = its.caps.debug_mode()
+        avail_fls = props['android.lens.info.availableFocalLengths']
 
         max_raw_size = its.objects.get_available_output_sizes('raw', props)[0]
         w, h = its.objects.get_available_output_sizes(
@@ -121,6 +122,8 @@
     rotation = {}
     trans = {}
     circle = {}
+    fl = {}
+    sensor_diag = {}
     point = {}
     for i in ids:
         print 'Starting camera %s' % i
@@ -179,6 +182,10 @@
         circle[i] = find_circle(cv2.cvtColor(img_rot, cv2.COLOR_BGR2GRAY),
                                 '%s_gray%s.jpg' % (NAME, i))
 
+        # Find focal length & sensor size
+        fl[i] = props_physical[i]['android.lens.info.availableFocalLengths'][0]
+        sensor_diag[i] = math.sqrt(size_raw[i][0] ** 2 + size_raw[i][1] ** 2)
+
         # Find 3D location of circle centers
         point[i] = np.dot(np.linalg.inv(k[i]),
                           np.array([circle[i][0],
@@ -195,7 +202,7 @@
     t = -1 * trans[ref_index]
     print 't:', t
 
-    # estimation ids[0] circle center from ids[1] & params
+    # Estimate ids[0] circle center from ids[1] & params
     estimated_0 = cv2.projectPoints(point[ids[1]].reshape(1, 3),
                                     r, t, k[ids[0]], None)[0][0][0]
     err_0 = np.linalg.norm(estimated_0 - circle[ids[0]][:2])
@@ -205,7 +212,7 @@
                                          estimated_0[0])
     print 'Error(pixels): %.1f' % err_0
 
-    # estimation ids[0] circle center from ids[1] & params
+    # Estimate ids[0] circle center from ids[1] & params
     estimated_1 = cv2.projectPoints(point[ids[0]].reshape(1, 3),
                                     r.T, -np.dot(r, t), k[ids[1]],
                                     None)[0][0][0]
@@ -218,11 +225,23 @@
     err_0 /= math.sqrt(size_raw[ids[0]][0]**2 + size_raw[ids[0]][1]**2)
     err_1 /= math.sqrt(size_raw[ids[1]][0]**2 + size_raw[ids[1]][1]**2)
     msg = '%s -> %s center error too large! val=%.1f%%, THRESH=%.f%%' % (
-            ids[1], ids[0], err_0*100, ALIGN_THRESH*100)
-    assert err_0 < ALIGN_THRESH, msg
+            ids[1], ids[0], err_0*100, ALIGN_TOL_PERCENT)
+    assert err_0*100 < ALIGN_TOL_PERCENT, msg
     msg = '%s -> %s center error too large! val=%.1f%%, THRESH=%.f%%' % (
-            ids[0], ids[1], err_1*100, ALIGN_THRESH*100)
-    assert err_1 < ALIGN_THRESH, msg
+            ids[0], ids[1], err_1*100, ALIGN_TOL_PERCENT)
+    assert err_1*100 < ALIGN_TOL_PERCENT, msg
+
+    # Check focal length and circle size if more than 1 focal length
+    if len(avail_fls) > 1:
+        print 'circle_0: %.2f, circle_1: %.2f' % (
+                circle[ids[0]][2], circle[ids[1]][2])
+        print 'fl_0: %.2f, fl_1: %.2f' % (fl[ids[0]], fl[ids[1]])
+        print 'diag_0: %.2f, diag_1: %.2f' % (
+                sensor_diag[ids[0]], sensor_diag[ids[1]])
+        msg = 'Circle size does not scale properly.'
+        assert np.isclose(circle[ids[0]][2]/fl[ids[0]]*sensor_diag[ids[0]],
+                          circle[ids[1]][2]/fl[ids[1]]*sensor_diag[ids[1]],
+                          rtol=CIRCLE_TOL_PERCENT/100.0), msg
 
 
 if __name__ == '__main__':
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 93be556..d503870 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -271,6 +271,52 @@
         </activity>
 
         <!--
+             CTS Verifier Bluetooth Hid Device Test Screen
+                 test category : bt_device_communication
+                 test parent : BluetoothTestActivity
+        -->
+        <activity
+            android:name=".bluetooth.HidDeviceActivity"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:label="@string/bt_hid_device" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+
+            <meta-data
+                android:name="test_category"
+                android:value="@string/bt_hid" />
+            <meta-data
+                android:name="test_parent"
+                android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
+        </activity>
+
+        <!--
+             CTS Verifier Bluetooth Hid Host Test Screen
+                 test category : bt_device_communication
+                 test parent : BluetoothTestActivity
+        -->
+        <activity
+            android:name=".bluetooth.HidHostActivity"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:label="@string/bt_hid_host" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+
+            <meta-data
+                android:name="test_category"
+                android:value="@string/bt_hid" />
+            <meta-data
+                android:name="test_parent"
+                android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
+        </activity>
+
+        <!--
              CTS Verifier Bluetooth Secure Server Test Screen
                  test category : bt_device_communication
                  test parent : BluetoothTestActivity
diff --git a/apps/CtsVerifier/res/layout/bt_hid_device.xml b/apps/CtsVerifier/res/layout/bt_hid_device.xml
new file mode 100644
index 0000000..39d9ecd
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/bt_hid_device.xml
@@ -0,0 +1,65 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+  <TextView
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:text="@string/bt_hid_device_register" />
+
+  <Button
+      android:id="@+id/bt_hid_device_register_button"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:text="@string/bt_hid_device_register" />
+
+  <Button
+      android:id="@+id/bt_hid_device_discoverable_button"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:text="@string/bt_make_discoverable" />
+
+  <Button
+      android:id="@+id/bt_hid_device_send_report_button"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:text="@string/bt_hid_device_send_report" />
+
+  <Button
+      android:id="@+id/bt_hid_device_reply_report_button"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:text="@string/bt_hid_device_reply_report" />
+
+  <Button
+      android:id="@+id/bt_hid_device_report_error_button"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:text="@string/bt_hid_device_report_error" />
+
+  <Button
+      android:id="@+id/bt_hid_device_unregister_button"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:text="@string/bt_hid_device_unregister" />
+
+  <include layout="@layout/pass_fail_buttons" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/bt_hid_host.xml b/apps/CtsVerifier/res/layout/bt_hid_host.xml
new file mode 100644
index 0000000..ec8f627
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/bt_hid_host.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/RootLayoutPadding"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+  <Button
+      android:id="@+id/bt_hid_host_pick_device_button"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:text="@string/bt_hid_host_select_device" />
+
+  <EditText
+      android:id="@+id/bt_hid_host_edit_text"
+      android:layout_width="match_parent"
+      android:layout_height="60dp" />
+
+  <include layout="@layout/pass_fail_buttons" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 6816429..23ca345 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -192,6 +192,7 @@
     <string name="bt_control">Bluetooth Control</string>
     <string name="bt_device_communication">Device Communication</string>
     <string name="bt_le">Bluetooth LE</string>
+    <string name="bt_hid">Bluetooth HID</string>
 
     <string name="bt_toggle_bluetooth">Toggle Bluetooth</string>
     <string name="bt_toggle_instructions">Disable and enable Bluetooth to successfully complete this test.</string>
@@ -224,6 +225,40 @@
         devices together and start the test.
     </string>
 
+    <!-- Strings for HidHost and HidDevice activity -->
+    <string name="bt_hid_host_test_name">Bluetooth HID Host Test</string>
+    <string name="bt_hid_host_test_info">
+        Start the CTS Verifier on another device, start the Bluetooth test, and choose
+        \"Bluetooth HID Device\" to complete the test.
+        \n\nClick \"Register app\" and \"Make discoverable\" on another device first, and click
+        \"Select device\". Choose the device from device picker. If the remote device is already
+        paired, unpair it first from system Settings.
+        \n\nAfter the remote device completes the \"Send_report\" command, text \"bluetooth\" should
+        appear in the EditText. Mark the test as passed.
+    </string>
+    <string name="bt_hid_host">Bluetooth HID Host</string>
+    <string name="bt_hid_host_select_device">Select device</string>
+
+    <string name="bt_hid_device_test_name">Bluetooth HID Device Test</string>
+    <string name="bt_hid_device_test_info">
+        Start the CTS Verifier on another device, start the Bluetooth test, and choose
+        \"Bluetooth HID Host\" to complete the test.
+        \n\nFirst, click the \"Register app\" button, and click the \"Make discoverable\" button.
+        \n\nThen, on another device, click the \"Select device" button, and choose this device.
+        \n\nWait until the dialog shows up for pairing two devices.
+        \n\nFinally, click the \"Test send_report\", \"Test reply_report\", \"Test report_error\".
+        \n\nIf all the commands are successful, then click \"Unregister app\" and mark the test as
+        passed.
+    </string>
+
+    <string name="bt_hid_device">Bluetooth HID Device</string>
+    <string name="bt_hid_device_register">Register app</string>
+    <string name="bt_hid_device_unregister">Unregister app</string>
+    <string name="bt_hid_device_send_report">Test Send_report</string>
+    <string name="bt_hid_device_reply_report">Test Reply_report</string>
+    <string name="bt_hid_device_report_error">Test Report_error</string>
+
+
     <string name="bt_secure_server">Secure Server</string>
     <string name="bt_secure_server_instructions">Start the CTS Verifier on another device, start the Bluetooth test, and choose \"Secure Client\" to complete the test.</string>
     <string name="bt_insecure_server">Insecure Server</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidConstants.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidConstants.java
new file mode 100644
index 0000000..ee7fda5
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidConstants.java
@@ -0,0 +1,126 @@
+/*
+ * 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.verifier.bluetooth;
+
+public class HidConstants {
+    public static final byte ID_KEYBOARD = 1;
+    public static final byte ID_MOUSE = 2;
+
+    public static final byte[] HIDD_REPORT_DESC = {
+            (byte) 0x05,
+            (byte) 0x01, // Usage page (Generic Desktop)
+            (byte) 0x09,
+            (byte) 0x06, // Usage (Keyboard)
+            (byte) 0xA1,
+            (byte) 0x01, // Collection (Application)
+            (byte) 0x85,
+            ID_KEYBOARD, //    Report ID
+            (byte) 0x05,
+            (byte) 0x07, //       Usage page (Key Codes)
+            (byte) 0x19,
+            (byte) 0xE0, //       Usage minimum (224)
+            (byte) 0x29,
+            (byte) 0xE7, //       Usage maximum (231)
+            (byte) 0x15,
+            (byte) 0x00, //       Logical minimum (0)
+            (byte) 0x25,
+            (byte) 0x01, //       Logical maximum (1)
+            (byte) 0x75,
+            (byte) 0x01, //       Report size (1)
+            (byte) 0x95,
+            (byte) 0x08, //       Report count (8)
+            (byte) 0x81,
+            (byte) 0x02, //       Input (Data, Variable, Absolute) ; Modifier byte
+            (byte) 0x75,
+            (byte) 0x08, //       Report size (8)
+            (byte) 0x95,
+            (byte) 0x01, //       Report count (1)
+            (byte) 0x81,
+            (byte) 0x01, //       Input (Constant)                 ; Reserved byte
+            (byte) 0x75,
+            (byte) 0x08, //       Report size (8)
+            (byte) 0x95,
+            (byte) 0x06, //       Report count (6)
+            (byte) 0x15,
+            (byte) 0x00, //       Logical Minimum (0)
+            (byte) 0x25,
+            (byte) 0x65, //       Logical Maximum (101)
+            (byte) 0x05,
+            (byte) 0x07, //       Usage page (Key Codes)
+            (byte) 0x19,
+            (byte) 0x00, //       Usage Minimum (0)
+            (byte) 0x29,
+            (byte) 0x65, //       Usage Maximum (101)
+            (byte) 0x81,
+            (byte) 0x00, //       Input (Data, Array)              ; Key array (6 keys)
+            (byte) 0xC0, // End Collection
+            (byte) 0x05,
+            (byte) 0x01, // Usage Page (Generic Desktop)
+            (byte) 0x09,
+            (byte) 0x02, // Usage (Mouse)
+            (byte) 0xA1,
+            (byte) 0x01, // Collection (Application)
+            (byte) 0x85,
+            ID_MOUSE, //    Report ID
+            (byte) 0x09,
+            (byte) 0x01, //    Usage (Pointer)
+            (byte) 0xA1,
+            (byte) 0x00, //    Collection (Physical)
+            (byte) 0x05,
+            (byte) 0x09, //       Usage Page (Buttons)
+            (byte) 0x19,
+            (byte) 0x01, //       Usage minimum (1)
+            (byte) 0x29,
+            (byte) 0x03, //       Usage maximum (3)
+            (byte) 0x15,
+            (byte) 0x00, //       Logical minimum (0)
+            (byte) 0x25,
+            (byte) 0x01, //       Logical maximum (1)
+            (byte) 0x75,
+            (byte) 0x01, //       Report size (1)
+            (byte) 0x95,
+            (byte) 0x03, //       Report count (3)
+            (byte) 0x81,
+            (byte) 0x02, //       Input (Data, Variable, Absolute)
+            (byte) 0x75,
+            (byte) 0x05, //       Report size (5)
+            (byte) 0x95,
+            (byte) 0x01, //       Report count (1)
+            (byte) 0x81,
+            (byte) 0x01, //       Input (constant)                 ; 5 bit padding
+            (byte) 0x05,
+            (byte) 0x01, //       Usage page (Generic Desktop)
+            (byte) 0x09,
+            (byte) 0x30, //       Usage (X)
+            (byte) 0x09,
+            (byte) 0x31, //       Usage (Y)
+            (byte) 0x09,
+            (byte) 0x38, //       Usage (Wheel)
+            (byte) 0x15,
+            (byte) 0x81, //       Logical minimum (-127)
+            (byte) 0x25,
+            (byte) 0x7F, //       Logical maximum (127)
+            (byte) 0x75,
+            (byte) 0x08, //       Report size (8)
+            (byte) 0x95,
+            (byte) 0x03, //       Report count (3)
+            (byte) 0x81,
+            (byte) 0x06, //       Input (Data, Variable, Relative)
+            (byte) 0xC0, //    End Collection
+            (byte) 0xC0 // End Collection
+    };
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidDeviceActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidDeviceActivity.java
new file mode 100644
index 0000000..534b030
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidDeviceActivity.java
@@ -0,0 +1,273 @@
+/*
+ * 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.verifier.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHidDevice;
+import android.bluetooth.BluetoothHidDeviceAppQosSettings;
+import android.bluetooth.BluetoothHidDeviceAppSdpSettings;
+import android.bluetooth.BluetoothProfile;
+import android.content.Intent;
+import android.os.Bundle;
+
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class HidDeviceActivity extends PassFailButtons.Activity {
+    private static final String TAG = HidDeviceActivity.class.getSimpleName();
+    private static final int MSG_APP_STATUS_CHANGED = 0;
+    private static final String SDP_NAME = "CtsVerifier";
+    private static final String SDP_DESCRIPTION = "CtsVerifier HID Device test";
+    private static final String SDP_PROVIDER = "Android";
+    private static final int QOS_TOKEN_RATE = 800; // 9 bytes * 1000000 us / 11250 us
+    private static final int QOS_TOKEN_BUCKET_SIZE = 9;
+    private static final int QOS_PEAK_BANDWIDTH = 0;
+    private static final int QOS_LATENCY = 11250;
+    static final String SAMPLE_INPUT = "bluetooth";
+
+    private BluetoothAdapter mBluetoothAdapter;
+    private BluetoothHidDevice mBluetoothHidDevice;
+    private BluetoothDevice mHidHost;
+    private ExecutorService mExecutor;
+
+    private Button mRegisterAppButton;
+    private Button mMakeDiscoverableButton;
+    private Button mUnregisterAppButton;
+    private Button mSendReportButton;
+    private Button mReplyReportButton;
+    private Button mReportErrorButton;
+
+    private BluetoothProfile.ServiceListener mProfileListener =
+            new BluetoothProfile.ServiceListener() {
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            if (profile == BluetoothProfile.HID_DEVICE) {
+                mBluetoothHidDevice = (BluetoothHidDevice) proxy;
+            }
+        }
+
+        public void onServiceDisconnected(int profile) {
+            if (profile == BluetoothProfile.HID_DEVICE) {
+                mBluetoothHidDevice = null;
+            }
+        }
+    };
+
+    private final BluetoothHidDeviceAppSdpSettings mSdpSettings =
+            new BluetoothHidDeviceAppSdpSettings(
+                    SDP_NAME,
+                    SDP_DESCRIPTION,
+                    SDP_PROVIDER,
+                    BluetoothHidDevice.SUBCLASS1_COMBO,
+                    HidConstants.HIDD_REPORT_DESC);
+
+    private final BluetoothHidDeviceAppQosSettings mOutQos =
+            new BluetoothHidDeviceAppQosSettings(
+                    BluetoothHidDeviceAppQosSettings.SERVICE_BEST_EFFORT,
+                    QOS_TOKEN_RATE,
+                    QOS_TOKEN_BUCKET_SIZE,
+                    QOS_PEAK_BANDWIDTH,
+                    QOS_LATENCY,
+                    BluetoothHidDeviceAppQosSettings.MAX);
+
+    private BluetoothHidDevice.Callback mCallback = new BluetoothHidDevice.Callback() {
+        @Override
+        public void onAppStatusChanged(BluetoothDevice pluggedDevice, boolean registered) {
+            Log.d(TAG, "onAppStatusChanged: pluggedDevice=" + pluggedDevice + " registered="
+                    + registered);
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.bt_hid_device);
+        setPassFailButtonClickListeners();
+        setInfoResources(R.string.bt_hid_device_test_name, R.string.bt_hid_device_test_info, -1);
+        getPassButton().setEnabled(false);
+
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        mBluetoothAdapter.getProfileProxy(getApplicationContext(), mProfileListener,
+                BluetoothProfile.HID_DEVICE);
+        mExecutor = Executors.newSingleThreadExecutor();
+
+        mRegisterAppButton = (Button) findViewById(R.id.bt_hid_device_register_button);
+        mRegisterAppButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                register();
+            }
+        });
+
+        mUnregisterAppButton = (Button) findViewById(R.id.bt_hid_device_unregister_button);
+        mUnregisterAppButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                unregister();
+            }
+        });
+
+        mMakeDiscoverableButton = (Button) findViewById(R.id.bt_hid_device_discoverable_button);
+        mMakeDiscoverableButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                makeDiscoverable();
+            }
+        });
+
+        mSendReportButton = (Button) findViewById(R.id.bt_hid_device_send_report_button);
+        mSendReportButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                testSendReport();
+            }
+        });
+
+        mReplyReportButton = (Button) findViewById(R.id.bt_hid_device_reply_report_button);
+        mReplyReportButton.setEnabled(false);
+        mReplyReportButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                testReplyReport();
+            }
+        });
+
+        mReportErrorButton = (Button) findViewById(R.id.bt_hid_device_report_error_button);
+        mReportErrorButton.setEnabled(false);
+        mReportErrorButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                testReportError();
+            }
+        });
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        unregister();
+    }
+
+    private boolean register() {
+        return mBluetoothHidDevice != null
+                && mBluetoothHidDevice.registerApp(mSdpSettings, null, mOutQos, mExecutor,
+                mCallback);
+    }
+
+    private void makeDiscoverable() {
+        if (mBluetoothAdapter.getScanMode() !=
+                BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
+            intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 30);
+            startActivity(intent);
+        }
+    }
+
+    private boolean unregister() {
+        return mBluetoothHidDevice != null && mBluetoothHidDevice.unregisterApp();
+    }
+
+
+    private boolean getConnectedDevice() {
+        List<BluetoothDevice> connectedDevices = mBluetoothHidDevice.getConnectedDevices();
+        if (connectedDevices.size() == 0) {
+            return false;
+        } else {
+            return false;
+        }
+    }
+
+    private void testSendReport() {
+        if (mHidHost == null) {
+            if (mBluetoothHidDevice.getConnectedDevices().size() == 0) {
+                Log.w(TAG, "HID host not connected");
+                return;
+            } else {
+                mHidHost = mBluetoothHidDevice.getConnectedDevices().get(0);
+                Log.d(TAG, "connected to: " + mHidHost);
+            }
+        }
+        for (char c : SAMPLE_INPUT.toCharArray()) {
+            mBluetoothHidDevice.sendReport(mHidHost, BluetoothHidDevice.REPORT_TYPE_INPUT,
+                    singleKeyHit(charToKeyCode(c)));
+            mBluetoothHidDevice.sendReport(mHidHost, BluetoothHidDevice.REPORT_TYPE_INPUT,
+                    singleKeyHit((byte) 0));
+        }
+        mReplyReportButton.setEnabled(true);
+
+    }
+
+    private void testReplyReport() {
+        if (mHidHost == null) {
+            if (mBluetoothHidDevice.getConnectedDevices().size() == 0) {
+                Log.w(TAG, "HID host not connected");
+                return;
+            } else {
+                mHidHost = mBluetoothHidDevice.getConnectedDevices().get(0);
+                Log.d(TAG, "connected to: " + mHidHost);
+            }
+        }
+        if (mBluetoothHidDevice.replyReport(mHidHost, (byte) 0, (byte) 0,
+                singleKeyHit((byte) 0))) {
+            mReportErrorButton.setEnabled(true);
+        }
+    }
+
+    private void testReportError() {
+        if (mHidHost == null) {
+            if (mBluetoothHidDevice.getConnectedDevices().size() == 0) {
+                Log.w(TAG, "HID host not connected");
+                return;
+            } else {
+                mHidHost = mBluetoothHidDevice.getConnectedDevices().get(0);
+                Log.d(TAG, "connected to: " + mHidHost);
+            }
+        }
+        if (mBluetoothHidDevice.reportError(mHidHost, (byte) 0)) {
+            getPassButton().setEnabled(true);
+        }
+    }
+
+
+    private byte[] singleKeyHit(byte code) {
+        byte[] keyboardData = new byte[8];
+        keyboardData[0] = 0;
+        keyboardData[1] = 0;
+        keyboardData[2] = code;
+        keyboardData[3] = 0;
+        keyboardData[4] = 0;
+        keyboardData[5] = 0;
+        keyboardData[6] = 0;
+        keyboardData[7] = 0;
+        return keyboardData;
+    }
+
+    private byte charToKeyCode(char c) {
+        if (c < 'a' || c > 'z') {
+            return 0;
+        }
+        return (byte) (c - 'a' + 0x04);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidHostActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidHostActivity.java
new file mode 100644
index 0000000..c3bcbf6
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/HidHostActivity.java
@@ -0,0 +1,107 @@
+/*
+ * 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.verifier.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestResult;
+
+public class HidHostActivity extends PassFailButtons.Activity {
+    private static final String TAG = HidHostActivity.class.getSimpleName();
+
+    BluetoothAdapter mBluetoothAdapter;
+
+    private static final int ENABLE_BLUETOOTH_REQUEST = 1;
+    private static final int PICK_SERVER_DEVICE_REQUEST = 2;
+
+    private String mDeviceAddress;
+
+    private Button mPickDeviceButton;
+    private EditText mEditText;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.bt_hid_host);
+        setPassFailButtonClickListeners();
+        setInfoResources(R.string.bt_hid_host_test_name, R.string.bt_hid_host_test_info, -1);
+        getPassButton().setEnabled(false);
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+
+        mEditText = (EditText) findViewById(R.id.bt_hid_host_edit_text);
+        mEditText.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                if (s.toString().equals(HidDeviceActivity.SAMPLE_INPUT)) {
+                    getPassButton().setEnabled(true);
+                }
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {}
+        });
+        mPickDeviceButton = (Button) findViewById(R.id.bt_hid_host_pick_device_button);
+        mPickDeviceButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(HidHostActivity.this,
+                        DevicePickerActivity.class);
+                startActivityForResult(intent, PICK_SERVER_DEVICE_REQUEST);
+                mEditText.requestFocus();
+            }
+        });
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        switch (requestCode) {
+            case PICK_SERVER_DEVICE_REQUEST:
+                Log.d(TAG, "pick device: " + resultCode);
+                if (resultCode == RESULT_OK) {
+                    mDeviceAddress = data.getStringExtra(DevicePickerActivity.EXTRA_DEVICE_ADDRESS);
+                    connectToDevice();
+                } else {
+                    setResult(RESULT_CANCELED);
+                    finish();
+                }
+                break;
+        }
+    }
+
+    private boolean connectToDevice() {
+        BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(mDeviceAddress);
+        bluetoothDevice.createBond();
+        return true;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
index 313505e..4fa6235 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
@@ -17,6 +17,7 @@
 
 
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.FreezePeriod;
 import android.app.admin.SystemUpdatePolicy;
 import android.app.admin.SystemUpdatePolicy.ValidationFailedException;
 import android.content.BroadcastReceiver;
@@ -29,6 +30,7 @@
 import android.util.Pair;
 
 import java.time.LocalDate;
+import java.time.MonthDay;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Semaphore;
@@ -255,12 +257,12 @@
         setFreezePeriods(policy, dates);
         mDevicePolicyManager.setSystemUpdatePolicy(getWho(), policy);
 
-        List<Pair<Integer, Integer>> loadedFreezePeriods = mDevicePolicyManager
+        List<FreezePeriod> loadedFreezePeriods = mDevicePolicyManager
                 .getSystemUpdatePolicy().getFreezePeriods();
         assertEquals(dates.length / 2, loadedFreezePeriods.size());
         for (int i = 0; i < dates.length; i += 2) {
-            assertEquals(parseDate(dates[i]), (int) loadedFreezePeriods.get(i / 2).first);
-            assertEquals(parseDate(dates[i + 1]), (int) loadedFreezePeriods.get(i / 2).second);
+            assertEquals(parseMonthDay(dates[i]), loadedFreezePeriods.get(i / 2).getStart());
+            assertEquals(parseMonthDay(dates[i + 1]), loadedFreezePeriods.get(i / 2).getEnd());
         }
     }
 
@@ -296,18 +298,16 @@
 
     //dates are in MM-DD format
     private void setFreezePeriods(SystemUpdatePolicy policy, String... dates) {
-        List<Pair<Integer, Integer>> periods = new ArrayList<>();
+        List<FreezePeriod> periods = new ArrayList<>();
         for (int i = 0; i < dates.length; i+= 2) {
-            periods.add(new Pair<>(parseDate(dates[i]), parseDate(dates[i + 1])));
+            periods.add(new FreezePeriod(parseMonthDay(dates[i]), parseMonthDay(dates[i + 1])));
         }
         policy.setFreezePeriods(periods);
     }
 
-    private int parseDate(String date) {
-        // Use leap year when parsing date string to handle "02-29", but force round down
-        // to Feb 28th by overriding the year to non-leap year.
-        return  LocalDate.of(2000, Integer.parseInt(date.substring(0, 2)),
-                Integer.parseInt(date.substring(3, 5))).withYear(2001).getDayOfYear();
+    private MonthDay parseMonthDay(String date) {
+        return MonthDay.of(Integer.parseInt(date.substring(0, 2)),
+                Integer.parseInt(date.substring(3, 5)));
     }
 
     private void clearFreezeRecord() throws Exception {
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java
index f086656..17cea9b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java
@@ -77,6 +77,7 @@
             .add("setTrustAgentConfiguration")
             .add("getRequiredStrongAuthTimeout")
             .add("setRequiredStrongAuthTimeout")
+            .add("isDeviceIdAttestationSupported")
             .build();
 
     private static final String LOG_TAG = "ParentProfileTest";
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java
index 8c7adbc5..803ae3f 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java
@@ -50,6 +50,9 @@
     }
 
     public void testQuietMode() throws Exception {
+        if (!mHasFeature) {
+          return;
+        }
         runDeviceTestsAsUser(
                 TEST_PACKAGE,
                 TEST_CLASS,
@@ -70,4 +73,4 @@
         params.put(PARAM_ORIGINAL_DEFAULT_LAUNCHER, mOriginalLauncher);
         return params;
     }
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
index 2ae5265..0614db6 100644
--- a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
+++ b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
@@ -43,7 +43,6 @@
         assertTrue(batterystats.length() > 0);
 
         Set<String> seenTags = new HashSet<>();
-        int version = -1;
 
         try (BufferedReader reader = new BufferedReader(
                 new StringReader(batterystats))) {
@@ -95,7 +94,10 @@
                         checkVibrator(parts);
                         break;
                     case "fg":
-                        checkForeground(parts);
+                        checkForegroundActivity(parts);
+                        break;
+                    case "fgs":
+                        checkForegroundService(parts);
                         break;
                     case "st":
                         checkStateTime(parts);
@@ -112,6 +114,12 @@
                     case "jb":
                         checkJob(parts);
                         break;
+                    case "jbc":
+                        checkJobCompletion(parts);
+                        break;
+                    case "jbd":
+                        checkJobsDeferred(parts);
+                        break;
                     case "kwl":
                         checkKernelWakelock(parts);
                         break;
@@ -258,20 +266,27 @@
         assertInteger(parts[5]); // count
     }
 
-    private void checkForeground(String[] parts) {
+    private void checkForegroundActivity(String[] parts) {
+        assertEquals(6, parts.length);
+        assertInteger(parts[4]); // totalTime
+        assertInteger(parts[5]); // count
+    }
+
+    private void checkForegroundService(String[] parts) {
         assertEquals(6, parts.length);
         assertInteger(parts[4]); // totalTime
         assertInteger(parts[5]); // count
     }
 
     private void checkStateTime(String[] parts) {
-        assertEquals(10, parts.length);
-        assertInteger(parts[4]); // top
-        assertInteger(parts[5]); // foreground_service
-        assertInteger(parts[6]); // top_sleeping
-        assertInteger(parts[7]); // foreground
-        assertInteger(parts[8]); // background
-        assertInteger(parts[9]); // cached
+        assertEquals(11, parts.length);
+        assertInteger(parts[4]);  // top
+        assertInteger(parts[5]);  // foreground_service
+        assertInteger(parts[6]);  // foreground
+        assertInteger(parts[7]);  // background
+        assertInteger(parts[8]);  // top_sleeping
+        assertInteger(parts[9]);  // heavy_weight
+        assertInteger(parts[10]); // cached
     }
 
     private void checkWakelock(String[] parts) {
@@ -337,6 +352,28 @@
         assertInteger(parts[8]); // bgCount
     }
 
+    private void checkJobCompletion(String[] parts) {
+        assertEquals(10, parts.length);
+        assertNotNull(parts[4]); // job
+        assertInteger(parts[5]); // reason_canceled
+        assertInteger(parts[6]); // reason_constraints_not_satisfied
+        assertInteger(parts[7]); // reason_preempt
+        assertInteger(parts[8]); // reason_timeout
+        assertInteger(parts[9]); // reason_device_idle
+    }
+
+    private void checkJobsDeferred(String[] parts) {
+        assertEquals(12, parts.length);
+        assertInteger(parts[4]); // jobsDeferredEventCount
+        assertInteger(parts[5]); // jobsDeferredCount
+        assertInteger(parts[6]); // totalLatencyMillis
+        assertInteger(parts[7]); // count at latency < 1 hr
+        assertInteger(parts[8]); // count at latency 1-2 hrs
+        assertInteger(parts[9]); // count at latency 2-4 hrs
+        assertInteger(parts[10]); // count at latency 4-8 hrs
+        assertInteger(parts[11]); // count at latency 8+ hrs
+    }
+
     private void checkKernelWakelock(String[] parts) {
         assertTrue(parts.length >= 7);
 	assertNotNull(parts[4]); // Kernel wakelock
@@ -530,7 +567,7 @@
     }
 
     private void checkDataConnection(String[] parts) {
-        assertEquals(21, parts.length);
+        assertEquals(25, parts.length);
         assertInteger(parts[4]);  // none
         assertInteger(parts[5]);  // gprs
         assertInteger(parts[6]);  // edge
@@ -547,7 +584,11 @@
         assertInteger(parts[17]); // lte
         assertInteger(parts[18]); // ehrpd
         assertInteger(parts[19]); // hspap
-        assertInteger(parts[20]); // other
+        assertInteger(parts[20]); // gsm
+        assertInteger(parts[21]); // td_scdma
+        assertInteger(parts[22]); // iwlan
+        assertInteger(parts[23]); // lte_ca
+        assertInteger(parts[24]); // other
     }
 
     private void checkWifiState(String[] parts) {
diff --git a/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java
index 4ab421b..20a6cab 100644
--- a/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java
@@ -26,7 +26,7 @@
 
     public void testMemInfoDump() throws Exception {
         final MemInfoDumpProto dump =
-                getDump(MemInfoDumpProto.parser(), "dumpsys meminfo -a --proto");
+                getDump(MemInfoDumpProto.parser(), "dumpsys -t 30000 meminfo -a --proto");
 
         verifyMemInfoDumpProto(dump, PRIVACY_NONE);
     }
diff --git a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
index 724d235..42ea6c2 100644
--- a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
@@ -85,9 +85,9 @@
         } else if (CpuFeatures.isArmCpu()) {
             return "arm";
         } else if (CpuFeatures.isX86_64Cpu()) {
-            return "x86";
-        } else if (CpuFeatures.isX86Cpu()) {
             return "x86_64";
+        } else if (CpuFeatures.isX86Cpu()) {
+            return "x86";
         } else if (CpuFeatures.isMips64Cpu()) {
             return "mips64";
         } else if (CpuFeatures.isMipsCpu()) {
diff --git a/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerManagedUserTest.java b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerManagedUserTest.java
index 1aa9609..48f8578 100644
--- a/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerManagedUserTest.java
+++ b/hostsidetests/shortcuts/deviceside/multiuser/src/android/content/pm/cts/shortcut/multiuser/ShortcutManagerManagedUserTest.java
@@ -115,22 +115,20 @@
                     assertEquals(userCurrent, si.getUserHandle());
                 });
 
-        try {
-            assertWith(getLauncherApps().getShortcuts(q, userOther)).isEmpty();
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException e) {
-            // okay
-        }
+        // Accessing the main profile from the managed profile, which will not throw, but will
+        // return an empty result.
+        assertWith(getLauncherApps().getShortcuts(q, userOther)).isEmpty();
 
         // TODO Make sure the activity actually starts.
         getLauncherApps().startShortcut(getContext().getPackageName(), "s1", null, null,
                 userCurrent);
 
         try {
+            // This won't throw SecurityException either.
             getLauncherApps().startShortcut(getContext().getPackageName(), "s1", null, null,
                     userOther);
-            fail("Didn't throw SecurityException");
-        } catch (SecurityException e) {
+            fail("Didn't throw ActivityNotFoundException");
+        } catch (ActivityNotFoundException e) {
             // okay
         }
     }
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
index dea5d87..41e51e8 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
@@ -90,6 +90,7 @@
 
         // Uninstall to clear the history in case it's still on the device.
         removeConfig(CONFIG_ID);
+        getReportList(); // Clears data.
     }
 
     @Override
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
index c863dc8..5d0fddc 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
@@ -87,6 +87,7 @@
     protected List<EventMetricData> doDeviceMethod(String methodName, StatsdConfig.Builder cfg)
             throws Exception {
         removeConfig(CONFIG_ID);
+        getReportList();  // Clears previous data on disk.
         uploadConfig(cfg);
         int appUid = getUid();
         LogUtil.CLog.d("\nPerforming device-side test of " + methodName + " for uid " + appUid);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java
new file mode 100644
index 0000000..6e9a462
--- /dev/null
+++ b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTestCase.java
@@ -0,0 +1,46 @@
+/*
+ * 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 android.cts.statsd.metadata;
+
+import android.cts.statsd.atom.AtomTestCase;
+import com.android.internal.os.StatsdConfigProto;
+import com.android.internal.os.StatsdConfigProto.StatsdConfig;
+import com.android.os.AtomsProto.Atom;
+import com.android.os.StatsLog.StatsdStatsReport;
+import com.android.tradefed.log.LogUtil;
+
+public class MetadataTestCase extends AtomTestCase {
+    public static final String DUMP_METADATA_CMD = "cmd stats print-stats";
+
+    protected StatsdStatsReport getStatsdStatsReport() throws Exception {
+        try {
+            StatsdStatsReport report = getDump(StatsdStatsReport.parser(),
+                    String.join(" ", DUMP_METADATA_CMD, "--proto"));
+            return report;
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+            LogUtil.CLog.e("Failed to fetch and parse the statsdstats output report.");
+            throw (e);
+        }
+    }
+
+    protected final StatsdConfig.Builder getBaseConfig() throws Exception {
+        StatsdConfig.Builder builder =  StatsdConfig.newBuilder().setId(CONFIG_ID)
+                .addAllowedLogSource("AID_SYSTEM");
+        addAtomEvent(builder, Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER);
+        return builder;
+    }
+}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
new file mode 100644
index 0000000..5cb37d3
--- /dev/null
+++ b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
@@ -0,0 +1,103 @@
+/*
+ * 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 android.cts.statsd.metadata;
+
+import android.cts.statsd.atom.AtomTestCase;
+
+import com.android.internal.os.StatsdConfigProto;
+import com.android.internal.os.StatsdConfigProto.StatsdConfig;
+import com.android.internal.os.StatsdConfigProto.Subscription;
+import com.android.internal.os.StatsdConfigProto.TimeUnit;
+import com.android.internal.os.StatsdConfigProto.ValueMetric;
+import com.android.os.AtomsProto.AnomalyDetected;
+import com.android.os.AtomsProto.AppBreadcrumbReported;
+import com.android.os.AtomsProto.Atom;
+import com.android.os.StatsLog.EventMetricData;
+import com.android.os.StatsLog.StatsdStatsReport;
+import com.android.os.StatsLog.StatsdStatsReport.ConfigStats;
+import com.android.tradefed.log.LogUtil;
+
+
+import java.util.List;
+
+/**
+ * Statsd Anomaly Detection tests.
+ */
+public class MetadataTests extends MetadataTestCase {
+
+    private static final String TAG = "Statsd.MetadataTests";
+
+    // Tests that anomaly detection for value works.
+    public void testConfigTtl() throws Exception {
+        final int TTL_TIME_SEC = 3;
+        StatsdConfig.Builder config = getBaseConfig();
+        config.setTtlInSeconds(TTL_TIME_SEC); // should reset in 3 seconds.
+        turnScreenOff();
+
+        uploadConfig(config);
+        Thread.sleep(WAIT_TIME_SHORT);
+        turnScreenOn();
+        Thread.sleep(WAIT_TIME_SHORT);
+        StatsdStatsReport report = getStatsdStatsReport(); // Has only been 1 second
+        LogUtil.CLog.d("got following statsdstats report: " + report.toString());
+        boolean foundActiveConfig = false;
+        int creationTime = 0;
+        for (ConfigStats stats: report.getConfigStatsList()) {
+            if (stats.getId() == CONFIG_ID) {
+                if(!stats.hasDeletionTimeSec()) {
+                    assertTrue("Found multiple active CTS configs!", foundActiveConfig == false);
+                    foundActiveConfig = true;
+                    creationTime = stats.getCreationTimeSec();
+                }
+            }
+        }
+        assertTrue("Did not find an active CTS config", foundActiveConfig);
+
+        turnScreenOff();
+        Thread.sleep(WAIT_TIME_LONG); // Has been 3 seconds, config should TTL
+        turnScreenOn(); // Force events to make sure the config TTLs.
+        report = getStatsdStatsReport();
+        LogUtil.CLog.d("got following statsdstats report: " + report.toString());
+        foundActiveConfig = false;
+        int expectedTime = creationTime + TTL_TIME_SEC;
+        for (ConfigStats stats: report.getConfigStatsList()) {
+            if (stats.getId() == CONFIG_ID) {
+                // Original config should be TTL'd
+                if (stats.getCreationTimeSec() == creationTime) {
+                    assertTrue("Config should have TTL'd but is still active",
+                            stats.hasDeletionTimeSec());
+                    assertTrue("Config deletion time should be about " + TTL_TIME_SEC +
+                            " after creation",
+                            Math.abs(stats.getDeletionTimeSec() - expectedTime) <= 1);
+                }
+                // There should still be one active config, that is marked as reset.
+                if(!stats.hasDeletionTimeSec()) {
+                    assertTrue("Found multiple active CTS configs!", foundActiveConfig == false);
+                    foundActiveConfig = true;
+                    creationTime = stats.getCreationTimeSec();
+                    assertTrue("Active config after TTL should be marked as reset",
+                            stats.hasResetTimeSec());
+                    assertEquals("Reset time and creation time should be equal for TTl'd configs",
+                            stats.getResetTimeSec(), stats.getCreationTimeSec());
+                    assertTrue("Reset config should be created when the original config TTL'd",
+                            Math.abs(stats.getCreationTimeSec() - expectedTime) <= 1);
+                }
+            }
+        }
+        assertTrue("Did not find an active CTS config after the TTL", foundActiveConfig);
+        turnScreenOff();
+    }
+}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java b/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
index 39ad762..d8d6339 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/metric/CountMetricsTests.java
@@ -21,8 +21,13 @@
 import com.android.os.AtomsProto.Atom;
 import com.android.os.AtomsProto.AppBreadcrumbReported;
 import com.android.os.StatsLog;
+import com.android.os.StatsLog.ConfigMetricsReport;
+import com.android.os.StatsLog.ConfigMetricsReportList;
+import com.android.os.StatsLog.CountBucketInfo;
+import com.android.os.StatsLog.CountMetricData;
 import com.android.os.StatsLog.StatsLogReport;
 import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil;
 
 import java.util.Arrays;
 import java.util.List;
@@ -53,7 +58,6 @@
         assertTrue(countData.getDataCount() > 0);
         assertEquals(2, countData.getData(0).getBucketInfo(0).getCount());
     }
-
     public void testEventCountWithCondition() throws Exception {
         int startMatcherId = 1;
         int endMatcherId = 2;
@@ -110,4 +114,60 @@
         assertTrue(countData.getDataCount() > 0);
         assertEquals(1, countData.getData(0).getBucketInfo(0).getCount());
     }
+
+    public void testPartialBucketCountMetric() throws Exception {
+        int matcherId = 1;
+        StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder();
+        builder.addCountMetric(StatsdConfigProto.CountMetric.newBuilder()
+                .setId(MetricsUtils.COUNT_METRIC_ID)
+                .setBucket(StatsdConfigProto.TimeUnit.ONE_DAY)  // Should ensure partial bucket.
+                .setWhat(matcherId))
+                .addAtomMatcher(MetricsUtils.simpleAtomMatcher(matcherId));
+        uploadConfig(builder);
+
+        doAppBreadcrumbReportedStart(0);
+
+        builder.getCountMetricBuilder(0).setBucket(StatsdConfigProto.TimeUnit.CTS);
+        uploadConfig(builder);  // The count metric had a partial bucket.
+        doAppBreadcrumbReportedStart(0);
+        Thread.sleep(10);
+        doAppBreadcrumbReportedStart(0);
+        Thread.sleep(WAIT_TIME_LONG); // Finish the current bucket.
+
+        ConfigMetricsReportList reports = getReportList();
+        LogUtil.CLog.d("Got following report list: " + reports.toString());
+
+        assertEquals("Expected 2 reports, got " + reports.getReportsCount(),
+                2, reports.getReportsCount());
+        boolean inOrder = reports.getReports(0).getCurrentReportWallClockNanos() <
+                reports.getReports(1).getCurrentReportWallClockNanos();
+
+        // Only 1 metric, so there should only be 1 StatsLogReport.
+        for (ConfigMetricsReport report : reports.getReportsList()) {
+            assertEquals("Expected 1 StatsLogReport in each ConfigMetricsReport",
+                    1, report.getMetricsCount());
+            assertEquals("Expected 1 CountMetricData in each report",
+                    1, report.getMetrics(0).getCountMetrics().getDataCount());
+        }
+        CountMetricData data1 =
+                reports.getReports(inOrder? 0 : 1).getMetrics(0).getCountMetrics().getData(0);
+        CountMetricData data2 =
+                reports.getReports(inOrder? 1 : 0).getMetrics(0).getCountMetrics().getData(0);
+        // Data1 should have only 1 bucket, and it should be a partial bucket.
+        // The count should be 1.
+        assertEquals("First report should only have 1 bucket", 1, data1.getBucketInfoCount());
+        CountBucketInfo bucketInfo = data1.getBucketInfo(0);
+        assertEquals("First report should have a count of 1", 1, bucketInfo.getCount());
+        assertTrue("First report's bucket should be less than 1 day",
+                bucketInfo.getEndBucketElapsedNanos() <
+                (bucketInfo.getStartBucketElapsedNanos() + 1_000_000_000L * 60L * 60L * 24L));
+
+        //Second report should have a count of 2.
+        assertTrue("Second report should have at most 2 buckets", data2.getBucketInfoCount() < 3);
+        int totalCount = 0;
+        for (CountBucketInfo bucket : data2.getBucketInfoList()) {
+            totalCount += bucket.getCount();
+        }
+        assertEquals("Second report should have a count of 2", 2, totalCount);
+    }
 }
diff --git a/tests/app/src/android/app/cts/NotificationTest.java b/tests/app/src/android/app/cts/NotificationTest.java
index 03ceb65..e2746c5 100644
--- a/tests/app/src/android/app/cts/NotificationTest.java
+++ b/tests/app/src/android/app/cts/NotificationTest.java
@@ -22,6 +22,7 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.Person;
 import android.app.RemoteInput;
 import android.app.stubs.R;
 import android.content.Context;
@@ -266,21 +267,22 @@
         String name = "name";
         String key = "key";
         String uri = "name:name";
-        Notification.Person person = new Notification.Person()
+        Person person = new Person.Builder()
                 .setName(name)
                 .setIcon(Icon.createWithResource(mContext, 1))
                 .setKey(key)
-                .setUri(uri);
+                .setUri(uri)
+                .build();
         mNotification = new Notification.Builder(mContext, CHANNEL.getId())
                 .setSmallIcon(1)
                 .setContentTitle(CONTENT_TITLE)
                 .addPerson(person)
                 .build();
 
-        ArrayList<Notification.Person> restoredPeople = mNotification.extras.getParcelableArrayList(
+        ArrayList<Person> restoredPeople = mNotification.extras.getParcelableArrayList(
                 Notification.EXTRA_PEOPLE_LIST);
         assertNotNull(restoredPeople);
-        Notification.Person restoredPerson = restoredPeople.get(0);
+        Person restoredPerson = restoredPeople.get(0);
         assertNotNull(restoredPerson);
         assertNotNull(restoredPerson.getIcon());
         assertEquals(name, restoredPerson.getName());
@@ -292,12 +294,13 @@
         String name = "name";
         String key = "key";
         String uri = "name:name";
-        Notification.Person user = new Notification.Person()
+        Person user = new Person.Builder()
                 .setName(name)
                 .setIcon(Icon.createWithResource(mContext, 1))
                 .setKey(key)
-                .setUri(uri);
-        Notification.Person participant = new Notification.Person().setName("sender");
+                .setUri(uri)
+                .build();
+        Person participant = new Person.Builder().setName("sender").build();
         Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle(user)
                 .addMessage("text", 0, participant)
                 .addMessage(new Message("text 2", 0, participant));
@@ -306,7 +309,7 @@
                 .setStyle(messagingStyle)
                 .build();
 
-        Notification.Person restoredPerson = mNotification.extras.getParcelable(
+        Person restoredPerson = mNotification.extras.getParcelable(
                 Notification.EXTRA_MESSAGING_PERSON);
         assertNotNull(restoredPerson);
         assertNotNull(restoredPerson.getIcon());
@@ -467,39 +470,6 @@
                 action.clone().getSemanticAction());
     }
 
-    public void testPerson_constructor() {
-        Notification.Person person = new Notification.Person();
-        assertFalse(person.isBot());
-        assertFalse(person.isImportant());
-        assertNull(person.getIcon());
-        assertNull(person.getKey());
-        assertNull(person.getName());
-        assertNull(person.getUri());
-    }
-
-    public void testPerson_parcelable() {
-        Notification.Person person = new Notification.Person()
-                .setBot(true)
-                .setImportant(true)
-                .setIcon(Icon.createWithResource(mContext, R.drawable.icon_blue))
-                .setKey("key")
-                .setName("Name")
-                .setUri(Uri.fromParts("a", "b", "c").toString());
-
-        Parcel parcel = Parcel.obtain();
-        person.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        Notification.Person result = Notification.Person.CREATOR.createFromParcel(parcel);
-
-        assertEquals(person.isBot(), result.isBot());
-        assertEquals(person.isImportant(), result.isImportant());
-        assertEquals(person.getIcon().getResId(), result.getIcon().getResId());
-        assertEquals(person.getKey(), result.getKey());
-        assertEquals(person.getName(), result.getName());
-        assertEquals(person.getUri(), result.getUri());
-    }
-
-
     private static RemoteInput newDataOnlyRemoteInput() {
         return new RemoteInput.Builder(DATA_RESULT_KEY)
             .setAllowFreeFormInput(false)
diff --git a/tests/app/src/android/app/cts/PersonTest.java b/tests/app/src/android/app/cts/PersonTest.java
new file mode 100644
index 0000000..a5869e6
--- /dev/null
+++ b/tests/app/src/android/app/cts/PersonTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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 android.app.cts;
+
+import android.app.Person;
+import android.app.stubs.R;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+
+public class PersonTest extends AndroidTestCase {
+
+    public void testPerson_defaults() {
+        Person person = new Person.Builder().build();
+        assertFalse(person.isBot());
+        assertFalse(person.isImportant());
+        assertNull(person.getIcon());
+        assertNull(person.getKey());
+        assertNull(person.getName());
+        assertNull(person.getUri());
+    }
+
+    public void testPerson_parcelable() {
+        Person person = new Person.Builder()
+                .setBot(true)
+                .setImportant(true)
+                .setIcon(Icon.createWithResource(getContext(), R.drawable.icon_blue))
+                .setKey("key")
+                .setName("Name")
+                .setUri(Uri.fromParts("a", "b", "c").toString())
+                .build();
+
+        Parcel parcel = Parcel.obtain();
+        person.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        Person result = Person.CREATOR.createFromParcel(parcel);
+
+        assertEquals(person.isBot(), result.isBot());
+        assertEquals(person.isImportant(), result.isImportant());
+        assertEquals(person.getIcon().getResId(), result.getIcon().getResId());
+        assertEquals(person.getKey(), result.getKey());
+        assertEquals(person.getName(), result.getName());
+        assertEquals(person.getUri(), result.getUri());
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
index 68b8482..3e552da 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
@@ -186,6 +186,7 @@
 
         // Fill in some stuff
         mActivity.mUsername.setText("foo");
+        focusToPasswordExpectNoWindowEvent();
         mActivity.mPassword.setText("bar");
 
         // Change URL bar before views become invisible
@@ -243,6 +244,7 @@
 
         // Fill in some stuff
         mActivity.mUsername.setText("foo");
+        focusToPasswordExpectNoWindowEvent();
         mActivity.mPassword.setText("bar");
 
         // Change URL bar before views become invisible
@@ -273,6 +275,7 @@
 
         // Fill in some stuff
         mActivity.mUsername.setText("foo");
+        focusToPasswordExpectNoWindowEvent();
         mActivity.mPassword.setText("bar");
 
         // Change URL bar before views become invisible
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
index d04d8a8..88acbda 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
@@ -147,6 +147,14 @@
     }
 
     /**
+     * Focus to password and expect no autofill window event
+     */
+    void focusToPasswordExpectNoWindowEvent() throws Throwable {
+        // TODO should use waitForWindowChange() if we can filter out event of app Activity itself.
+        mActivityRule.runOnUiThread(() -> mActivity.mPassword.changeFocus(true));
+    }
+
+    /**
      * Tests autofilling the virtual views, using the sync / async version of ViewStructure.addChild
      */
     private void autofillTest(boolean sync) throws Exception {
@@ -535,6 +543,7 @@
 
         // Fill in some stuff
         mActivity.mUsername.setText("foo");
+        focusToPasswordExpectNoWindowEvent();
         mActivity.mPassword.setText("bar");
 
         // Trigger save.
@@ -714,7 +723,7 @@
     }
 
     @Test
-    public void testDatasetFiltering() throws Exception {
+    public void testDatasetFiltering() throws Throwable {
         final String aa = "Two A's";
         final String ab = "A and B";
         final String b = "Only B";
@@ -738,7 +747,7 @@
                 .build());
 
         // Trigger auto-fill.
-        focusToUsername();
+        focusToUsernameExpectNoWindowEvent();
         sReplier.getNextFillRequest();
 
         // With no filter text all datasets should be shown
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java
index 4788d35..bce6bff 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java
@@ -508,9 +508,13 @@
             text.text = value;
             final AutofillManager autofillManager =
                     getContext().getSystemService(AutofillManager.class);
-            if (autofillManager != null) {
-                autofillManager.notifyValueChanged(VirtualContainerView.this, text.id,
-                        AutofillValue.forText(text.text));
+            if (mCompatMode) {
+                sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED, text.id);
+            } else {
+                if (autofillManager != null) {
+                    autofillManager.notifyValueChanged(VirtualContainerView.this, text.id,
+                            AutofillValue.forText(text.text));
+                }
             }
             invalidate();
         }
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
index 6b989bc..84071fc 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -2330,6 +2330,15 @@
                 collector.expectInRange("Exif TAG_ISO is incorrect", iso,
                         expectedIso/100, (expectedIso+50)/100);
             }
+        } else {
+            // External camera specific checks
+            // TAG_MAKE
+            String make = exif.getAttribute(ExifInterface.TAG_MAKE);
+            collector.expectNotNull("Exif TAG_MAKE is null", make);
+
+            // TAG_MODEL
+            String model = exif.getAttribute(ExifInterface.TAG_MODEL);
+            collector.expectNotNull("Exif TAG_MODEL is nuill", model);
         }
 
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
index 23eb28c..f43ec64 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
@@ -61,9 +61,10 @@
 import android.content.ComponentName;
 import android.platform.test.annotations.Presubmit;
 import android.server.am.ActivityManagerState.ActivityDisplay;
-import androidx.annotation.Nullable;
 import android.support.test.filters.FlakyTest;
 
+import androidx.annotation.Nullable;
+
 import org.junit.Before;
 import org.junit.Test;
 
@@ -75,6 +76,8 @@
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:ActivityManagerMultiDisplayTests
  */
+@Presubmit
+@FlakyTest(bugId = 77652261)
 public class ActivityManagerMultiDisplayTests extends ActivityManagerDisplayTestBase {
 
     // TODO(b/70247058): Use {@link Context#sendBroadcast(Intent).
@@ -97,8 +100,6 @@
     /**
      * Tests launching an activity on virtual display.
      */
-    @Presubmit
-    @FlakyTest(bugId = 77270929)
     @Test
     public void testLaunchActivityOnSecondaryDisplay() throws Exception {
         try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
@@ -418,8 +419,6 @@
      * command and without specifying the display id - the second activity must appear on the
      * primary display.
      */
-    @Presubmit
-    @FlakyTest(bugId = 77469851)
     @Test
     public void testConsequentLaunchActivity() throws Exception {
         try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
@@ -455,7 +454,6 @@
      * Tests launching an activity on simulated display and then launching another activity from the
      * first one - it must appear on the secondary display, because it was launched from there.
      */
-    @Presubmit
     @Test
     public void testConsequentLaunchActivityFromSecondaryDisplay() throws Exception {
         try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
@@ -634,7 +632,6 @@
      * Tests launching activities on secondary and then on primary display to see if the stack
      * visibility is not affected.
      */
-    @Presubmit
     @Test
     public void testLaunchActivitiesAffectsVisibility() throws Exception {
         // Start launching activity.
@@ -662,7 +659,6 @@
     /**
      * Test that move-task works when moving between displays.
      */
-    @Presubmit
     @Test
     public void testMoveTaskBetweenDisplays() throws Exception {
         try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
@@ -702,8 +698,6 @@
      * is moved correctly.
      * This version launches virtual display creator to fullscreen stack in split-screen.
      */
-    @Presubmit
-    @FlakyTest(bugId = 77207453)
     @Test
     public void testStackFocusSwitchOnDisplayRemoved() throws Exception {
         assumeTrue(supportsSplitScreenMultiWindow());
@@ -1107,7 +1101,6 @@
     /**
      * Test that all activities that were on the private display are destroyed on display removal.
      */
-    @Presubmit
     @Test
     public void testContentDestroyOnDisplayRemoved() throws Exception {
         LogSeparator logSeparator;
@@ -1157,7 +1150,6 @@
     /**
      * Test that the update of display metrics updates all its content.
      */
-    @Presubmit
     @Test
     public void testDisplayResize() throws Exception {
         try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
index 380449c..7f7d697 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
@@ -43,6 +43,7 @@
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 @Presubmit
+@FlakyTest(bugId = 77652261)
 public class ActivityLifecycleTests extends ActivityLifecycleClientTestBase {
 
     @Test
@@ -121,7 +122,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 77565927)
     public void testRelaunchConfigurationChangedWhileBecomingVisible() throws Exception {
         final Activity becomingVisibleActivity =
                 mFirstActivityTestRule.launchActivity(new Intent());
@@ -226,7 +226,6 @@
         LifecycleVerifier.assertRestartAndPauseSequence(FirstActivity.class, getLifecycleLog());
     }
 
-    @FlakyTest(bugId = 74409828)
     @Test
     public void testPausedWhenRecreatedFromInNonFocusedStack() throws Exception {
         // Launch first activity
@@ -435,7 +434,6 @@
     /**
      * The that recreate request from an activity is executed immediately.
      */
-    @FlakyTest(bugId = 77565927)
     @Test
     public void testLocalRecreate() throws Exception {
         // Launch the activity that will recreate itself
@@ -464,7 +462,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 65236456)
     public void testOnNewIntent() throws Exception {
         // Launch a singleTop activity
         final Activity singleTopActivity =
@@ -491,7 +488,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 65236456)
     public void testOnNewIntentFromHidden() throws Exception {
         // Launch a singleTop activity
         final Activity singleTopActivity =
@@ -528,7 +524,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 65236456)
     public void testOnNewIntentFromPaused() throws Exception {
         // Launch a singleTop activity
         final Activity singleTopActivity =
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index 6e9eb1b..d7f2b32 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -27,6 +27,7 @@
 import android.media.AudioTrack;
 import android.media.PlaybackParams;
 import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.LargeTest;
 import android.util.Log;
 
 import com.android.compatibility.common.util.CtsAndroidTestCase;
@@ -2263,6 +2264,67 @@
         track.release();
     }
 
+    // Test that AudioTrack stop limits drain to only those frames written at the time of stop.
+    // This ensures consistent stop behavior on Android P and beyond, where data written
+    // immediately after a stop doesn't get caught in the drain.
+    @LargeTest
+    public void testStopDrain() throws Exception {
+        final String TEST_NAME = "testStopDrain";
+        final int TEST_SR = 8000;
+        final int TEST_CONF = AudioFormat.CHANNEL_OUT_MONO; // required for test
+        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT; // required for test
+        final int TEST_MODE = AudioTrack.MODE_STREAM; // required for test
+        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
+
+        final int channelCount = AudioFormat.channelCountFromOutChannelMask(TEST_CONF);
+        final int bytesPerSample = AudioFormat.getBytesPerSample(TEST_FORMAT);
+        final int bytesPerFrame = channelCount * bytesPerSample;
+        final int frameCount = TEST_SR * 3; // 3 seconds of buffer.
+        final int bufferSizeInBytes = frameCount * bytesPerFrame;
+
+        final AudioTrack track = new AudioTrack(
+                TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT, bufferSizeInBytes, TEST_MODE);
+
+        try {
+            // Create 6 seconds of data, but send down only 3 seconds to fill buffer.
+            final byte[] soundData = AudioHelper.createSoundDataInByteArray(
+                    bufferSizeInBytes * 2, TEST_SR, 600 /* frequency */, 0 /* sweep */);
+            assertEquals("cannot fill AudioTrack buffer",
+                    bufferSizeInBytes,
+                    track.write(soundData, 0 /* offsetInBytes */, bufferSizeInBytes));
+
+            // Set the track playing.
+            track.play();
+
+            // Note that the timings here are very generous for our test (really the
+            // granularity we need is on the order of a second).  If we don't get scheduled
+            // to run within about a second or so - this should be extremely rare -
+            // the result should be a false pass (rather than a false fail).
+
+            // After 1.5 seconds stop.
+            Thread.sleep(1500 /* millis */); // Assume device starts within 1.5 sec.
+            track.stop();
+
+            // We should drain 1.5 seconds and fill another 3 seconds of data.
+            // We shouldn't be able to write 6 seconds of data - that indicates stop continues
+            // to drain beyond the frames written at the time of stop.
+            int length = 0;
+            while (length < soundData.length) {
+                Thread.sleep(800 /* millis */); // assume larger than AF thread loop period
+                final int delta = track.write(soundData, length, soundData.length - length);
+                assertTrue("track write error: " + delta, delta >= 0);
+                if (delta == 0) break;
+                length += delta;
+            }
+
+            // Check to see we limit the data drained (should be able to exactly fill the buffer).
+            assertEquals("stop drain must be limited " + bufferSizeInBytes + " != " + length,
+                    bufferSizeInBytes, length);
+        } finally {
+            track.release();
+        }
+    }
+
     public void testVariableSpeedPlayback() throws Exception {
         if (!hasAudioOutput()) {
             Log.w(TAG,"AUDIO_OUTPUT feature not found. This system might not have a valid "
diff --git a/tests/tests/media/src/android/media/cts/VolumeShaperTest.java b/tests/tests/media/src/android/media/cts/VolumeShaperTest.java
index 30f07e2..d7bd9de 100644
--- a/tests/tests/media/src/android/media/cts/VolumeShaperTest.java
+++ b/tests/tests/media/src/android/media/cts/VolumeShaperTest.java
@@ -25,10 +25,9 @@
 import android.content.pm.PackageManager;
 import android.media.AudioAttributes;
 import android.media.AudioFormat;
-import android.media.AudioSystem;
+import android.media.AudioManager;
 import android.media.AudioTrack;
 import android.media.MediaPlayer;
-import android.media.PlaybackParams;
 import android.media.VolumeShaper;
 import android.os.Parcel;
 import android.os.PowerManager;
@@ -204,7 +203,7 @@
                             AudioAttributes.USAGE_MEDIA  // offload allowed
                             : AudioAttributes.USAGE_NOTIFICATION) // offload not allowed
                     .build(),
-                AudioSystem.newAudioSessionId());
+                new AudioManager(getContext()).generateAudioSessionId());
         mediaPlayer.setWakeMode(getContext(), PowerManager.PARTIAL_WAKE_LOCK);
         mediaPlayer.setLooping(true);
         return mediaPlayer;
diff --git a/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java
index 20f971f..3a474c8 100644
--- a/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java
@@ -40,8 +40,9 @@
 
 public class SelfManagedConnectionServiceTest extends BaseTelecomTestWithMockServices {
     private Uri TEST_ADDRESS_1 = Uri.fromParts("sip", "call1@test.com", null);
-    private Uri TEST_ADDRESS_2 = Uri.fromParts("tel", "650-555-1212", null);
-    private Uri TEST_ADDRESS_3 = Uri.fromParts("tel", "650-555-1213", null);
+    private Uri TEST_ADDRESS_2 = Uri.fromParts("tel", "6505551212", null);
+    private Uri TEST_ADDRESS_3 = Uri.fromParts("tel", "6505551213", null);
+    private Uri TEST_ADDRESS_4 = Uri.fromParts(TestUtils.TEST_URI_SCHEME, "fizzle_schmozle", null);
 
     @Override
     protected void setUp() throws Exception {
@@ -54,6 +55,7 @@
 
             mTelecomManager.registerPhoneAccount(TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1);
             mTelecomManager.registerPhoneAccount(TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_2);
+            mTelecomManager.registerPhoneAccount(TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_3);
         }
     }
 
@@ -67,6 +69,7 @@
             connectionService.tearDown();
             mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_SELF_MANAGED_HANDLE_1);
             mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_SELF_MANAGED_HANDLE_2);
+            mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_SELF_MANAGED_HANDLE_3);
         }
     }
 
@@ -84,44 +87,46 @@
 
         assertTrue(phoneAccountHandles.contains(TestUtils.TEST_SELF_MANAGED_HANDLE_1));
         assertTrue(phoneAccountHandles.contains(TestUtils.TEST_SELF_MANAGED_HANDLE_2));
+        assertTrue(phoneAccountHandles.contains(TestUtils.TEST_SELF_MANAGED_HANDLE_3));
         assertFalse(phoneAccountHandles.contains(TestUtils.TEST_PHONE_ACCOUNT_HANDLE));
     }
 
     /**
      * Tests the ability to successfully register a self-managed
      * {@link android.telecom.PhoneAccount}.
+     * <p>
+     * It should be possible to register self-managed Connection Services which suppor the TEL, SIP,
+     * or other URI schemes.
      */
     public void testRegisterSelfManagedConnectionService() {
         if (!mShouldTestTelecom) {
             return;
         }
+        verifyAccountRegistration(TestUtils.TEST_SELF_MANAGED_HANDLE_1,
+                TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1);
+        verifyAccountRegistration(TestUtils.TEST_SELF_MANAGED_HANDLE_2,
+                TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_2);
+        verifyAccountRegistration(TestUtils.TEST_SELF_MANAGED_HANDLE_3,
+                TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_3);
+    }
 
+    private void verifyAccountRegistration(PhoneAccountHandle handle, PhoneAccount phoneAccount) {
         // The phone account is registered in the setup method.
-        assertPhoneAccountRegistered(TestUtils.TEST_SELF_MANAGED_HANDLE_1);
-        assertPhoneAccountEnabled(TestUtils.TEST_SELF_MANAGED_HANDLE_1);
-        PhoneAccount registeredAccount = mTelecomManager.getPhoneAccount(
-                TestUtils.TEST_SELF_MANAGED_HANDLE_1);
-
-        assertPhoneAccountRegistered(TestUtils.TEST_SELF_MANAGED_HANDLE_2);
-        assertPhoneAccountEnabled(TestUtils.TEST_SELF_MANAGED_HANDLE_2);
-        PhoneAccount registeredAccount2 = mTelecomManager.getPhoneAccount(
-                TestUtils.TEST_SELF_MANAGED_HANDLE_2);
+        assertPhoneAccountRegistered(handle);
+        assertPhoneAccountEnabled(handle);
+        PhoneAccount registeredAccount = mTelecomManager.getPhoneAccount(handle);
 
         // It should exist and be the same as the previously registered one.
         assertNotNull(registeredAccount);
-        assertNotNull(registeredAccount2);
 
         // We cannot just check for equality of the PhoneAccount since the one we registered is not
         // enabled, and the one we get back after registration is.
-        assertPhoneAccountEquals(TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1, registeredAccount);
-        assertPhoneAccountEquals(TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_2, registeredAccount2);
+        assertPhoneAccountEquals(phoneAccount, registeredAccount);
 
         // An important assumption is that self-managed PhoneAccounts are automatically
         // enabled by default.
         assertTrue("Self-managed PhoneAccounts must be enabled by default.",
                 registeredAccount.isEnabled());
-        assertTrue("Self-managed PhoneAccounts must be enabled by default.",
-                registeredAccount2.isEnabled());
     }
 
     /**
@@ -211,6 +216,7 @@
 
         addAndVerifyIncomingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
         addAndVerifyIncomingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_2, TEST_ADDRESS_3);
+        addAndVerifyIncomingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_3, TEST_ADDRESS_4);
     }
 
     private void addAndVerifyIncomingCall(PhoneAccountHandle handle, Uri address)
@@ -230,6 +236,7 @@
 
         // Expect there to be no managed calls at the moment.
         assertFalse(mTelecomManager.isInManagedCall());
+        assertTrue(mTelecomManager.isInCall());
 
         setDisconnectedAndVerify(connection);
     }
@@ -272,6 +279,8 @@
             return;
         }
         placeAndVerifyOutgoingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_1, TEST_ADDRESS_1);
+        placeAndVerifyOutgoingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_2, TEST_ADDRESS_3);
+        placeAndVerifyOutgoingCall(TestUtils.TEST_SELF_MANAGED_HANDLE_3, TEST_ADDRESS_4);
     }
 
     private void placeAndVerifyOutgoingCall(PhoneAccountHandle handle, Uri address) throws Exception {
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index 31000de..36303b6 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -77,6 +77,10 @@
     public static final PhoneAccountHandle TEST_SELF_MANAGED_HANDLE_2 =
             new PhoneAccountHandle(new ComponentName(PACKAGE, SELF_MANAGED_COMPONENT),
                     SELF_MANAGED_ACCOUNT_ID_2);
+    public static final String SELF_MANAGED_ACCOUNT_ID_3 = "ctstest_SELF_MANAGED_ID_3";
+    public static final PhoneAccountHandle TEST_SELF_MANAGED_HANDLE_3 =
+            new PhoneAccountHandle(new ComponentName(PACKAGE, SELF_MANAGED_COMPONENT),
+                    SELF_MANAGED_ACCOUNT_ID_3);
 
     public static final String ACCOUNT_LABEL = "CTSConnectionService";
     public static final PhoneAccount TEST_PHONE_ACCOUNT = PhoneAccount.builder(
@@ -122,6 +126,18 @@
             .build();
     public static final String REMOTE_ACCOUNT_LABEL = "CTSRemoteConnectionService";
     public static final String SELF_MANAGED_ACCOUNT_LABEL = "android.telecom.cts";
+    public static final String TEST_URI_SCHEME = "foobuzz";
+    public static final PhoneAccount TEST_SELF_MANAGED_PHONE_ACCOUNT_3 = PhoneAccount.builder(
+            TEST_SELF_MANAGED_HANDLE_3, SELF_MANAGED_ACCOUNT_LABEL)
+            .setAddress(Uri.fromParts(TEST_URI_SCHEME, "test@test.com", null))
+            .setSubscriptionAddress(Uri.fromParts(TEST_URI_SCHEME, "test@test.com", null))
+            .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED |
+                    PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING |
+                    PhoneAccount.CAPABILITY_VIDEO_CALLING)
+            .setHighlightColor(Color.BLUE)
+            .setShortDescription(SELF_MANAGED_ACCOUNT_LABEL)
+            .addSupportedUriScheme(TEST_URI_SCHEME)
+            .build();
     public static final PhoneAccount TEST_SELF_MANAGED_PHONE_ACCOUNT_2 = PhoneAccount.builder(
             TEST_SELF_MANAGED_HANDLE_2, SELF_MANAGED_ACCOUNT_LABEL)
             .setAddress(Uri.parse("sip:test@test.com"))
diff --git a/tests/tests/telephony/Android.mk b/tests/tests/telephony/Android.mk
index f19dbb5..6f3d71a 100644
--- a/tests/tests/telephony/Android.mk
+++ b/tests/tests/telephony/Android.mk
@@ -26,7 +26,8 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     ctstestrunner \
-    compatibility-device-util
+    compatibility-device-util \
+    truth-prebuilt
 
 LOCAL_HOST_SHARED_LIBRARIES := compatibility-device-telephony-preconditions
 
diff --git a/tests/tests/telephony/AndroidTest.xml b/tests/tests/telephony/AndroidTest.xml
index a696dfc..43486b8 100644
--- a/tests/tests/telephony/AndroidTest.xml
+++ b/tests/tests/telephony/AndroidTest.xml
@@ -30,6 +30,7 @@
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.telephony.cts" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="run-command" value="pm disable com.google.android.dialer/com.android.voicemail.impl.StatusCheckJobService" />
diff --git a/tests/tests/telephony/src/android/telephony/cts/RadioAccessSpecifierTest.java b/tests/tests/telephony/src/android/telephony/cts/RadioAccessSpecifierTest.java
new file mode 100644
index 0000000..693472f
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/RadioAccessSpecifierTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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 android.telephony.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.telephony.RadioAccessSpecifier;
+import android.test.AndroidTestCase;
+
+public class RadioAccessSpecifierTest extends AndroidTestCase {
+    public void testConstructorAndGetters() {
+        // Constructor and getters.
+        int ran = 1;
+        int[] bands = {1, 2, 3, 4};
+        int[] channels = {5, 6, 7};
+        RadioAccessSpecifier radioAccessSpecifier = new RadioAccessSpecifier(ran, bands, channels);
+        assertThat(radioAccessSpecifier.describeContents()).isEqualTo(0);
+        assertThat(radioAccessSpecifier.getRadioAccessNetwork()).isEqualTo(ran);
+        assertThat(radioAccessSpecifier.getBands()).isEqualTo(bands);
+        assertThat(radioAccessSpecifier.getChannels()).isEqualTo(channels);
+
+        // Comparision method.
+        RadioAccessSpecifier toCompare1 = new RadioAccessSpecifier(ran, bands, channels);
+        RadioAccessSpecifier toCompare2 = new RadioAccessSpecifier(ran, new int[] {1, 2, 3, 4},
+                new int[] {5, 6, 7});
+        RadioAccessSpecifier toCompare3 = new RadioAccessSpecifier(ran+1, bands, channels);
+        assertThat(radioAccessSpecifier).isEqualTo(toCompare1);
+        assertThat(radioAccessSpecifier).isEqualTo(toCompare2);
+        assertThat(radioAccessSpecifier).isNotEqualTo(toCompare3);
+
+        // Parcel read and write.
+        Parcel stateParcel = Parcel.obtain();
+        radioAccessSpecifier.writeToParcel(stateParcel, 0);
+        stateParcel.setDataPosition(0);
+        toCompare1 = RadioAccessSpecifier.CREATOR.createFromParcel(stateParcel);
+        assertThat(radioAccessSpecifier).isEqualTo(toCompare1);
+
+        // Other methods.
+        assertThat(radioAccessSpecifier.hashCode()).isGreaterThan(0);
+        assertThat(radioAccessSpecifier.toString()).isNotNull();
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/ServiceStateTest.java b/tests/tests/telephony/src/android/telephony/cts/ServiceStateTest.java
index ce9d72e..47f1429 100644
--- a/tests/tests/telephony/src/android/telephony/cts/ServiceStateTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/ServiceStateTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -15,7 +15,12 @@
  */
 package android.telephony.cts;
 
+import static android.telephony.ServiceState.DUPLEX_MODE_FDD;
+import static android.telephony.ServiceState.DUPLEX_MODE_TDD;
+import static android.telephony.ServiceState.DUPLEX_MODE_UNKNOWN;
+
 import android.os.Parcel;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.ServiceState;
 import android.test.AndroidTestCase;
 
@@ -25,6 +30,9 @@
     private static final String OPERATOR_NUMERIC = "02871";
     private static final int SYSTEM_ID = 123;
     private static final int NETWORK_ID = 456;
+    private static final int CHANNEL_NUMBER_BAND_66 = 66436;
+    private static final int CHANNEL_NUMBER_BAND_33 = 36000;
+    private static final int[] CELL_BANDWIDTH = {1, 2, 3};
 
     public void testServiceState() {
         ServiceState serviceState = new ServiceState();
@@ -59,6 +67,21 @@
         assertEquals(SYSTEM_ID, serviceState.getCdmaSystemId());
         assertEquals(NETWORK_ID, serviceState.getCdmaNetworkId());
 
+        serviceState.setChannelNumber(CHANNEL_NUMBER_BAND_66);
+        assertEquals(CHANNEL_NUMBER_BAND_66, serviceState.getChannelNumber());
+
+        serviceState.setCellBandwidths(CELL_BANDWIDTH);
+        assertEquals(CELL_BANDWIDTH, serviceState.getCellBandwidths());
+
+        serviceState.setRilDataRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_GSM);
+        assertEquals(DUPLEX_MODE_UNKNOWN, serviceState.getDuplexMode());
+
+        serviceState.setRilDataRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
+        assertEquals(DUPLEX_MODE_FDD, serviceState.getDuplexMode());
+
+        serviceState.setChannelNumber(CHANNEL_NUMBER_BAND_33);
+        assertEquals(DUPLEX_MODE_TDD, serviceState.getDuplexMode());
+
         assertTrue(serviceState.hashCode() > 0);
         assertNotNull(serviceState.toString());