Implement ActivityManager to LMKD reconnect functionality
am: 80bf49d556

Change-Id: Ib17e93917b7217ea15957433c3f5184b48345c2c
diff --git a/api/current.txt b/api/current.txt
index e741629..d2d63af 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -45500,6 +45500,7 @@
     field public static final int TYPE_MCX = 1024; // 0x400
     field public static final int TYPE_MMS = 2; // 0x2
     field public static final int TYPE_SUPL = 4; // 0x4
+    field public static final int TYPE_XCAP = 2048; // 0x800
   }
 
   public static class ApnSetting.Builder {
@@ -46809,7 +46810,7 @@
     field public static final long WEEK_IN_MILLIS = 604800000L; // 0x240c8400L
     field public static final String YEAR_FORMAT = "%Y";
     field public static final String YEAR_FORMAT_TWO_DIGITS = "%g";
-    field public static final long YEAR_IN_MILLIS = 31449600000L; // 0x7528ad000L
+    field @Deprecated public static final long YEAR_IN_MILLIS = 31449600000L; // 0x7528ad000L
     field @Deprecated public static final int[] sameMonthTable;
     field @Deprecated public static final int[] sameYearTable;
   }
@@ -48246,6 +48247,13 @@
     ctor public Base64OutputStream(java.io.OutputStream, int);
   }
 
+  public final class CloseGuard {
+    ctor public CloseGuard();
+    method public void close();
+    method public void open(@NonNull String);
+    method public void warnIfOpen();
+  }
+
   @Deprecated public final class Config {
     field @Deprecated public static final boolean DEBUG = false;
     field @Deprecated public static final boolean LOGD = true;
diff --git a/api/system-current.txt b/api/system-current.txt
index ebfd55e..bf0bfb6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1343,15 +1343,24 @@
 
   public final class BluetoothDevice implements android.os.Parcelable {
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean cancelBondProcess();
+    method public boolean cancelPairing();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getBatteryLevel();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getMessageAccessPermission();
     method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public byte[] getMetadata(int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getPhonebookAccessPermission();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getSimAccessPermission();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isBondingInitiatedLocally();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setAlias(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMessageAccessPermission(int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, @NonNull byte[]);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPin(@Nullable String);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSilenceMode(boolean);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSimAccessPermission(int);
     field public static final int ACCESS_ALLOWED = 1; // 0x1
     field public static final int ACCESS_REJECTED = 2; // 0x2
     field public static final int ACCESS_UNKNOWN = 0; // 0x0
@@ -7912,6 +7921,10 @@
     field public final double lng;
   }
 
+  public class CellBroadcastIntents {
+    method public static void sendOrderedBroadcastForBackgroundReceivers(@NonNull android.content.Context, @Nullable android.os.UserHandle, @NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
+  }
+
   public abstract class CellBroadcastService extends android.app.Service {
     ctor public CellBroadcastService();
     method @CallSuper @NonNull public android.os.IBinder onBind(@Nullable android.content.Intent);
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 49187dc..323c7d1 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.Manifest;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -33,8 +34,12 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.UUID;
 
 /**
@@ -771,6 +776,13 @@
     @UnsupportedAppUsage
     public static final String EXTRA_SDP_SEARCH_STATUS =
             "android.bluetooth.device.extra.SDP_SEARCH_STATUS";
+
+    /** @hide */
+    @IntDef(prefix = "ACCESS_", value = {ACCESS_UNKNOWN,
+            ACCESS_ALLOWED, ACCESS_REJECTED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AccessPermission{}
+
     /**
      * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
      * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
@@ -1096,15 +1108,14 @@
 
     /**
      * Get the most recent identified battery level of this Bluetooth device
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return Battery level in percents from 0 to 100, or {@link #BATTERY_LEVEL_UNKNOWN} if
      * Bluetooth is disabled, or device is disconnected, or does not have any battery reporting
      * service, or return value is invalid
      * @hide
      */
+    @SystemApi
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-    @UnsupportedAppUsage
     public int getBatteryLevel() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1187,8 +1198,15 @@
         return false;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
+    /**
+     * Gets whether bonding was initiated locally
+     *
+     * @return true if bonding is initiated locally, false otherwise
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public boolean isBondingInitiatedLocally() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1480,15 +1498,20 @@
         return false;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public boolean setPasskey(int passkey) {
-        //TODO(BT)
-        /*
-        try {
-            return sService.setPasskey(this, true, 4, passkey);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}*/
-        return false;
+    /**
+     * Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
+     *
+     * @return true pin has been set false for error
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    public boolean setPin(@Nullable String pin) {
+        byte[] pinBytes = convertPinToBytes(pin);
+        if (pinBytes == null) {
+            return false;
+        }
+        return setPin(pinBytes);
     }
 
     /**
@@ -1511,22 +1534,18 @@
         return false;
     }
 
-    /** @hide */
-    public boolean setRemoteOutOfBandData() {
-        // TODO(BT)
-        /*
-        try {
-          return sService.setRemoteOutOfBandData(this);
-      } catch (RemoteException e) {Log.e(TAG, "", e);}*/
-        return false;
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public boolean cancelPairingUserInput() {
+    /**
+     * Cancels pairing to this device
+     *
+     * @return true if pairing cancelled successfully, false otherwise
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean cancelPairing() {
         final IBluetooth service = sService;
         if (service == null) {
-            Log.e(TAG, "BT not enabled. Cannot create pairing user input");
+            Log.e(TAG, "BT not enabled. Cannot cancel pairing");
             return false;
         }
         try {
@@ -1537,17 +1556,6 @@
         return false;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public boolean isBluetoothDock() {
-        // TODO(BT)
-        /*
-        try {
-            return sService.isBluetoothDock(this);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}*/
-        return false;
-    }
-
     boolean isBluetoothEnabled() {
         boolean ret = false;
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -1558,13 +1566,14 @@
     }
 
     /**
-     * Requires {@link android.Manifest.permission#BLUETOOTH}.
+     * Gets whether the phonebook access is allowed for this bluetooth device
      *
      * @return Whether the phonebook access is allowed to this device. Can be {@link
      * #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public int getPhonebookAccessPermission() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1667,14 +1676,14 @@
     }
 
     /**
-     * Requires {@link android.Manifest.permission#BLUETOOTH}.
+     * Gets whether message access is allowed to this bluetooth device
      *
-     * @return Whether the message access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
-     * {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
+     * @return Whether the message access is allowed to this device.
      * @hide
      */
-    @UnsupportedAppUsage
-    public int getMessageAccessPermission() {
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public @AccessPermission int getMessageAccessPermission() {
         final IBluetooth service = sService;
         if (service == null) {
             return ACCESS_UNKNOWN;
@@ -1689,15 +1698,18 @@
 
     /**
      * Sets whether the message access is allowed to this device.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
      *
-     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
-     * #ACCESS_REJECTED}.
+     * @param value is the value we are setting the message access permission to
      * @return Whether the value has been successfully set.
      * @hide
      */
-    @UnsupportedAppUsage
-    public boolean setMessageAccessPermission(int value) {
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean setMessageAccessPermission(@AccessPermission int value) {
+        // Validates param value is one of the accepted constants
+        if (value != ACCESS_ALLOWED && value != ACCESS_REJECTED && value != ACCESS_UNKNOWN) {
+            throw new IllegalArgumentException(value + "is not a valid AccessPermission value");
+        }
         final IBluetooth service = sService;
         if (service == null) {
             return false;
@@ -1711,13 +1723,14 @@
     }
 
     /**
-     * Requires {@link android.Manifest.permission#BLUETOOTH}.
+     * Gets whether sim access is allowed for this bluetooth device
      *
-     * @return Whether the Sim access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
-     * {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
+     * @return Whether the Sim access is allowed to this device.
      * @hide
      */
-    public int getSimAccessPermission() {
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public @AccessPermission int getSimAccessPermission() {
         final IBluetooth service = sService;
         if (service == null) {
             return ACCESS_UNKNOWN;
@@ -1732,14 +1745,14 @@
 
     /**
      * Sets whether the Sim access is allowed to this device.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
      *
      * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
      * #ACCESS_REJECTED}.
      * @return Whether the value has been successfully set.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setSimAccessPermission(int value) {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1970,7 +1983,7 @@
      * @return the pin code as a UTF-8 byte array, or null if it is an invalid Bluetooth pin.
      * @hide
      */
-    @UnsupportedAppUsage
+    @VisibleForTesting
     public static byte[] convertPinToBytes(String pin) {
         if (pin == null) {
             return null;
diff --git a/core/java/android/telephony/CellBroadcastIntents.java b/core/java/android/telephony/CellBroadcastIntents.java
new file mode 100644
index 0000000..8446253
--- /dev/null
+++ b/core/java/android/telephony/CellBroadcastIntents.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.UserHandle;
+
+/**
+ * A static helper class used to send Intents with prepopulated flags.
+ * <p>
+ * This is intended to be used by the CellBroadcastService and will throw a security exception if
+ * used from a UID besides the network stack UID.
+ *
+ * @hide
+ */
+@SystemApi
+public class CellBroadcastIntents {
+    private static final String LOG_TAG = "CellBroadcastIntents";
+
+    /**
+     * @hide
+     */
+    private CellBroadcastIntents() {
+    }
+
+    /**
+     * Returns an intent which can be received by background BroadcastReceivers. This is only
+     * intended to be used by the CellBroadcastService and will throw a security exception if called
+     * from another UID.
+     *
+     * @param context            The context from which to send the broadcast
+     * @param user               The user from which to send the broadcast
+     * @param intent             The Intent to broadcast; all receivers matching this Intent will
+     *                           receive the broadcast.
+     * @param receiverPermission String naming a permissions that a receiver must hold in order to
+     *                           receive your broadcast. If null, no permission is required.
+     * @param receiverAppOp      The app op associated with the broadcast. If null, no appOp is
+     *                           required. If both receiverAppOp and receiverPermission are
+     *                           non-null, a receiver must have both of them to receive the
+     *                           broadcast
+     * @param resultReceiver     Your own BroadcastReceiver to treat as the final receiver of the
+     *                           broadcast.
+     * @param scheduler          A custom Handler with which to schedule the resultReceiver
+     *                           callback; if null it will be scheduled in the Context's main
+     *                           thread.
+     * @param initialCode        An initial value for the result code.  Often Activity.RESULT_OK.
+     * @param initialData        An initial value for the result data.  Often null.
+     * @param initialExtras      An initial value for the result extras.  Often null.
+     */
+    public static void sendOrderedBroadcastForBackgroundReceivers(@NonNull Context context,
+            @Nullable UserHandle user, @NonNull Intent intent, @Nullable String receiverPermission,
+            @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver,
+            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+            @Nullable Bundle initialExtras) {
+        int status = context.checkCallingOrSelfPermission(
+                "android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS");
+        if (status == PackageManager.PERMISSION_DENIED) {
+            throw new SecurityException(
+                    "Caller does not have permission to send broadcast for background receivers");
+        }
+        Intent backgroundIntent = new Intent(intent);
+        backgroundIntent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        if (user != null) {
+            context.createContextAsUser(user, 0).sendOrderedBroadcast(backgroundIntent,
+                    receiverPermission, receiverAppOp, resultReceiver, scheduler, initialCode,
+                    initialData, initialExtras);
+        } else {
+            context.sendOrderedBroadcast(backgroundIntent, receiverPermission,
+                    receiverAppOp, resultReceiver, scheduler, initialCode, initialData,
+                    initialExtras);
+        }
+    }
+}
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index f87a7c5..308c8b3 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -25,6 +25,8 @@
 import android.net.NetworkCapabilities;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.Annotation.ApnType;
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index e94b800..90625183 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -56,8 +56,12 @@
     public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
     public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;
     /**
-     * This constant is actually the length of 364 days, not of a year!
+     * @deprecated Not all years have the same number of days, and this constant is actually the
+     * length of 364 days. Please use other date/time constructs such as
+     * {@link java.util.concurrent.TimeUnit}, {@link java.util.Calendar} or
+     * {@link java.time.Duration} instead.
      */
+    @Deprecated
     public static final long YEAR_IN_MILLIS = WEEK_IN_MILLIS * 52;
 
     // The following FORMAT_* symbols are used for specifying the format of
diff --git a/core/java/android/util/CloseGuard.java b/core/java/android/util/CloseGuard.java
new file mode 100644
index 0000000..c39a6c9
--- /dev/null
+++ b/core/java/android/util/CloseGuard.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import android.annotation.NonNull;
+
+/**
+ * CloseGuard is a mechanism for flagging implicit finalizer cleanup of
+ * resources that should have been cleaned up by explicit close
+ * methods (aka "explicit termination methods" in Effective Java).
+ * <p>
+ * A simple example: <pre>   {@code
+ *   class Foo {
+ *
+ *       private final CloseGuard guard = CloseGuard.get();
+ *
+ *       ...
+ *
+ *       public Foo() {
+ *           ...;
+ *           guard.open("cleanup");
+ *       }
+ *
+ *       public void cleanup() {
+ *          guard.close();
+ *          ...;
+ *       }
+ *
+ *       protected void finalize() throws Throwable {
+ *           try {
+ *               // Note that guard could be null if the constructor threw.
+ *               if (guard != null) {
+ *                   guard.warnIfOpen();
+ *               }
+ *               cleanup();
+ *           } finally {
+ *               super.finalize();
+ *           }
+ *       }
+ *   }
+ * }</pre>
+ *
+ * In usage where the resource to be explicitly cleaned up is
+ * allocated after object construction, CloseGuard protection can
+ * be deferred. For example: <pre>   {@code
+ *   class Bar {
+ *
+ *       private final CloseGuard guard = CloseGuard.get();
+ *
+ *       ...
+ *
+ *       public Bar() {
+ *           ...;
+ *       }
+ *
+ *       public void connect() {
+ *          ...;
+ *          guard.open("cleanup");
+ *       }
+ *
+ *       public void cleanup() {
+ *          guard.close();
+ *          ...;
+ *          Reference.reachabilityFence(this);
+ *          // For full correctness in the absence of a close() call, other methods may also need
+ *          // reachabilityFence() calls.
+ *       }
+ *
+ *       protected void finalize() throws Throwable {
+ *           try {
+ *               // Note that guard could be null if the constructor threw.
+ *               if (guard != null) {
+ *                   guard.warnIfOpen();
+ *               }
+ *               cleanup();
+ *           } finally {
+ *               super.finalize();
+ *           }
+ *       }
+ *   }
+ * }</pre>
+ *
+ * When used in a constructor, calls to {@code open} should occur at
+ * the end of the constructor since an exception that would cause
+ * abrupt termination of the constructor will mean that the user will
+ * not have a reference to the object to cleanup explicitly. When used
+ * in a method, the call to {@code open} should occur just after
+ * resource acquisition.
+ */
+public final class CloseGuard {
+    private final dalvik.system.CloseGuard mImpl;
+
+    /**
+     * Constructs a new CloseGuard instance.
+     * {@link #open(String)} can be used to set up the instance to warn on failure to close.
+     */
+    public CloseGuard() {
+        mImpl = dalvik.system.CloseGuard.get();
+    }
+
+    /**
+     * Initializes the instance with a warning that the caller should have explicitly called the
+     * {@code closeMethodName} method instead of relying on finalization.
+     *
+     * @param closeMethodName non-null name of explicit termination method. Printed by warnIfOpen.
+     * @throws NullPointerException if closeMethodName is null.
+     */
+    public void open(@NonNull String closeMethodName) {
+        mImpl.open(closeMethodName);
+    }
+
+    /** Marks this CloseGuard instance as closed to avoid warnings on finalization. */
+    public void close() {
+        mImpl.close();
+    }
+
+    /**
+     * Logs a warning if the caller did not properly cleanup by calling an explicit close method
+     * before finalization.
+     */
+    public void warnIfOpen() {
+        mImpl.warnIfOpen();
+    }
+}
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
index b906d84..ed613c3 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
@@ -176,14 +176,12 @@
                         mDevice.setPin(mPin);
                         break;
                     case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
-                        mDevice.setPasskey(mPasskey);
                         break;
                     case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
                     case BluetoothDevice.PAIRING_VARIANT_CONSENT:
                         mDevice.setPairingConfirmation(true);
                         break;
                     case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
-                        mDevice.setRemoteOutOfBandData();
                         break;
                 }
             } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 1670d49..4d4f447 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -24,6 +24,7 @@
     ],
     static_libs: [
         "frameworks-base-testutils",
+        "core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
         "core-tests-support",
         "android-common",
         "frameworks-core-util-lib",
diff --git a/core/tests/coretests/src/android/util/CloseGuardTest.java b/core/tests/coretests/src/android/util/CloseGuardTest.java
new file mode 100644
index 0000000..d86c7b7
--- /dev/null
+++ b/core/tests/coretests/src/android/util/CloseGuardTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import libcore.dalvik.system.CloseGuardSupport;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+
+/** Unit tests for {@link android.util.CloseGuard} */
+public class CloseGuardTest {
+
+    @Rule
+    public final TestRule rule = CloseGuardSupport.getRule();
+
+    @Test
+    public void testEnabled_NotOpen() throws Throwable {
+        ResourceOwner owner = new ResourceOwner();
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test
+    public void testEnabled_OpenNotClosed() throws Throwable {
+        ResourceOwner owner = new ResourceOwner();
+        owner.open();
+        assertUnreleasedResources(owner, 1);
+    }
+
+    @Test
+    public void testEnabled_OpenThenClosed() throws Throwable {
+        ResourceOwner owner = new ResourceOwner();
+        owner.open();
+        owner.close();
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testOpen_withNullMethodName_throwsNPE() throws Throwable {
+        CloseGuard closeGuard = new CloseGuard();
+        closeGuard.open(null);
+    }
+
+    private void assertUnreleasedResources(ResourceOwner owner, int expectedCount)
+            throws Throwable {
+        try {
+            CloseGuardSupport.getFinalizerChecker().accept(owner, expectedCount);
+        } finally {
+            // Close the resource so that CloseGuard does not generate a warning for real when it
+            // is actually finalized.
+            owner.close();
+        }
+    }
+
+    /**
+     * A test user of {@link CloseGuard}.
+     */
+    private static class ResourceOwner {
+
+        private final CloseGuard mCloseGuard;
+
+        ResourceOwner() {
+            mCloseGuard = new CloseGuard();
+        }
+
+        public void open() {
+            mCloseGuard.open("close");
+        }
+
+        public void close() {
+            mCloseGuard.close();
+        }
+
+        /**
+         * Make finalize public so that it can be tested directly without relying on garbage
+         * collection to trigger it.
+         */
+        @Override
+        public void finalize() throws Throwable {
+            mCloseGuard.warnIfOpen();
+            super.finalize();
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 96aee51..a2bd210 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -155,8 +155,8 @@
     public boolean disconnect(BluetoothDevice device) {
         if (mService == null) return false;
         // Downgrade priority as user is disconnecting the headset.
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
-            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        if (mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         }
         return mService.disconnect(device);
     }
@@ -179,23 +179,29 @@
     }
 
     public boolean isPreferred(BluetoothDevice device) {
-        if (mService == null) return false;
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        if (mService == null) {
+            return false;
+        }
+        return mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     public int getPreferred(BluetoothDevice device) {
-        if (mService == null) return BluetoothProfile.PRIORITY_OFF;
-        return mService.getPriority(device);
+        if (mService == null) {
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+        }
+        return mService.getConnectionPolicy(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
-        if (mService == null) return;
+        if (mService == null) {
+            return;
+        }
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
     boolean isA2dpPlaying() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
index 55765dd..9c896c8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -124,8 +124,8 @@
             return false;
         }
         // Downgrade priority as user is disconnecting the headset.
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        if (mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         }
         return mService.disconnect(device);
     }
@@ -141,14 +141,14 @@
         if (mService == null) {
             return false;
         }
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        return mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     public int getPreferred(BluetoothDevice device) {
         if (mService == null) {
-            return BluetoothProfile.PRIORITY_OFF;
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
         }
-        return mService.getPriority(device);
+        return mService.getConnectionPolicy(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
@@ -156,11 +156,11 @@
             return;
         }
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 0d972c5..2f34b2b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -116,7 +116,7 @@
         }
         return new Pair<>(
                 getBluetoothDrawable(context,
-                        com.android.internal.R.drawable.ic_settings_bluetooth),
+                        com.android.internal.R.drawable.ic_settings_bluetooth).mutate(),
                 context.getString(R.string.bluetooth_talkback_bluetooth));
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index c1b89e6..abfee1d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -643,12 +643,8 @@
 
         refresh();
 
-        if (bondState == BluetoothDevice.BOND_BONDED) {
-            if (mDevice.isBluetoothDock()) {
-                onBondingDockConnect();
-            } else if (mDevice.isBondingInitiatedLocally()) {
-                connect(false);
-            }
+        if (bondState == BluetoothDevice.BOND_BONDED && mDevice.isBondingInitiatedLocally()) {
+            connect(false);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index 9f7b718..560cb3b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -120,8 +120,8 @@
             return false;
         }
         // Downgrade priority as user is disconnecting the headset.
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        if (mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         }
         return mService.disconnect(device);
     }
@@ -165,14 +165,14 @@
         if (mService == null) {
             return false;
         }
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        return mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     public int getPreferred(BluetoothDevice device) {
         if (mService == null) {
-            return BluetoothProfile.PRIORITY_OFF;
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
         }
-        return mService.getPriority(device);
+        return mService.getConnectionPolicy(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
@@ -180,11 +180,11 @@
             return;
         }
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index ebaeb74..58655a2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -153,8 +153,8 @@
     public boolean disconnect(BluetoothDevice device) {
         if (mService == null) return false;
         // Downgrade priority as user is disconnecting the hearing aid.
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
-            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        if (mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         }
         return mService.disconnect(device);
     }
@@ -177,23 +177,29 @@
     }
 
     public boolean isPreferred(BluetoothDevice device) {
-        if (mService == null) return false;
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        if (mService == null) {
+            return false;
+        }
+        return mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     public int getPreferred(BluetoothDevice device) {
-        if (mService == null) return BluetoothProfile.PRIORITY_OFF;
-        return mService.getPriority(device);
+        if (mService == null) {
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+        }
+        return mService.getConnectionPolicy(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
-        if (mService == null) return;
+        if (mService == null) {
+            return;
+        }
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
index 860b77d..a372e23 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
@@ -135,8 +135,8 @@
             return false;
         }
         // Downgrade priority as user is disconnecting the headset.
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
-            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        if (mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         }
         return mService.disconnect(device);
     }
@@ -154,15 +154,15 @@
         if (mService == null) {
             return false;
         }
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        return mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     @Override
     public int getPreferred(BluetoothDevice device) {
         if (mService == null) {
-            return BluetoothProfile.PRIORITY_OFF;
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
         }
-        return mService.getPriority(device);
+        return mService.getConnectionPolicy(device);
     }
 
     @Override
@@ -171,11 +171,11 @@
             return;
         }
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index 6d874ab..975a1e6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -116,23 +116,27 @@
     }
 
     public boolean isPreferred(BluetoothDevice device) {
-        if (mService == null) return false;
-        return mService.getPriority(device) != BluetoothProfile.PRIORITY_OFF;
+        if (mService == null) {
+            return false;
+        }
+        return mService.getConnectionPolicy(device) != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     public int getPreferred(BluetoothDevice device) {
-        if (mService == null) return BluetoothProfile.PRIORITY_OFF;
-        return mService.getPriority(device);
+        if (mService == null) {
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+        }
+        return mService.getConnectionPolicy(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
         if (mService == null) return;
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
index d4dda32..95139a1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
@@ -123,8 +123,8 @@
             return false;
         }
         // Downgrade priority as user is disconnecting.
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        if (mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         }
         return mService.disconnect(device);
     }
@@ -140,14 +140,14 @@
         if (mService == null) {
             return false;
         }
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        return mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     public int getPreferred(BluetoothDevice device) {
         if (mService == null) {
-            return BluetoothProfile.PRIORITY_OFF;
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
         }
-        return mService.getPriority(device);
+        return mService.getConnectionPolicy(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
@@ -155,11 +155,11 @@
             return;
         }
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
index b2a9a6a..31a0eea 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
@@ -119,8 +119,8 @@
         if (mService == null) {
             return false;
         }
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        if (mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         }
         return mService.disconnect(device);
     }
@@ -136,14 +136,14 @@
         if (mService == null) {
             return false;
         }
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        return mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     public int getPreferred(BluetoothDevice device) {
         if (mService == null) {
-            return BluetoothProfile.PRIORITY_OFF;
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
         }
-        return mService.getPriority(device);
+        return mService.getConnectionPolicy(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
@@ -151,11 +151,11 @@
             return;
         }
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS
index 7162121..387bae1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS
@@ -1,8 +1,7 @@
 # Default reviewers for this and subdirectories.
-asapperstein@google.com
-asargent@google.com
-eisenbach@google.com
-jackqdyulei@google.com
 siyuanh@google.com
+hughchen@google.com
+timhypeng@google.com
+robertluo@google.com
 
-# Emergency approvers in case the above are not available
\ No newline at end of file
+# Emergency approvers in case the above are not available
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
index e1e5dbe..8e3f3ed 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
@@ -57,7 +57,7 @@
     }
 
     public int getPreferred(BluetoothDevice device) {
-        return BluetoothProfile.PRIORITY_OFF; // Settings app doesn't handle OPP
+        return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; // Settings app doesn't handle OPP
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
index a2da4fb..4ea0df6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
@@ -151,14 +151,14 @@
         if (mService == null) {
             return false;
         }
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        return mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     public int getPreferred(BluetoothDevice device) {
         if (mService == null) {
-            return BluetoothProfile.PRIORITY_OFF;
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
         }
-        return mService.getPriority(device);
+        return mService.getConnectionPolicy(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
@@ -166,11 +166,11 @@
             return;
         }
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
index 9b733f2..0ca4d61 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
@@ -119,8 +119,8 @@
         if (mService == null) {
             return false;
         }
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        if (mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
         }
         return mService.disconnect(device);
     }
@@ -136,14 +136,14 @@
         if (mService == null) {
             return false;
         }
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        return mService.getConnectionPolicy(device) > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
     }
 
     public int getPreferred(BluetoothDevice device) {
         if (mService == null) {
-            return BluetoothProfile.PRIORITY_OFF;
+            return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
         }
-        return mService.getPriority(device);
+        return mService.getConnectionPolicy(device);
     }
 
     public void setPreferred(BluetoothDevice device, boolean preferred) {
@@ -151,11 +151,11 @@
             return;
         }
         if (preferred) {
-            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            if (mService.getConnectionPolicy(device) < BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+                mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
             }
         } else {
-            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+            mService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
         }
     }
 
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 37add3d..135f199d 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -62,9 +62,6 @@
 
     private @NonNull AudioDeviceBroker mDeviceBroker;
 
-    // cache of the address of the last dock the device was connected to
-    private String mDockAddress;
-
     // Monitoring of audio routes.  Protected by mAudioRoutes.
     final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo();
     final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers =
@@ -168,7 +165,7 @@
         int a2dpVolume = btInfo.getVolume();
         if (AudioService.DEBUG_DEVICES) {
             Log.d(TAG, "onSetA2dpSinkConnectionState btDevice=" + btDevice + " state="
-                    + state + " is dock=" + btDevice.isBluetoothDock() + " vol=" + a2dpVolume);
+                    + state + " vol=" + a2dpVolume);
         }
         String address = btDevice.getAddress();
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
@@ -196,42 +193,17 @@
                         mDeviceBroker.postBluetoothA2dpDeviceConfigChange(btDevice);
                     }
                 } else {
-                    if (btDevice.isBluetoothDock()) {
-                        if (state == BluetoothProfile.STATE_DISCONNECTED) {
-                            // introduction of a delay for transient disconnections of docks when
-                            // power is rapidly turned off/on, this message will be canceled if
-                            // we reconnect the dock under a preset delay
-                            makeA2dpDeviceUnavailableLater(address,
-                                    AudioDeviceBroker.BTA2DP_DOCK_TIMEOUT_MS);
-                            // the next time isConnected is evaluated, it will be false for the dock
-                        }
-                    } else {
-                        makeA2dpDeviceUnavailableNow(address, di.mDeviceCodecFormat);
-                    }
+                    makeA2dpDeviceUnavailableNow(address, di.mDeviceCodecFormat);
                 }
-            } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
-                if (btDevice.isBluetoothDock()) {
-                    // this could be a reconnection after a transient disconnection
-                    mDeviceBroker.cancelA2dpDockTimeout();
-                    mDockAddress = address;
-                } else {
-                    // this could be a connection of another A2DP device before the timeout of
-                    // a dock: cancel the dock timeout, and make the dock unavailable now
-                    if (mDeviceBroker.hasScheduledA2dpDockTimeout() && mDockAddress != null) {
-                        mDeviceBroker.cancelA2dpDockTimeout();
-                        makeA2dpDeviceUnavailableNow(mDockAddress,
-                                AudioSystem.AUDIO_FORMAT_DEFAULT);
-                    }
-                }
-                if (a2dpVolume != -1) {
-                    mDeviceBroker.postSetVolumeIndexOnDevice(AudioSystem.STREAM_MUSIC,
-                            // convert index to internal representation in VolumeStreamState
-                            a2dpVolume * 10,
-                            AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "onSetA2dpSinkConnectionState");
-                }
-                makeA2dpDeviceAvailable(address, BtHelper.getName(btDevice),
-                        "onSetA2dpSinkConnectionState", a2dpCodec);
             }
+            if (a2dpVolume != -1) {
+                mDeviceBroker.postSetVolumeIndexOnDevice(AudioSystem.STREAM_MUSIC,
+                        // convert index to internal representation in VolumeStreamState
+                        a2dpVolume * 10,
+                        AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "onSetA2dpSinkConnectionState");
+            }
+            makeA2dpDeviceAvailable(address, BtHelper.getName(btDevice),
+                    "onSetA2dpSinkConnectionState", a2dpCodec);
         }
     }
 
@@ -672,9 +644,6 @@
                 DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
         // Remove A2DP routes as well
         setCurrentAudioRouteNameIfPossible(null);
-        if (mDockAddress == address) {
-            mDockAddress = null;
-        }
     }
 
     @GuardedBy("mConnectedDevices")
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java b/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java
index 52cede2..23b5c14 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecKeycode.java
@@ -250,7 +250,11 @@
             new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_LEFT_UP),
             // No Android keycode defined for CEC_KEYCODE_LEFT_DOWN
             new KeycodeEntry(UNSUPPORTED_KEYCODE, CEC_KEYCODE_LEFT_DOWN),
+            // Both KEYCODE_HOME and KEYCODE_MENU keys are sent as CEC_KEYCODE_ROOT_MENU
+            // NOTE that the HOME key is not usually forwarded.
+            // When CEC_KEYCODE_ROOT_MENU is received, it is translated to KEYCODE_HOME
             new KeycodeEntry(KeyEvent.KEYCODE_HOME, CEC_KEYCODE_ROOT_MENU),
+            new KeycodeEntry(KeyEvent.KEYCODE_MENU, CEC_KEYCODE_ROOT_MENU),
             new KeycodeEntry(KeyEvent.KEYCODE_SETTINGS, CEC_KEYCODE_SETUP_MENU),
             new KeycodeEntry(KeyEvent.KEYCODE_TV_CONTENTS_MENU, CEC_KEYCODE_CONTENTS_MENU, false),
             // No Android keycode defined for CEC_KEYCODE_FAVORITE_MENU
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index 9b9f4de..f295ed3 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.provider.Settings;
 import android.telecom.TelecomManager;
 
 import com.android.internal.util.NotificationMessagingUtil;
@@ -55,14 +54,9 @@
         final boolean isLeftHighImportance = leftImportance >= IMPORTANCE_DEFAULT;
         final boolean isRightHighImportance = rightImportance >= IMPORTANCE_DEFAULT;
 
-        // With new interruption model, prefer importance bucket above all other criteria
-        // (to ensure buckets are contiguous)
-        if (Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 1) == 1) {
-            if (isLeftHighImportance != isRightHighImportance) {
-                // by importance bucket, high importance higher than low importance
-                return -1 * Boolean.compare(isLeftHighImportance, isRightHighImportance);
-            }
+        if (isLeftHighImportance != isRightHighImportance) {
+            // by importance bucket, high importance higher than low importance
+            return -1 * Boolean.compare(isLeftHighImportance, isRightHighImportance);
         }
 
         // first all colorized notifications
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index 8441edb..1b1ac6d 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -114,16 +114,10 @@
     }
 
     @Override
-    public synchronized void suggestManualTime(ManualTimeSuggestion suggestion) {
+    public synchronized void suggestManualTime(@NonNull ManualTimeSuggestion suggestion) {
         final TimestampedValue<Long> newUtcTime = suggestion.getUtcTime();
 
-        // We can validate the suggestion against the reference time clock.
-        long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis();
-        if (elapsedRealtimeMillis < newUtcTime.getReferenceTimeMillis()) {
-            // elapsedRealtime clock went backwards?
-            Slog.w(LOG_TAG, "New reference time is in the future? Ignoring."
-                    + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
-                    + ", timeSuggestion=" + suggestion);
+        if (!validateSuggestionTime(newUtcTime, suggestion)) {
             return;
         }
 
@@ -202,62 +196,76 @@
     }
 
     @GuardedBy("this")
-    private boolean validateAndStorePhoneSuggestion(@NonNull PhoneTimeSuggestion timeSuggestion) {
-        if (timeSuggestion.getUtcTime().getValue() == null) {
-            Slog.w(LOG_TAG, "Suggestion utcTime contains null value"
-                    + " timeSuggestion=" + timeSuggestion);
+    private boolean validateAndStorePhoneSuggestion(@NonNull PhoneTimeSuggestion suggestion) {
+        TimestampedValue<Long> newUtcTime = suggestion.getUtcTime();
+        if (!validateSuggestionTime(newUtcTime, suggestion)) {
+            // There's probably nothing useful we can do: elsewhere we assume that reference
+            // times are in the past so just stop here.
             return false;
         }
 
-        int phoneId = timeSuggestion.getPhoneId();
+        int phoneId = suggestion.getPhoneId();
         LinkedList<PhoneTimeSuggestion> phoneSuggestions = mSuggestionByPhoneId.get(phoneId);
         if (phoneSuggestions == null) {
             // The first time we've seen this phoneId.
             phoneSuggestions = new LinkedList<>();
             mSuggestionByPhoneId.put(phoneId, phoneSuggestions);
         } else if (phoneSuggestions.isEmpty()) {
-            Slog.w(LOG_TAG, "Suggestions unexpectedly empty when adding"
-                    + " timeSuggestion=" + timeSuggestion);
+            Slog.w(LOG_TAG, "Suggestions unexpectedly empty when adding suggestion=" + suggestion);
         }
 
         if (!phoneSuggestions.isEmpty()) {
-            PhoneTimeSuggestion previousSuggestion = phoneSuggestions.getFirst();
-
             // We can log / discard suggestions with obvious issues with the reference time clock.
-            long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis();
-            TimestampedValue<Long> newTime = timeSuggestion.getUtcTime();
-            if (elapsedRealtimeMillis < newTime.getReferenceTimeMillis()) {
-                // elapsedRealtime clock went backwards?
-                Slog.w(LOG_TAG, "New reference time is in the future?"
-                        + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
-                        + ", timeSuggestion=" + timeSuggestion);
-                // There's probably nothing useful we can do: elsewhere we assume that reference
-                // times are in the past so just stop here.
+            PhoneTimeSuggestion previousSuggestion = phoneSuggestions.getFirst();
+            if (previousSuggestion == null
+                    || previousSuggestion.getUtcTime() == null
+                    || previousSuggestion.getUtcTime().getValue() == null) {
+                // This should be impossible given we only store validated suggestions.
+                Slog.w(LOG_TAG, "Previous suggestion is null or has a null time."
+                        + " previousSuggestion=" + previousSuggestion
+                        + ", suggestion=" + suggestion);
                 return false;
             }
 
-            if (previousSuggestion.getUtcTime() != null) {
-                long referenceTimeDifference = TimestampedValue.referenceTimeDifference(
-                        timeSuggestion.getUtcTime(), previousSuggestion.getUtcTime());
-                if (referenceTimeDifference < 0) {
-                    // The reference time is before the previously received suggestion. Ignore it.
-                    Slog.w(LOG_TAG, "Out of order phone suggestion received."
-                            + " referenceTimeDifference=" + referenceTimeDifference
-                            + " lastSuggestion=" + previousSuggestion
-                            + " newSuggestion=" + timeSuggestion);
-                    return false;
-                }
+            long referenceTimeDifference = TimestampedValue.referenceTimeDifference(
+                    newUtcTime, previousSuggestion.getUtcTime());
+            if (referenceTimeDifference < 0) {
+                // The reference time is before the previously received suggestion. Ignore it.
+                Slog.w(LOG_TAG, "Out of order phone suggestion received."
+                        + " referenceTimeDifference=" + referenceTimeDifference
+                        + " previousSuggestion=" + previousSuggestion
+                        + " suggestion=" + suggestion);
+                return false;
             }
         }
 
         // Store the latest suggestion.
-        phoneSuggestions.addFirst(timeSuggestion);
+        phoneSuggestions.addFirst(suggestion);
         if (phoneSuggestions.size() > KEEP_SUGGESTION_HISTORY_SIZE) {
             phoneSuggestions.removeLast();
         }
         return true;
     }
 
+    private boolean validateSuggestionTime(
+            @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) {
+        if (newUtcTime.getValue() == null) {
+            Slog.w(LOG_TAG, "Suggested time value is null. suggestion=" + suggestion);
+            return false;
+        }
+
+        // We can validate the suggestion against the reference time clock.
+        long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis();
+        if (elapsedRealtimeMillis < newUtcTime.getReferenceTimeMillis()) {
+            // elapsedRealtime clock went backwards?
+            Slog.w(LOG_TAG, "New reference time is in the future? Ignoring."
+                    + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
+                    + ", suggestion=" + suggestion);
+            return false;
+        }
+        return true;
+    }
+
     @GuardedBy("this")
     private void doAutoTimeDetection(@NonNull String detectionReason) {
         if (!mCallback.isAutoTimeDetectionEnabled()) {
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 73faf9f..3940a3b 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -116,7 +116,8 @@
             ApnSetting.TYPE_CBS,
             ApnSetting.TYPE_IA,
             ApnSetting.TYPE_EMERGENCY,
-            ApnSetting.TYPE_MCX
+            ApnSetting.TYPE_MCX,
+            ApnSetting.TYPE_XCAP,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ApnType {
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index bbf746fc..fc717e7 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -24,8 +24,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.AccessNetworkConstants.TransportType;
-
 import android.telephony.Annotation.NetworkType;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -90,7 +90,7 @@
      * Dual Connectivity(EN-DC).
      * @hide
      */
-    public static final int NR_STATE_NONE = -1;
+    public static final int NR_STATE_NONE = 0;
 
     /**
      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 1e601cf..9ace86c 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -102,7 +102,7 @@
      * Indicates frequency range is unknown.
      * @hide
      */
-    public static final int FREQUENCY_RANGE_UNKNOWN = -1;
+    public static final int FREQUENCY_RANGE_UNKNOWN = 0;
 
     /**
      * Indicates the frequency range is below 1GHz.
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 60774e7..034fc22 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -20,7 +20,7 @@
 import android.annotation.Nullable;
 import android.content.ContentValues;
 import android.database.Cursor;
-import android.hardware.radio.V1_4.ApnTypes;
+import android.hardware.radio.V1_5.ApnTypes;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -110,6 +110,8 @@
     public static final int TYPE_EMERGENCY = ApnTypes.EMERGENCY;
     /** APN type for MCX (Mission Critical Service) where X can be PTT/Video/Data */
     public static final int TYPE_MCX = ApnTypes.MCX;
+    /** APN type for XCAP. */
+    public static final int TYPE_XCAP = ApnTypes.XCAP;
 
     // Possible values for authentication types.
     /** No authentication type. */
@@ -198,6 +200,7 @@
         APN_TYPE_STRING_MAP.put("ia", TYPE_IA);
         APN_TYPE_STRING_MAP.put("emergency", TYPE_EMERGENCY);
         APN_TYPE_STRING_MAP.put("mcx", TYPE_MCX);
+        APN_TYPE_STRING_MAP.put("xcap", TYPE_XCAP);
         APN_TYPE_INT_MAP = new ArrayMap<Integer, String>();
         APN_TYPE_INT_MAP.put(TYPE_DEFAULT, "default");
         APN_TYPE_INT_MAP.put(TYPE_MMS, "mms");
@@ -210,6 +213,7 @@
         APN_TYPE_INT_MAP.put(TYPE_IA, "ia");
         APN_TYPE_INT_MAP.put(TYPE_EMERGENCY, "emergency");
         APN_TYPE_INT_MAP.put(TYPE_MCX, "mcx");
+        APN_TYPE_INT_MAP.put(TYPE_XCAP, "xcap");
 
         PROTOCOL_STRING_MAP = new ArrayMap<String, Integer>();
         PROTOCOL_STRING_MAP.put("IP", PROTOCOL_IP);
@@ -1944,8 +1948,9 @@
          * {@link ApnSetting} built from this builder otherwise.
          */
         public ApnSetting build() {
-            if ((mApnTypeBitmask & (TYPE_DEFAULT | TYPE_MMS | TYPE_SUPL | TYPE_DUN | TYPE_HIPRI |
-                    TYPE_FOTA | TYPE_IMS | TYPE_CBS | TYPE_IA | TYPE_EMERGENCY | TYPE_MCX)) == 0
+            if ((mApnTypeBitmask & (TYPE_DEFAULT | TYPE_MMS | TYPE_SUPL | TYPE_DUN | TYPE_HIPRI
+                    | TYPE_FOTA | TYPE_IMS | TYPE_CBS | TYPE_IA | TYPE_EMERGENCY | TYPE_MCX
+                    | TYPE_XCAP)) == 0
                 || TextUtils.isEmpty(mApnName) || TextUtils.isEmpty(mEntryName)) {
                 return null;
             }
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 76b214b..f4b2cef 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -889,6 +889,12 @@
      */
     public static final int CODE_WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 1623;
 
+    /**
+     * The dialed RTT call should be retried without RTT
+     * @hide
+     */
+    public static final int CODE_RETRY_ON_IMS_WITHOUT_RTT = 3001;
+
     /*
      * OEM specific error codes. To be used by OEMs when they don't want to reveal error code which
      * would be replaced by ERROR_UNSPECIFIED.
@@ -1069,6 +1075,7 @@
             CODE_REJECT_VT_AVPF_NOT_ALLOWED,
             CODE_REJECT_ONGOING_ENCRYPTED_CALL,
             CODE_REJECT_ONGOING_CS_CALL,
+            CODE_RETRY_ON_IMS_WITHOUT_RTT,
             CODE_OEM_CAUSE_1,
             CODE_OEM_CAUSE_2,
             CODE_OEM_CAUSE_3,
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index 05e2ed9..6e63514 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -161,6 +161,8 @@
     public static final String APN_TYPE_EMERGENCY = "emergency";
     /** APN type for Mission Critical Services */
     public static final String APN_TYPE_MCX = "mcx";
+    /** APN type for XCAP */
+    public static final String APN_TYPE_XCAP = "xcap";
     /** Array of all APN types */
     public static final String[] APN_TYPES = {APN_TYPE_DEFAULT,
             APN_TYPE_MMS,
@@ -172,7 +174,8 @@
             APN_TYPE_CBS,
             APN_TYPE_IA,
             APN_TYPE_EMERGENCY,
-            APN_TYPE_MCX
+            APN_TYPE_MCX,
+            APN_TYPE_XCAP,
     };
 
     public static final int RIL_CARD_MAX_APPS    = 8;