Merge "Revert "Refine documentation for Process.setThreadPriority""
diff --git a/ApiDocs.bp b/ApiDocs.bp
index ca921ff..d630209 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -65,7 +65,7 @@
         "test-base/src/**/*.java",
         ":opt-telephony-srcs",
         ":opt-net-voip-srcs",
-        ":art-module-public-api-stubs-source",
+        ":art.module.public.api{.public.stubs.source}",
         ":conscrypt.module.public.api{.public.stubs.source}",
         ":android_icu4j_public_api_files",
         "test-mock/src/**/*.java",
@@ -131,7 +131,7 @@
     ],
     knowntags: [
         "docs/knowntags.txt",
-        ":known-oj-tags",
+        ":art.module.public.api{.doctags}",
     ],
     custom_template: "droiddoc-templates-sdk",
     resourcesdir: "docs/html/reference/images/",
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 4b0df44..9e087f0 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -47,7 +47,7 @@
         "core/java/**/*.logtags",
         ":opt-telephony-srcs",
         ":opt-net-voip-srcs",
-        ":art-module-public-api-stubs-source",
+        ":art.module.public.api{.public.stubs.source}",
         ":android_icu4j_public_api_files",
         "**/package.html",
     ],
diff --git a/apex/media/OWNERS b/apex/media/OWNERS
index 9b853c5..ced2fb5 100644
--- a/apex/media/OWNERS
+++ b/apex/media/OWNERS
@@ -1,4 +1,10 @@
 andrewlewis@google.com
 aquilescanta@google.com
+chz@google.com
+hdmoon@google.com
+hkuang@google.com
+jinpark@google.com
+klhyun@google.com
+lnilsson@google.com
 marcone@google.com
 sungsoo@google.com
diff --git a/api/current.txt b/api/current.txt
index 167c2b4..e16876e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8771,6 +8771,7 @@
     method public void onPhyUpdate(android.bluetooth.BluetoothGatt, int, int, int);
     method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int);
     method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int);
+    method public void onServiceChanged(@NonNull android.bluetooth.BluetoothGatt);
     method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
   }
 
@@ -36463,7 +36464,7 @@
     method public int dataCapacity();
     method public int dataPosition();
     method public int dataSize();
-    method public void enforceInterface(String);
+    method public void enforceInterface(@NonNull String);
     method public boolean hasFileDescriptors();
     method public byte[] marshall();
     method @NonNull public static android.os.Parcel obtain();
@@ -36534,7 +36535,7 @@
     method public void writeFloatArray(@Nullable float[]);
     method public void writeInt(int);
     method public void writeIntArray(@Nullable int[]);
-    method public void writeInterfaceToken(String);
+    method public void writeInterfaceToken(@NonNull String);
     method public void writeList(@Nullable java.util.List);
     method public void writeLong(long);
     method public void writeLongArray(@Nullable long[]);
@@ -46944,7 +46945,7 @@
     method public long getNci();
     method @IntRange(from=0, to=3279165) public int getNrarfcn();
     method @IntRange(from=0, to=1007) public int getPci();
-    method @IntRange(from=0, to=65535) public int getTac();
+    method @IntRange(from=0, to=16777215) public int getTac();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR;
   }
@@ -47038,9 +47039,9 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoWcdma> CREATOR;
   }
 
-  public abstract class CellLocation {
-    ctor public CellLocation();
-    method public static android.telephony.CellLocation getEmpty();
+  @Deprecated public abstract class CellLocation {
+    ctor @Deprecated public CellLocation();
+    method @Deprecated public static android.telephony.CellLocation getEmpty();
     method @Deprecated public static void requestLocationUpdate();
   }
 
@@ -48548,19 +48549,19 @@
 
 package android.telephony.cdma {
 
-  public class CdmaCellLocation extends android.telephony.CellLocation {
-    ctor public CdmaCellLocation();
-    ctor public CdmaCellLocation(android.os.Bundle);
-    method public static double convertQuartSecToDecDegrees(int);
-    method public void fillInNotifierBundle(android.os.Bundle);
-    method public int getBaseStationId();
-    method public int getBaseStationLatitude();
-    method public int getBaseStationLongitude();
-    method public int getNetworkId();
-    method public int getSystemId();
-    method public void setCellLocationData(int, int, int);
-    method public void setCellLocationData(int, int, int, int, int);
-    method public void setStateInvalid();
+  @Deprecated public class CdmaCellLocation extends android.telephony.CellLocation {
+    ctor @Deprecated public CdmaCellLocation();
+    ctor @Deprecated public CdmaCellLocation(android.os.Bundle);
+    method @Deprecated public static double convertQuartSecToDecDegrees(int);
+    method @Deprecated public void fillInNotifierBundle(android.os.Bundle);
+    method @Deprecated public int getBaseStationId();
+    method @Deprecated public int getBaseStationLatitude();
+    method @Deprecated public int getBaseStationLongitude();
+    method @Deprecated public int getNetworkId();
+    method @Deprecated public int getSystemId();
+    method @Deprecated public void setCellLocationData(int, int, int);
+    method @Deprecated public void setCellLocationData(int, int, int, int, int);
+    method @Deprecated public void setStateInvalid();
   }
 
 }
@@ -48760,15 +48761,15 @@
 
 package android.telephony.gsm {
 
-  public class GsmCellLocation extends android.telephony.CellLocation {
-    ctor public GsmCellLocation();
-    ctor public GsmCellLocation(android.os.Bundle);
-    method public void fillInNotifierBundle(android.os.Bundle);
-    method public int getCid();
-    method public int getLac();
-    method public int getPsc();
-    method public void setLacAndCid(int, int);
-    method public void setStateInvalid();
+  @Deprecated public class GsmCellLocation extends android.telephony.CellLocation {
+    ctor @Deprecated public GsmCellLocation();
+    ctor @Deprecated public GsmCellLocation(android.os.Bundle);
+    method @Deprecated public void fillInNotifierBundle(android.os.Bundle);
+    method @Deprecated public int getCid();
+    method @Deprecated public int getLac();
+    method @Deprecated public int getPsc();
+    method @Deprecated public void setLacAndCid(int, int);
+    method @Deprecated public void setStateInvalid();
   }
 
   @Deprecated public final class SmsManager {
diff --git a/api/system-current.txt b/api/system-current.txt
index 6d13582..ddf9c4d9 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -11188,6 +11188,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 9f6b828..1c40cff 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -16,6 +16,8 @@
 
 package android.bluetooth;
 
+import android.annotation.NonNull;
+
 /**
  * This abstract class is used to implement {@link BluetoothGatt} callbacks.
  */
@@ -203,8 +205,7 @@
      * called to re-discover the services.
      *
      * @param gatt GATT client involved
-     * @hide
      */
-    public void onServiceChanged(BluetoothGatt gatt) {
+    public void onServiceChanged(@NonNull BluetoothGatt gatt) {
     }
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index f257326..2138f53 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -785,4 +785,6 @@
     List<String> getMimeGroup(String packageName, String group);
 
     boolean isAutoRevokeWhitelisted(String packageName);
+
+    void grantImplicitAccess(int queryingUid, String visibleAuthority);
 }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 46af630..0789cfb 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -8018,6 +8018,20 @@
                 "getMimeGroup not implemented in subclass");
     }
 
+    /**
+     * Grants implicit visibility of the package that provides an authority to a querying UID.
+     *
+     * @throws SecurityException when called by a package other than the contacts provider
+     * @hide
+     */
+    public void grantImplicitAccess(int queryingUid, String visibleAuthority) {
+        try {
+            ActivityThread.getPackageManager().grantImplicitAccess(queryingUid, visibleAuthority);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     // Some of the flags don't affect the query result, but let's be conservative and cache
     // each combination of flags separately.
 
diff --git a/core/java/android/hardware/camera2/impl/FrameNumberTracker.java b/core/java/android/hardware/camera2/impl/FrameNumberTracker.java
index 27f8a61..7b6a457 100644
--- a/core/java/android/hardware/camera2/impl/FrameNumberTracker.java
+++ b/core/java/android/hardware/camera2/impl/FrameNumberTracker.java
@@ -37,12 +37,16 @@
     /** the completed frame number for each type of capture results */
     private long[] mCompletedFrameNumber = new long[CaptureRequest.REQUEST_TYPE_COUNT];
 
-    /** the skipped frame numbers that don't belong to each type of capture results */
-    private final LinkedList<Long>[] mSkippedOtherFrameNumbers =
+    /** the frame numbers that don't belong to each type of capture results and are yet to be seen
+     * through an updateTracker() call. Each list holds a list of frame numbers that should appear
+     * with request types other than that, to which the list corresponds.
+     */
+    private final LinkedList<Long>[] mPendingFrameNumbersWithOtherType =
             new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
 
-    /** the skipped frame numbers that belong to each type of capture results */
-    private final LinkedList<Long>[] mSkippedFrameNumbers =
+    /** the frame numbers that belong to each type of capture results which should appear, but
+     * haven't yet.*/
+    private final LinkedList<Long>[] mPendingFrameNumbers =
             new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
 
     /** frame number -> request type */
@@ -53,8 +57,8 @@
     public FrameNumberTracker() {
         for (int i = 0; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
             mCompletedFrameNumber[i] = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
-            mSkippedOtherFrameNumbers[i] = new LinkedList<Long>();
-            mSkippedFrameNumbers[i] = new LinkedList<Long>();
+            mPendingFrameNumbersWithOtherType[i] = new LinkedList<Long>();
+            mPendingFrameNumbers[i] = new LinkedList<Long>();
         }
     }
 
@@ -66,29 +70,29 @@
             int requestType = (int) pair.getValue();
             Boolean removeError = false;
             if (errorFrameNumber == mCompletedFrameNumber[requestType] + 1) {
-                mCompletedFrameNumber[requestType] = errorFrameNumber;
                 removeError = true;
+            }
+            // The error frame number could have also either been in the pending list or one of the
+            // 'other' pending lists.
+            if (!mPendingFrameNumbers[requestType].isEmpty()) {
+                if (errorFrameNumber == mPendingFrameNumbers[requestType].element()) {
+                    mPendingFrameNumbers[requestType].remove();
+                    removeError = true;
+                }
             } else {
-                if (!mSkippedFrameNumbers[requestType].isEmpty()) {
-                    if (errorFrameNumber == mSkippedFrameNumbers[requestType].element()) {
-                        mCompletedFrameNumber[requestType] = errorFrameNumber;
-                        mSkippedFrameNumbers[requestType].remove();
+                for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
+                    int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT;
+                    if (!mPendingFrameNumbersWithOtherType[otherType].isEmpty() && errorFrameNumber
+                            == mPendingFrameNumbersWithOtherType[otherType].element()) {
+                        mPendingFrameNumbersWithOtherType[otherType].remove();
                         removeError = true;
-                    }
-                } else {
-                    for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
-                        int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT;
-                        if (!mSkippedOtherFrameNumbers[otherType].isEmpty() && errorFrameNumber
-                                == mSkippedOtherFrameNumbers[otherType].element()) {
-                            mCompletedFrameNumber[requestType] = errorFrameNumber;
-                            mSkippedOtherFrameNumbers[otherType].remove();
-                            removeError = true;
-                            break;
-                        }
+                        break;
                     }
                 }
             }
             if (removeError) {
+                mCompletedFrameNumber[requestType] = errorFrameNumber;
+                mPartialResults.remove(errorFrameNumber);
                 iter.remove();
             }
         }
@@ -182,7 +186,7 @@
      * It validates that all previous frames of the same category have arrived.
      *
      * If there is a gap since previous frame number of the same category, assume the frames in
-     * the gap are other categories and store them in the skipped frame number queue to check
+     * the gap are other categories and store them in the pending frame number queue to check
      * against when frames of those categories arrive.
      */
     private void updateCompletedFrameNumber(long frameNumber,
@@ -199,25 +203,29 @@
         if (frameNumber < maxOtherFrameNumberSeen) {
             // if frame number is smaller than completed frame numbers of other categories,
             // it must be:
-            // - the head of mSkippedFrameNumbers for this category, or
-            // - in one of other mSkippedOtherFrameNumbers
-            if (!mSkippedFrameNumbers[requestType].isEmpty()) {
-                // frame number must be head of current type of mSkippedFrameNumbers if
-                // mSkippedFrameNumbers isn't empty.
-                if (frameNumber < mSkippedFrameNumbers[requestType].element()) {
+            // - the head of mPendingFrameNumbers for this category, or
+            // - in one of other mPendingFrameNumbersWithOtherType
+            if (!mPendingFrameNumbers[requestType].isEmpty()) {
+                // frame number must be head of current type of mPendingFrameNumbers if
+                // mPendingFrameNumbers isn't empty.
+                Long pendingFrameNumberSameType = mPendingFrameNumbers[requestType].element();
+                if (frameNumber == pendingFrameNumberSameType) {
+                    // frame number matches the head of the pending frame number queue.
+                    // Do this before the inequality checks since this is likely to be the common
+                    // case.
+                    mPendingFrameNumbers[requestType].remove();
+                } else if (frameNumber < pendingFrameNumberSameType) {
                     throw new IllegalArgumentException("frame number " + frameNumber
                             + " is a repeat");
-                } else if (frameNumber > mSkippedFrameNumbers[requestType].element()) {
+                } else {
                     throw new IllegalArgumentException("frame number " + frameNumber
                             + " comes out of order. Expecting "
-                            + mSkippedFrameNumbers[requestType].element());
+                            + pendingFrameNumberSameType);
                 }
-                // frame number matches the head of the skipped frame number queue.
-                mSkippedFrameNumbers[requestType].remove();
             } else {
-                // frame number must be in one of the other mSkippedOtherFrameNumbers.
-                int index1 = mSkippedOtherFrameNumbers[otherType1].indexOf(frameNumber);
-                int index2 = mSkippedOtherFrameNumbers[otherType2].indexOf(frameNumber);
+                // frame number must be in one of the other mPendingFrameNumbersWithOtherType.
+                int index1 = mPendingFrameNumbersWithOtherType[otherType1].indexOf(frameNumber);
+                int index2 = mPendingFrameNumbersWithOtherType[otherType2].indexOf(frameNumber);
                 boolean inSkippedOther1 = index1 != -1;
                 boolean inSkippedOther2 = index2 != -1;
                 if (!(inSkippedOther1 ^ inSkippedOther2)) {
@@ -225,33 +233,39 @@
                             + " is a repeat or invalid");
                 }
 
-                // We know the category of frame numbers in skippedOtherFrameNumbers leading up
-                // to the current frame number. Move them into the correct skippedFrameNumbers.
+                // We know the category of frame numbers in pendingFrameNumbersWithOtherType leading
+                // up to the current frame number. The destination is the type which isn't the
+                // requestType* and isn't the src. Move them into the correct pendingFrameNumbers.
+                // * : This is since frameNumber is the first frame of requestType that we've
+                // received in the 'others' list, since for each request type frames come in order.
+                // All the frames before frameNumber are of the same type. They're not of
+                // 'requestType', neither of the type of the 'others' list they were found in. The
+                // remaining option is the 3rd type.
                 LinkedList<Long> srcList, dstList;
                 int index;
                 if (inSkippedOther1) {
-                    srcList = mSkippedOtherFrameNumbers[otherType1];
-                    dstList = mSkippedFrameNumbers[otherType2];
+                    srcList = mPendingFrameNumbersWithOtherType[otherType1];
+                    dstList = mPendingFrameNumbers[otherType2];
                     index = index1;
                 } else {
-                    srcList = mSkippedOtherFrameNumbers[otherType2];
-                    dstList = mSkippedFrameNumbers[otherType1];
+                    srcList = mPendingFrameNumbersWithOtherType[otherType2];
+                    dstList = mPendingFrameNumbers[otherType1];
                     index = index2;
                 }
                 for (int i = 0; i < index; i++) {
                     dstList.add(srcList.removeFirst());
                 }
 
-                // Remove current frame number from skippedOtherFrameNumbers
+                // Remove current frame number from pendingFrameNumbersWithOtherType
                 srcList.remove();
             }
         } else {
             // there is a gap of unseen frame numbers which should belong to the other
-            // 2 categories. Put all the skipped frame numbers in the queue.
+            // 2 categories. Put all the pending frame numbers in the queue.
             for (long i =
                     Math.max(maxOtherFrameNumberSeen, mCompletedFrameNumber[requestType]) + 1;
                     i < frameNumber; i++) {
-                mSkippedOtherFrameNumbers[requestType].add(i);
+                mPendingFrameNumbersWithOtherType[requestType].add(i);
             }
         }
 
diff --git a/core/java/android/os/FileBridge.java b/core/java/android/os/FileBridge.java
index 21fd819..ab5637c 100644
--- a/core/java/android/os/FileBridge.java
+++ b/core/java/android/os/FileBridge.java
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import static android.system.OsConstants.AF_UNIX;
 import static android.system.OsConstants.SOCK_STREAM;
 
 import android.system.ErrnoException;
@@ -58,17 +57,19 @@
     /** CMD_CLOSE */
     private static final int CMD_CLOSE = 3;
 
-    private FileDescriptor mTarget;
+    private ParcelFileDescriptor mTarget;
 
-    private final FileDescriptor mServer = new FileDescriptor();
-    private final FileDescriptor mClient = new FileDescriptor();
+    private ParcelFileDescriptor mServer;
+    private ParcelFileDescriptor mClient;
 
     private volatile boolean mClosed;
 
     public FileBridge() {
         try {
-            Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mServer, mClient);
-        } catch (ErrnoException e) {
+            ParcelFileDescriptor[] fds = ParcelFileDescriptor.createSocketPair(SOCK_STREAM);
+            mServer = fds[0];
+            mClient = fds[1];
+        } catch (IOException e) {
             throw new RuntimeException("Failed to create bridge");
         }
     }
@@ -80,15 +81,14 @@
     public void forceClose() {
         IoUtils.closeQuietly(mTarget);
         IoUtils.closeQuietly(mServer);
-        IoUtils.closeQuietly(mClient);
         mClosed = true;
     }
 
-    public void setTargetFile(FileDescriptor target) {
+    public void setTargetFile(ParcelFileDescriptor target) {
         mTarget = target;
     }
 
-    public FileDescriptor getClientSocket() {
+    public ParcelFileDescriptor getClientSocket() {
         return mClient;
     }
 
@@ -96,32 +96,33 @@
     public void run() {
         final byte[] temp = new byte[8192];
         try {
-            while (IoBridge.read(mServer, temp, 0, MSG_LENGTH) == MSG_LENGTH) {
+            while (IoBridge.read(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH) == MSG_LENGTH) {
                 final int cmd = Memory.peekInt(temp, 0, ByteOrder.BIG_ENDIAN);
                 if (cmd == CMD_WRITE) {
                     // Shuttle data into local file
                     int len = Memory.peekInt(temp, 4, ByteOrder.BIG_ENDIAN);
                     while (len > 0) {
-                        int n = IoBridge.read(mServer, temp, 0, Math.min(temp.length, len));
+                        int n = IoBridge.read(mServer.getFileDescriptor(), temp, 0,
+                                              Math.min(temp.length, len));
                         if (n == -1) {
                             throw new IOException(
                                     "Unexpected EOF; still expected " + len + " bytes");
                         }
-                        IoBridge.write(mTarget, temp, 0, n);
+                        IoBridge.write(mTarget.getFileDescriptor(), temp, 0, n);
                         len -= n;
                     }
 
                 } else if (cmd == CMD_FSYNC) {
                     // Sync and echo back to confirm
-                    Os.fsync(mTarget);
-                    IoBridge.write(mServer, temp, 0, MSG_LENGTH);
+                    Os.fsync(mTarget.getFileDescriptor());
+                    IoBridge.write(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH);
 
                 } else if (cmd == CMD_CLOSE) {
                     // Close and echo back to confirm
-                    Os.fsync(mTarget);
-                    Os.close(mTarget);
+                    Os.fsync(mTarget.getFileDescriptor());
+                    mTarget.close();
                     mClosed = true;
-                    IoBridge.write(mServer, temp, 0, MSG_LENGTH);
+                    IoBridge.write(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH);
                     break;
                 }
             }
@@ -143,17 +144,11 @@
             mClient = clientPfd.getFileDescriptor();
         }
 
-        public FileBridgeOutputStream(FileDescriptor client) {
-            mClientPfd = null;
-            mClient = client;
-        }
-
         @Override
         public void close() throws IOException {
             try {
                 writeCommandAndBlock(CMD_CLOSE, "close()");
             } finally {
-                IoBridge.closeAndSignalBlockedThreads(mClient);
                 IoUtils.closeQuietly(mClientPfd);
             }
         }
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 7b82b1a..fe70a88 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -642,11 +642,11 @@
      * {@link #dataPosition}.  This is used to validate that the marshalled
      * transaction is intended for the target interface.
      */
-    public final void writeInterfaceToken(String interfaceName) {
+    public final void writeInterfaceToken(@NonNull String interfaceName) {
         nativeWriteInterfaceToken(mNativePtr, interfaceName);
     }
 
-    public final void enforceInterface(String interfaceName) {
+    public final void enforceInterface(@NonNull String interfaceName) {
         nativeEnforceInterface(mNativePtr, interfaceName);
     }
 
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 095882e..60f1b44 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -36,7 +36,6 @@
 import com.android.server.NetworkManagementSocketTagger;
 
 import dalvik.system.RuntimeHooks;
-import dalvik.system.ThreadPrioritySetter;
 import dalvik.system.VMRuntime;
 
 import libcore.content.type.MimeMap;
@@ -208,7 +207,6 @@
      */
     public static void preForkInit() {
         if (DEBUG) Slog.d(TAG, "Entered preForkInit.");
-        RuntimeHooks.setThreadPrioritySetter(new RuntimeThreadPrioritySetter());
         RuntimeInit.enableDdms();
         // TODO(b/142019040#comment13): Decide whether to load the default instance eagerly, i.e.
         // MimeMap.setDefault(DefaultMimeMapFactory.create());
@@ -221,35 +219,6 @@
         MimeMap.setDefaultSupplier(DefaultMimeMapFactory::create);
     }
 
-    private static class RuntimeThreadPrioritySetter implements ThreadPrioritySetter {
-        // Should remain consistent with kNiceValues[] in system/libartpalette/palette_android.cc
-        private static final int[] NICE_VALUES = {
-            Process.THREAD_PRIORITY_LOWEST,  // 1 (MIN_PRIORITY)
-            Process.THREAD_PRIORITY_BACKGROUND + 6,
-            Process.THREAD_PRIORITY_BACKGROUND + 3,
-            Process.THREAD_PRIORITY_BACKGROUND,
-            Process.THREAD_PRIORITY_DEFAULT,  // 5 (NORM_PRIORITY)
-            Process.THREAD_PRIORITY_DEFAULT - 2,
-            Process.THREAD_PRIORITY_DEFAULT - 4,
-            Process.THREAD_PRIORITY_URGENT_DISPLAY + 3,
-            Process.THREAD_PRIORITY_URGENT_DISPLAY + 2,
-            Process.THREAD_PRIORITY_URGENT_DISPLAY  // 10 (MAX_PRIORITY)
-        };
-
-        @Override
-        public void setPriority(int nativeTid, int priority) {
-            // Check NICE_VALUES[] length first.
-            if (NICE_VALUES.length != (1 + Thread.MAX_PRIORITY - Thread.MIN_PRIORITY)) {
-                throw new AssertionError("Unexpected NICE_VALUES.length=" + NICE_VALUES.length);
-            }
-            // Priority should be in the range of MIN_PRIORITY (1) to MAX_PRIORITY (10).
-            if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
-                throw new IllegalArgumentException("Priority out of range: " + priority);
-            }
-            Process.setThreadPriority(nativeTid, NICE_VALUES[priority - Thread.MIN_PRIORITY]);
-        }
-    }
-
     @UnsupportedAppUsage
     protected static final void commonInit() {
         if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index f0f1b74..1968146 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -315,4 +315,9 @@
             cflags: ["-DANDROID_EXPERIMENTAL_MTE"],
         },
     },
+
+    // Workaround Clang LTO crash.
+    lto: {
+        never: true,
+    },
 }
diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h
index eeda275..ad8aeb2 100644
--- a/core/jni/core_jni_helpers.h
+++ b/core/jni/core_jni_helpers.h
@@ -90,6 +90,12 @@
     return res;
 }
 
+static inline jobject jniGetReferent(JNIEnv* env, jobject ref) {
+    jclass cls = FindClassOrDie(env, "java/lang/ref/Reference");
+    jmethodID get = GetMethodIDOrDie(env, cls, "get", "()Ljava/lang/Object;");
+    return env->CallObjectMethod(ref, get);
+}
+
 /**
  * Read the specified field from jobject, and convert to std::string.
  * If the field cannot be obtained, return defaultValue.
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index 11f6a91..542d26f 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -17,6 +17,9 @@
 roosa@google.com
 per-file usagestatsservice.proto, usagestatsservice_v2.proto = mwachens@google.com
 
+# Biometrics
+kchyn@google.com
+
 # Launcher
 hyunyoungs@google.com
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8656820..80f73f0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2682,6 +2682,14 @@
     <permission android:name="android.permission.SUGGEST_MANUAL_TIME_AND_ZONE"
         android:protectionLevel="signature" />
 
+    <!-- Allows applications like settings to manage configuration associated with automatic time
+         and time zone detection.
+         <p>Not for use by third-party applications.
+         @hide
+    -->
+    <permission android:name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION"
+        android:protectionLevel="signature|privileged" />
+
     <!-- ==================================================== -->
     <!-- Permissions related to changing status bar   -->
     <!-- ==================================================== -->
diff --git a/core/tests/coretests/src/android/os/FileBridgeTest.java b/core/tests/coretests/src/android/os/FileBridgeTest.java
index d4f6b1f..708bfa6 100644
--- a/core/tests/coretests/src/android/os/FileBridgeTest.java
+++ b/core/tests/coretests/src/android/os/FileBridgeTest.java
@@ -16,6 +16,9 @@
 
 package android.os;
 
+import static android.os.ParcelFileDescriptor.MODE_CREATE;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+
 import android.os.FileBridge.FileBridgeOutputStream;
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
@@ -25,7 +28,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.Random;
@@ -33,7 +35,7 @@
 public class FileBridgeTest extends AndroidTestCase {
 
     private File file;
-    private FileOutputStream fileOs;
+    private ParcelFileDescriptor outputFile;
     private FileBridge bridge;
     private FileBridgeOutputStream client;
 
@@ -44,17 +46,17 @@
         file = getContext().getFileStreamPath("meow.dat");
         file.delete();
 
-        fileOs = new FileOutputStream(file);
+        outputFile = ParcelFileDescriptor.open(file, MODE_CREATE | MODE_READ_WRITE);
 
         bridge = new FileBridge();
-        bridge.setTargetFile(fileOs.getFD());
+        bridge.setTargetFile(outputFile);
         bridge.start();
         client = new FileBridgeOutputStream(bridge.getClientSocket());
     }
 
     @Override
     protected void tearDown() throws Exception {
-        fileOs.close();
+        outputFile.close();
         file.delete();
     }
 
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 672b428..0a9e50e 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -427,6 +427,8 @@
         <permission name="android.permission.CAPTURE_AUDIO_OUTPUT" />
         <!-- Permissions required for CTS test - AdbManagerTest -->
         <permission name="android.permission.MANAGE_DEBUGGING" />
+        <!-- Permissions required for CTS test - TimeManagerTest -->
+        <permission name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index a362bd2..667a751 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -139,7 +139,7 @@
     mAnimationContext->destroy();
 }
 
-static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) {
+static void setBufferCount(ANativeWindow* window) {
     int query_value;
     int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
     if (err != 0 || query_value < 0) {
@@ -148,7 +148,9 @@
     }
     auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
 
-    int bufferCount = min_undequeued_buffers + 2 + extraBuffers;
+    // We only need to set min_undequeued + 2 because the renderahead amount was already factored into the
+    // query for min_undequeued
+    int bufferCount = min_undequeued_buffers + 2;
     native_window_set_buffer_count(window, bufferCount);
 }
 
@@ -179,7 +181,8 @@
             mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior);
 
     if (mNativeSurface && !mNativeSurface->didSetExtraBuffers()) {
-        setBufferCount(mNativeSurface->getNativeWindow(), mRenderAheadCapacity);
+        setBufferCount(mNativeSurface->getNativeWindow());
+
     }
 
     mFrameNumber = -1;
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index d35bc41..d02b496 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -372,7 +372,7 @@
                     AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) {
                 startLocalPlayer();
             }
-        } else if (mAllowRemote && (mRemotePlayer != null)) {
+        } else if (mAllowRemote && (mRemotePlayer != null) && (mUri != null)) {
             final Uri canonicalUri = mUri.getCanonicalUri();
             final boolean looping;
             final float volume;
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 8deb0c4..9deeb8f 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -34,6 +34,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
+import android.database.StaleDataException;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -492,7 +493,12 @@
     public Uri getRingtoneUri(int position) {
         // use cursor directly instead of requerying it, which could easily
         // cause position to shuffle.
-        if (mCursor == null || !mCursor.moveToPosition(position)) {
+        try {
+            if (mCursor == null || !mCursor.moveToPosition(position)) {
+                return null;
+            }
+        } catch (StaleDataException | IllegalStateException e) {
+            Log.e(TAG, "Unexpected Exception has been catched.", e);
             return null;
         }
 
@@ -1130,11 +1136,13 @@
 
             // Try finding the scanned ringtone
             final String filename = getDefaultRingtoneFilename(type);
+            final String whichAudio = getQueryStringForType(type);
+            final String where = MediaColumns.DISPLAY_NAME + "=? AND " + whichAudio + "=?";
             final Uri baseUri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
             try (Cursor cursor = context.getContentResolver().query(baseUri,
                     new String[] { MediaColumns._ID },
-                    MediaColumns.DISPLAY_NAME + "=?",
-                    new String[] { filename }, null)) {
+                    where,
+                    new String[] { filename, "1" }, null)) {
                 if (cursor.moveToFirst()) {
                     final Uri ringtoneUri = context.getContentResolver().canonicalizeOrElse(
                             ContentUris.withAppendedId(baseUri, cursor.getLong(0)));
@@ -1162,4 +1170,13 @@
             default: throw new IllegalArgumentException();
         }
     }
+
+    private static String getQueryStringForType(int type) {
+        switch (type) {
+            case TYPE_RINGTONE: return MediaStore.Audio.AudioColumns.IS_RINGTONE;
+            case TYPE_NOTIFICATION: return MediaStore.Audio.AudioColumns.IS_NOTIFICATION;
+            case TYPE_ALARM: return MediaStore.Audio.AudioColumns.IS_ALARM;
+            default: throw new IllegalArgumentException();
+        }
+    }
 }
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index d2294b3..d346670 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -96,6 +96,11 @@
         "-Wunused",
         "-Wunreachable-code",
     ],
+
+    // Workaround Clang LTO crash.
+    lto: {
+        never: true,
+    },
 }
 
 cc_library_shared {
diff --git a/media/jni/audioeffect/Android.bp b/media/jni/audioeffect/Android.bp
index 5ba5c01..40e4c54 100644
--- a/media/jni/audioeffect/Android.bp
+++ b/media/jni/audioeffect/Android.bp
@@ -28,4 +28,9 @@
         "-Wunused",
         "-Wunreachable-code",
     ],
+
+    // Workaround Clang LTO crash.
+    lto: {
+        never: true,
+    },
 }
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index d6c74b1e..8a36837 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -8771,6 +8771,7 @@
     method public void onPhyUpdate(android.bluetooth.BluetoothGatt, int, int, int);
     method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int);
     method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int);
+    method public void onServiceChanged(@NonNull android.bluetooth.BluetoothGatt);
     method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
   }
 
@@ -35030,7 +35031,7 @@
     method public int dataCapacity();
     method public int dataPosition();
     method public int dataSize();
-    method public void enforceInterface(String);
+    method public void enforceInterface(@NonNull String);
     method public boolean hasFileDescriptors();
     method public byte[] marshall();
     method @NonNull public static android.os.Parcel obtain();
@@ -35101,7 +35102,7 @@
     method public void writeFloatArray(@Nullable float[]);
     method public void writeInt(int);
     method public void writeIntArray(@Nullable int[]);
-    method public void writeInterfaceToken(String);
+    method public void writeInterfaceToken(@NonNull String);
     method public void writeList(@Nullable java.util.List);
     method public void writeLong(long);
     method public void writeLongArray(@Nullable long[]);
@@ -45112,7 +45113,7 @@
     method public long getNci();
     method @IntRange(from=0, to=3279165) public int getNrarfcn();
     method @IntRange(from=0, to=1007) public int getPci();
-    method @IntRange(from=0, to=65535) public int getTac();
+    method @IntRange(from=0, to=16777215) public int getTac();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR;
   }
@@ -45206,9 +45207,9 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoWcdma> CREATOR;
   }
 
-  public abstract class CellLocation {
-    ctor public CellLocation();
-    method public static android.telephony.CellLocation getEmpty();
+  @Deprecated public abstract class CellLocation {
+    ctor @Deprecated public CellLocation();
+    method @Deprecated public static android.telephony.CellLocation getEmpty();
     method @Deprecated public static void requestLocationUpdate();
   }
 
@@ -46716,19 +46717,19 @@
 
 package android.telephony.cdma {
 
-  public class CdmaCellLocation extends android.telephony.CellLocation {
-    ctor public CdmaCellLocation();
-    ctor public CdmaCellLocation(android.os.Bundle);
-    method public static double convertQuartSecToDecDegrees(int);
-    method public void fillInNotifierBundle(android.os.Bundle);
-    method public int getBaseStationId();
-    method public int getBaseStationLatitude();
-    method public int getBaseStationLongitude();
-    method public int getNetworkId();
-    method public int getSystemId();
-    method public void setCellLocationData(int, int, int);
-    method public void setCellLocationData(int, int, int, int, int);
-    method public void setStateInvalid();
+  @Deprecated public class CdmaCellLocation extends android.telephony.CellLocation {
+    ctor @Deprecated public CdmaCellLocation();
+    ctor @Deprecated public CdmaCellLocation(android.os.Bundle);
+    method @Deprecated public static double convertQuartSecToDecDegrees(int);
+    method @Deprecated public void fillInNotifierBundle(android.os.Bundle);
+    method @Deprecated public int getBaseStationId();
+    method @Deprecated public int getBaseStationLatitude();
+    method @Deprecated public int getBaseStationLongitude();
+    method @Deprecated public int getNetworkId();
+    method @Deprecated public int getSystemId();
+    method @Deprecated public void setCellLocationData(int, int, int);
+    method @Deprecated public void setCellLocationData(int, int, int, int, int);
+    method @Deprecated public void setStateInvalid();
   }
 
 }
@@ -46928,15 +46929,15 @@
 
 package android.telephony.gsm {
 
-  public class GsmCellLocation extends android.telephony.CellLocation {
-    ctor public GsmCellLocation();
-    ctor public GsmCellLocation(android.os.Bundle);
-    method public void fillInNotifierBundle(android.os.Bundle);
-    method public int getCid();
-    method public int getLac();
-    method public int getPsc();
-    method public void setLacAndCid(int, int);
-    method public void setStateInvalid();
+  @Deprecated public class GsmCellLocation extends android.telephony.CellLocation {
+    ctor @Deprecated public GsmCellLocation();
+    ctor @Deprecated public GsmCellLocation(android.os.Bundle);
+    method @Deprecated public void fillInNotifierBundle(android.os.Bundle);
+    method @Deprecated public int getCid();
+    method @Deprecated public int getLac();
+    method @Deprecated public int getPsc();
+    method @Deprecated public void setLacAndCid(int, int);
+    method @Deprecated public void setStateInvalid();
   }
 
   @Deprecated public final class SmsManager {
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index 419d401..b67c22c 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -10070,6 +10070,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index f5f58ef..a927997 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -326,6 +326,9 @@
     <!-- Permission needed for CTS test - DisplayTest -->
     <uses-permission android:name="android.permission.OVERRIDE_DISPLAY_MODE_REQUESTS" />
 
+    <!-- Permission needed for CTS test - TimeManagerTest -->
+    <uses-permission android:name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" />
+
     <application android:label="@string/app_label"
                 android:theme="@android:style/Theme.DeviceDefault.DayNight"
                 android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index f6c2ee2..02815a57 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -503,14 +503,14 @@
             }
 
             if (msg.what != MSG_SERVICE_COMMAND) {
-                // Sanity check.
+                // Confidence check.
                 Log.e(TAG, "Invalid message type: " + msg.what);
                 return;
             }
 
             // At this point it's handling onStartCommand(), with the intent passed as an Extra.
             if (!(msg.obj instanceof Intent)) {
-                // Sanity check.
+                // Confidence check.
                 Log.wtf(TAG, "handleMessage(): invalid msg.obj type: " + msg.obj);
                 return;
             }
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index b95092a..b8cfa1e 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -561,7 +561,7 @@
             // Clear properties
             mContext.getSharedPreferences(PREFS_BUGREPORT, Context.MODE_PRIVATE)
                     .edit().clear().commit();
-            // Sanity check...
+            // Confidence check...
             assertEquals("Did not reset properties", STATE_UNKNOWN,
                     getWarningState(mContext, STATE_UNKNOWN));
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 18a7add..cf83603 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -284,6 +284,9 @@
         mNetworkToIconLookup.put(toDisplayIconKey(
                 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE),
                 TelephonyIcons.NR_5G_PLUS);
+        mNetworkToIconLookup.put(toIconKey(
+                TelephonyManager.NETWORK_TYPE_NR),
+                TelephonyIcons.NR_5G);
     }
 
     private String getIconKey() {
@@ -306,9 +309,9 @@
             case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO:
                 return toIconKey(TelephonyManager.NETWORK_TYPE_LTE) + "_CA_Plus";
             case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA:
-                return "5G";
+                return toIconKey(TelephonyManager.NETWORK_TYPE_NR);
             case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE:
-                return "5G_Plus";
+                return toIconKey(TelephonyManager.NETWORK_TYPE_NR) + "_Plus";
             default:
                 return "unsupported";
         }
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index 33b9d00..da5f25b 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -28,6 +28,7 @@
 import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
 import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
 import android.net.netlink.NetlinkSocket;
+import android.net.netlink.StructNfGenMsg;
 import android.net.netlink.StructNlMsgHdr;
 import android.net.util.SharedLog;
 import android.net.util.SocketUtils;
@@ -41,11 +42,12 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.FileDescriptor;
-import java.io.InterruptedIOException;
 import java.io.IOException;
+import java.io.InterruptedIOException;
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.NoSuchElementException;
 
@@ -66,11 +68,12 @@
     private static final String NO_IPV4_ADDRESS = "";
     private static final String NO_IPV4_GATEWAY = "";
     // Reference kernel/uapi/linux/netfilter/nfnetlink_compat.h
-    private static final int NF_NETLINK_CONNTRACK_NEW = 1;
-    private static final int NF_NETLINK_CONNTRACK_UPDATE = 2;
-    private static final int NF_NETLINK_CONNTRACK_DESTROY = 4;
+    public static final int NF_NETLINK_CONNTRACK_NEW = 1;
+    public static final int NF_NETLINK_CONNTRACK_UPDATE = 2;
+    public static final int NF_NETLINK_CONNTRACK_DESTROY = 4;
     // Reference libnetfilter_conntrack/linux_nfnetlink_conntrack.h
     public static final short NFNL_SUBSYS_CTNETLINK = 1;
+    public static final short IPCTNL_MSG_CT_NEW = 0;
     public static final short IPCTNL_MSG_CT_GET = 1;
 
     private final long NETLINK_MESSAGE_TIMEOUT_MS = 500;
@@ -237,7 +240,7 @@
                 NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
         if (h1 == null) return false;
 
-        sendNetlinkMessage(h1, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
+        sendIpv4NfGenMsg(h1, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
                            (short) (NLM_F_REQUEST | NLM_F_DUMP));
 
         final NativeHandle h2 = mDeps.createConntrackSocket(
@@ -267,16 +270,23 @@
     }
 
     @VisibleForTesting
-    public void sendNetlinkMessage(@NonNull NativeHandle handle, short type, short flags) {
-        final int length = StructNlMsgHdr.STRUCT_SIZE;
+    public void sendIpv4NfGenMsg(@NonNull NativeHandle handle, short type, short flags) {
+        final int length = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE;
         final byte[] msg = new byte[length];
-        final StructNlMsgHdr nlh = new StructNlMsgHdr();
         final ByteBuffer byteBuffer = ByteBuffer.wrap(msg);
+        byteBuffer.order(ByteOrder.nativeOrder());
+
+        final StructNlMsgHdr nlh = new StructNlMsgHdr();
         nlh.nlmsg_len = length;
         nlh.nlmsg_type = type;
         nlh.nlmsg_flags = flags;
-        nlh.nlmsg_seq = 1;
+        nlh.nlmsg_seq = 0;
         nlh.pack(byteBuffer);
+
+        // Header needs to be added to buffer since a generic netlink request is being sent.
+        final StructNfGenMsg nfh = new StructNfGenMsg((byte) OsConstants.AF_INET);
+        nfh.pack(byteBuffer);
+
         try {
             NetlinkSocket.sendMessage(handle.getFileDescriptor(), msg, 0 /* offset */, length,
                                       NETLINK_MESSAGE_TIMEOUT_MS);
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 7dd5290..64d5025 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -2104,7 +2104,7 @@
     }
 
     private boolean hasCallingPermission(@NonNull String permission) {
-        return mContext.checkCallingPermission(permission) == PERMISSION_GRANTED;
+        return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
     }
 
     /** Unregister tethering event callback */
diff --git a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index 64be2d9..d206ea0 100644
--- a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -553,7 +553,6 @@
         TestNetworkManager tnm = mContext.getSystemService(TestNetworkManager.class);
         TestNetworkInterface iface = tnm.createTapInterface();
         Log.d(TAG, "Created test interface " + iface.getInterfaceName());
-        assertNotNull(NetworkInterface.getByName(iface.getInterfaceName()));
         return iface;
     }
 
diff --git a/packages/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java b/packages/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
new file mode 100644
index 0000000..57c28fc
--- /dev/null
+++ b/packages/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 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.networkstack.tethering;
+
+import static android.net.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE;
+import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP;
+import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
+
+import static com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_GET;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_NEW;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.NFNL_SUBSYS_CTNETLINK;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_DESTROY;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_NEW;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.netlink.StructNlMsgHdr;
+import android.net.util.SharedLog;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.NativeHandle;
+import android.system.Os;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConntrackSocketTest {
+    private static final long TIMEOUT = 500;
+
+    private HandlerThread mHandlerThread;
+    private Handler mHandler;
+    private final SharedLog mLog = new SharedLog("privileged-test");
+
+    private OffloadHardwareInterface mOffloadHw;
+    private OffloadHardwareInterface.Dependencies mDeps;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mHandlerThread = new HandlerThread(getClass().getSimpleName());
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+
+        // Looper must be prepared here since AndroidJUnitRunner runs tests on separate threads.
+        if (Looper.myLooper() == null) Looper.prepare();
+
+        mDeps = new OffloadHardwareInterface.Dependencies(mLog);
+        mOffloadHw = new OffloadHardwareInterface(mHandler, mLog, mDeps);
+    }
+
+    @Test
+    public void testIpv4ConntrackSocket() throws Exception {
+        // Set up server and connect.
+        final InetSocketAddress anyAddress = new InetSocketAddress(
+                InetAddress.getByName("127.0.0.1"), 0);
+        final ServerSocket serverSocket = new ServerSocket();
+        serverSocket.bind(anyAddress);
+        final SocketAddress theAddress = serverSocket.getLocalSocketAddress();
+
+        // Make a connection to the server.
+        final Socket socket = new Socket();
+        socket.connect(theAddress);
+        final Socket acceptedSocket = serverSocket.accept();
+
+        final NativeHandle handle = mDeps.createConntrackSocket(
+                NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
+        mOffloadHw.sendIpv4NfGenMsg(handle,
+                (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
+                (short) (NLM_F_REQUEST | NLM_F_DUMP));
+
+        boolean foundConntrackEntry = false;
+        ByteBuffer buffer = ByteBuffer.allocate(DEFAULT_RECV_BUFSIZE);
+        buffer.order(ByteOrder.nativeOrder());
+
+        try {
+            while (Os.read(handle.getFileDescriptor(), buffer) > 0) {
+                buffer.flip();
+
+                // TODO: ConntrackMessage should get a parse API like StructNlMsgHdr
+                // so we can confirm that the conntrack added is for the TCP connection above.
+                final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(buffer);
+                assertNotNull(nlmsghdr);
+
+                // As long as 1 conntrack entry is found test case will pass, even if it's not
+                // the from the TCP connection above.
+                if (nlmsghdr.nlmsg_type == ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW)) {
+                    foundConntrackEntry = true;
+                    break;
+                }
+            }
+        } finally {
+            socket.close();
+            serverSocket.close();
+        }
+        assertTrue("Did not receive any NFNL_SUBSYS_CTNETLINK/IPCTNL_MSG_CT_NEW message",
+                foundConntrackEntry);
+    }
+}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
index c543fad..38b19dd 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
@@ -17,8 +17,9 @@
 package com.android.networkstack.tethering;
 
 import static android.net.util.TetheringUtils.uint16;
-import static android.system.OsConstants.SOCK_STREAM;
+import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.SOCK_STREAM;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -35,14 +36,15 @@
 import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
 import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
 import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
+import android.net.netlink.StructNfGenMsg;
 import android.net.netlink.StructNlMsgHdr;
 import android.net.util.SharedLog;
 import android.os.Handler;
 import android.os.NativeHandle;
 import android.os.test.TestLooper;
 import android.system.ErrnoException;
-import android.system.OsConstants;
 import android.system.Os;
+import android.system.OsConstants;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -55,8 +57,8 @@
 import org.mockito.MockitoAnnotations;
 
 import java.io.FileDescriptor;
-import java.io.OutputStream;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.ArrayList;
 
 @RunWith(AndroidJUnit4.class)
@@ -218,7 +220,7 @@
     }
 
     @Test
-    public void testNetlinkMessage() throws Exception {
+    public void testSendIpv4NfGenMsg() throws Exception {
         FileDescriptor writeSocket = new FileDescriptor();
         FileDescriptor readSocket = new FileDescriptor();
         try {
@@ -229,17 +231,25 @@
         }
         when(mNativeHandle.getFileDescriptor()).thenReturn(writeSocket);
 
-        mOffloadHw.sendNetlinkMessage(mNativeHandle, TEST_TYPE, TEST_FLAGS);
+        mOffloadHw.sendIpv4NfGenMsg(mNativeHandle, TEST_TYPE, TEST_FLAGS);
 
-        ByteBuffer buffer = ByteBuffer.allocate(StructNlMsgHdr.STRUCT_SIZE);
+        ByteBuffer buffer = ByteBuffer.allocate(9823);  // Arbitrary value > expectedLen.
+        buffer.order(ByteOrder.nativeOrder());
+
         int read = Os.read(readSocket, buffer);
+        final int expectedLen = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE;
+        assertEquals(expectedLen, read);
 
         buffer.flip();
-        assertEquals(StructNlMsgHdr.STRUCT_SIZE, buffer.getInt());
+        assertEquals(expectedLen, buffer.getInt());
         assertEquals(TEST_TYPE, buffer.getShort());
         assertEquals(TEST_FLAGS, buffer.getShort());
-        assertEquals(1 /* seq */, buffer.getInt());
+        assertEquals(0 /* seq */, buffer.getInt());
         assertEquals(0 /* pid */, buffer.getInt());
+        assertEquals(AF_INET, buffer.get());             // nfgen_family
+        assertEquals(0 /* error */, buffer.get());       // version
+        assertEquals(0 /* error */, buffer.getShort());  // res_id
+        assertEquals(expectedLen, buffer.position());
     }
 
     private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index ff8c628..7cdd3b3 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -284,10 +284,12 @@
         @Override
         public int handleFailedAttempt() {
             final int lockoutMode = getLockoutMode();
-            if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
-                mPerformanceStats.permanentLockout++;
-            } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
-                mPerformanceStats.lockout++;
+            if (mPerformanceStats != null) {
+                if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
+                    mPerformanceStats.permanentLockout++;
+                } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
+                    mPerformanceStats.lockout++;
+                }
             }
 
             // Failing multiple times will continue to push out the lockout time
@@ -730,10 +732,12 @@
         if (client != null && client.onAuthenticated(identifier, authenticated, token)) {
             removeClient(client);
         }
-        if (authenticated) {
-            mPerformanceStats.accept++;
-        } else {
-            mPerformanceStats.reject++;
+        if (mPerformanceStats != null) {
+            if (authenticated) {
+                mPerformanceStats.accept++;
+            } else {
+                mPerformanceStats.reject++;
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index e12cb8f..f116a24 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -352,6 +352,11 @@
     public abstract boolean destroyCeSnapshotsNotSpecified(int userId, int[] retainRollbackIds);
 
     /**
+     * Inform apexd that the boot has completed.
+     */
+    public abstract void markBootCompleted();
+
+    /**
      * Dumps various state information to the provided {@link PrintWriter} object.
      *
      * @param pw the {@link PrintWriter} object to send information to.
@@ -883,6 +888,15 @@
             }
         }
 
+        @Override
+        public void markBootCompleted() {
+            try {
+                waitForApexService().markBootCompleted();
+            } catch (RemoteException re) {
+                Slog.e(TAG, "Unable to contact apexservice", re);
+            }
+        }
+
         /**
          * Dump information about the packages contained in a particular cache
          * @param packagesCache the cache to print information about.
@@ -1130,6 +1144,11 @@
         }
 
         @Override
+        public void markBootCompleted() {
+            // No-op
+        }
+
+        @Override
         void dump(PrintWriter pw, String packageName) {
             // No-op
         }
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index c3c2e5e..069a00f 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -547,9 +547,9 @@
         final boolean newIsForceQueryable =
                 mForceQueryable.contains(newPkgSetting.appId)
                         /* shared user that is already force queryable */
-                        || newPkg.isForceQueryable()
-                        || newPkgSetting.forceQueryableOverride
+                        || newPkgSetting.forceQueryableOverride /* adb override */
                         || (newPkgSetting.isSystem() && (mSystemAppsQueryable
+                        || newPkg.isForceQueryable()
                         || ArrayUtils.contains(mForceQueryableByDevicePackageNames,
                         newPkg.getPackageName())));
         if (newIsForceQueryable
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 994cec2..90d9834 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -943,6 +943,23 @@
         }
     }
 
+    private ParcelFileDescriptor openTargetInternal(String path, int flags, int mode)
+            throws IOException, ErrnoException {
+        // TODO: this should delegate to DCS so the system process avoids
+        // holding open FDs into containers.
+        final FileDescriptor fd = Os.open(path, flags, mode);
+        return new ParcelFileDescriptor(fd);
+    }
+
+    private ParcelFileDescriptor createRevocableFdInternal(RevocableFileDescriptor fd,
+            ParcelFileDescriptor pfd) throws IOException {
+        int releasedFdInt = pfd.detachFd();
+        FileDescriptor releasedFd = new FileDescriptor();
+        releasedFd.setInt$(releasedFdInt);
+        fd.init(mContext, releasedFd);
+        return fd.getRevocableFileDescriptor();
+    }
+
     private ParcelFileDescriptor doWriteInternal(String name, long offsetBytes, long lengthBytes,
             ParcelFileDescriptor incomingFd) throws IOException {
         // Quick sanity check of state, and allocate a pipe for ourselves. We
@@ -975,21 +992,20 @@
                 Binder.restoreCallingIdentity(identity);
             }
 
-            // TODO: this should delegate to DCS so the system process avoids
-            // holding open FDs into containers.
-            final FileDescriptor targetFd = Os.open(target.getAbsolutePath(),
+            ParcelFileDescriptor targetPfd = openTargetInternal(target.getAbsolutePath(),
                     O_CREAT | O_WRONLY, 0644);
             Os.chmod(target.getAbsolutePath(), 0644);
 
             // If caller specified a total length, allocate it for them. Free up
             // cache space to grow, if needed.
             if (stageDir != null && lengthBytes > 0) {
-                mContext.getSystemService(StorageManager.class).allocateBytes(targetFd, lengthBytes,
+                mContext.getSystemService(StorageManager.class).allocateBytes(
+                        targetPfd.getFileDescriptor(), lengthBytes,
                         PackageHelper.translateAllocateFlags(params.installFlags));
             }
 
             if (offsetBytes > 0) {
-                Os.lseek(targetFd, offsetBytes, OsConstants.SEEK_SET);
+                Os.lseek(targetPfd.getFileDescriptor(), offsetBytes, OsConstants.SEEK_SET);
             }
 
             if (incomingFd != null) {
@@ -999,8 +1015,9 @@
                 // inserted above to hold the session active.
                 try {
                     final Int64Ref last = new Int64Ref(0);
-                    FileUtils.copy(incomingFd.getFileDescriptor(), targetFd, lengthBytes, null,
-                            Runnable::run, (long progress) -> {
+                    FileUtils.copy(incomingFd.getFileDescriptor(), targetPfd.getFileDescriptor(),
+                            lengthBytes, null, Runnable::run,
+                            (long progress) -> {
                                 if (params.sizeBytes > 0) {
                                     final long delta = progress - last.value;
                                     last.value = progress;
@@ -1011,7 +1028,7 @@
                                 }
                             });
                 } finally {
-                    IoUtils.closeQuietly(targetFd);
+                    IoUtils.closeQuietly(targetPfd);
                     IoUtils.closeQuietly(incomingFd);
 
                     // We're done here, so remove the "bridge" that was holding
@@ -1027,12 +1044,11 @@
                 }
                 return null;
             } else if (PackageInstaller.ENABLE_REVOCABLE_FD) {
-                fd.init(mContext, targetFd);
-                return fd.getRevocableFileDescriptor();
+                return createRevocableFdInternal(fd, targetPfd);
             } else {
-                bridge.setTargetFile(targetFd);
+                bridge.setTargetFile(targetPfd);
                 bridge.start();
-                return new ParcelFileDescriptor(bridge.getClientSocket());
+                return bridge.getClientSocket();
             }
 
         } catch (ErrnoException e) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 81748b2..4f0c707 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -280,6 +280,7 @@
 import android.os.storage.VolumeInfo;
 import android.os.storage.VolumeRecord;
 import android.permission.IPermissionManager;
+import android.provider.ContactsContract;
 import android.provider.DeviceConfig;
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
@@ -25400,6 +25401,32 @@
         }
     }
 
+    @Override
+    public void grantImplicitAccess(int recipientUid, String visibleAuthority) {
+        // This API is exposed temporarily to only the contacts provider. (b/158688602)
+        final int callingUid = Binder.getCallingUid();
+        ProviderInfo contactsProvider = resolveContentProviderInternal(
+                        ContactsContract.AUTHORITY, 0, UserHandle.getUserId(callingUid));
+        if (contactsProvider == null || contactsProvider.applicationInfo == null
+                || !UserHandle.isSameApp(contactsProvider.applicationInfo.uid, callingUid)) {
+            throw new SecurityException(callingUid + " is not allow to call grantImplicitAccess");
+        }
+        final int userId = UserHandle.getUserId(recipientUid);
+        final long token = Binder.clearCallingIdentity();
+        final ProviderInfo providerInfo;
+        try {
+            providerInfo = resolveContentProvider(visibleAuthority, 0 /*flags*/, userId);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        if (providerInfo == null) {
+            return;
+        }
+        int visibleUid = providerInfo.applicationInfo.uid;
+        mPmInternal.grantImplicitAccess(userId, null /*Intent*/, UserHandle.getAppId(recipientUid),
+                visibleUid, false);
+    }
+
     boolean canHaveOatDir(String packageName) {
         synchronized (mLock) {
             AndroidPackage p = mPackages.get(packageName);
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 09682c6..39b3203 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1377,7 +1377,7 @@
         long timeoutMs = -1;
         while ((opt = getNextOption()) != null) {
             switch (opt) {
-                case "--wait":
+                case "--wait-for-staged-ready":
                     waitForStagedSessionReady = true;
                     // If there is only one remaining argument, then it represents the sessionId, we
                     // shouldn't try to parse it as timeoutMs.
@@ -2865,7 +2865,7 @@
                     }
                     sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
                     break;
-                case "--wait":
+                case "--wait-for-staged-ready":
                     params.mWaitForStagedSessionReady = true;
                     try {
                         params.timeoutMs = Long.parseLong(peekNextArg());
@@ -3597,7 +3597,7 @@
         pw.println("       [--preload] [--instant] [--full] [--dont-kill]");
         pw.println("       [--enable-rollback]");
         pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
-        pw.println("       [--apex] [--wait TIMEOUT]");
+        pw.println("       [--apex] [--wait-for-staged-ready TIMEOUT]");
         pw.println("       [PATH [SPLIT...]|-]");
         pw.println("    Install an application.  Must provide the apk data to install, either as");
         pw.println("    file path(s) or '-' to read from stdin.  Options are:");
@@ -3625,8 +3625,8 @@
         pw.println("          3=device setup, 4=user request");
         pw.println("      --force-uuid: force install on to disk volume with given UUID");
         pw.println("      --apex: install an .apex file, not an .apk");
-        pw.println("      --wait: when performing staged install, wait TIMEOUT milliseconds");
-        pw.println("          for pre-reboot verification to complete. If TIMEOUT is not");
+        pw.println("      --wait-for-staged-ready: when performing staged install, wait TIMEOUT");
+        pw.println("          ms for pre-reboot verification to complete. If TIMEOUT is not");
         pw.println("          specified it will wait for " + DEFAULT_WAIT_MS + " milliseconds.");
         pw.println("");
         pw.println("  install-existing [--user USER_ID|all|current]");
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index e2bd1f1..0c96f59 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -164,6 +164,7 @@
         public void onBootPhase(int phase) {
             if (phase == SystemService.PHASE_BOOT_COMPLETED && sStagingManager != null) {
                 sStagingManager.markStagedSessionsAsSuccessful();
+                sStagingManager.markBootCompleted();
             }
         }
     }
@@ -179,6 +180,10 @@
         }
     }
 
+    private void markBootCompleted() {
+        mApexManager.markBootCompleted();
+    }
+
     /**
      * Validates the signature used to sign the container of the new apex package
      *
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index 2623094..37aedac 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -365,7 +365,25 @@
     }
 
     @Test
-    public void testForceQueryable_DoesntFilter() throws Exception {
+    public void testForceQueryable_SystemDoesntFilter() throws Exception {
+        final AppsFilter appsFilter =
+                new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
+        simulateAddBasicAndroid(appsFilter);
+        appsFilter.onSystemReady();
+
+        PackageSetting target = simulateAddPackage(appsFilter,
+                pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID,
+                setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
+        PackageSetting calling = simulateAddPackage(appsFilter,
+                pkg("com.some.other.package"), DUMMY_CALLING_APPID);
+
+        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+                SYSTEM_USER));
+    }
+
+
+    @Test
+    public void testForceQueryable_NonSystemFilters() throws Exception {
         final AppsFilter appsFilter =
                 new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
         simulateAddBasicAndroid(appsFilter);
@@ -376,7 +394,7 @@
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package"), DUMMY_CALLING_APPID);
 
-        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
                 SYSTEM_USER));
     }
 
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
index ac88560..ddc6084 100644
--- a/telephony/api/system-current.txt
+++ b/telephony/api/system-current.txt
@@ -660,6 +660,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index 05cef9b..3923c756 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -37,7 +37,7 @@
     private static final String TAG = "CellIdentityNr";
 
     private static final int MAX_PCI = 1007;
-    private static final int MAX_TAC = 65535;
+    private static final int MAX_TAC = 16777215; // 0xffffff
     private static final int MAX_NRARFCN = 3279165;
     private static final long MAX_NCI = 68719476735L;
 
@@ -65,7 +65,7 @@
     /**
      *
      * @param pci Physical Cell Id in range [0, 1007].
-     * @param tac 16-bit Tracking Area Code.
+     * @param tac 24-bit Tracking Area Code.
      * @param nrArfcn NR Absolute Radio Frequency Channel Number, in range [0, 3279165].
      * @param bands Bands used by the cell. Band number defined in 3GPP TS 38.101-1 and TS 38.101-2.
      * @param mccStr 3-digit Mobile Country Code in string format.
@@ -215,9 +215,9 @@
 
     /**
      * Get the tracking area code.
-     * @return a 16 bit integer or {@link CellInfo#UNAVAILABLE} if unknown.
+     * @return a 24 bit integer or {@link CellInfo#UNAVAILABLE} if unknown.
      */
-    @IntRange(from = 0, to = 65535)
+    @IntRange(from = 0, to = 16777215)
     public int getTac() {
         return mTac;
     }
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index cdf7351..8f5ec36 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -29,7 +29,10 @@
 
 /**
  * Abstract class that represents the location of the device.  {@more}
+ *
+ * @deprecated use {@link android.telephony.CellIdentity CellIdentity}.
  */
+@Deprecated
 public abstract class CellLocation {
 
     /**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 85dca2b..66eadb5 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -13388,4 +13388,38 @@
             return true;
         }
     }
+
+    /**
+     * Returns a list of the equivalent home PLMNs (EF_EHPLMN) from the USIM app.
+     *
+     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     *
+     * @return A list of equivalent home PLMNs. Returns an empty list if EF_EHPLMN is empty or
+     * does not exist on the SIM card.
+     *
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     * @throws SecurityException if the caller doesn't have the permission.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public @NonNull List<String> getEquivalentHomePlmns() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getEquivalentHomePlmns(getSubId(), mContext.getOpPackageName(),
+                        getAttributionTag());
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            if (!isSystemProcess()) {
+                ex.rethrowAsRuntimeException();
+            }
+        }
+
+        return Collections.emptyList();
+    }
 }
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 9bc39a0..d808cab 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -23,7 +23,10 @@
 
 /**
  * Represents the cell location on a CDMA phone.
+ *
+ * @deprecated use {@link android.telephony.CellIdentity CellIdentity}.
  */
+@Deprecated
 public class CdmaCellLocation extends CellLocation {
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private int mBaseStationId = -1;
diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java
index bc8ee1d..2eee4ce 100644
--- a/telephony/java/android/telephony/gsm/GsmCellLocation.java
+++ b/telephony/java/android/telephony/gsm/GsmCellLocation.java
@@ -23,7 +23,10 @@
 
 /**
  * Represents the cell location on a GSM phone.
+ *
+ * @deprecated use {@link android.telephony.CellIdentity CellIdentity}.
  */
+@Deprecated
 public class GsmCellLocation extends CellLocation {
     private int mLac;
     private int mCid;
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index ae1b5c1..659d9cd3 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2297,4 +2297,12 @@
      * Whether device can connect to 5G network when two SIMs are active.
      */
     boolean canConnectTo5GInDsdsMode();
+
+    /**
+     * Returns a list of the equivalent home PLMNs (EF_EHPLMN) from the USIM app.
+     *
+     * @return A list of equivalent home PLMNs. Returns an empty list if EF_EHPLMN is empty or
+     * does not exist on the SIM card.
+     */
+    List<String> getEquivalentHomePlmns(int subId, String callingPackage, String callingFeatureId);
 }
diff --git a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt
index 0f62c4f..e9227e94 100644
--- a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt
+++ b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt
@@ -107,7 +107,10 @@
     fun ParcelFileDescriptor.text() = FileReader(fileDescriptor).readText()
 
     @After
-    fun resetIdentity() = uiAutomation.dropShellPermissionIdentity()
+    fun resetChangeIdAndIdentity() {
+        command("am compat reset $TEST_CHANGE_ID $TEST_PKG")
+        uiAutomation.dropShellPermissionIdentity()
+    }
 
     @Test
     fun execute() {
diff --git a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
index 61d7c76..fb4a2b2 100644
--- a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
+++ b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
@@ -26,6 +26,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -57,6 +58,9 @@
 
     private WatchdogEventLogger mLogger = new WatchdogEventLogger();
 
+    @Rule
+    public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this);
+
     @Before
     public void setUp() throws Exception {
         runPhase("cleanUp");
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 9169ef5..be74e33 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -34,6 +34,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -87,6 +88,9 @@
 
     private WatchdogEventLogger mLogger = new WatchdogEventLogger();
 
+    @Rule
+    public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this);
+
     @Before
     public void setUp() throws Exception {
         deleteFiles("/system/apex/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex",
diff --git a/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java b/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java
new file mode 100644
index 0000000..b086213
--- /dev/null
+++ b/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 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.tests.rollback.host;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.rules.ExternalResource;
+
+public class AbandonSessionsRule extends ExternalResource {
+    private final BaseHostJUnit4Test mHost;
+
+    public AbandonSessionsRule(BaseHostJUnit4Test host) {
+        mHost = host;
+    }
+
+    @Override
+    protected void before() throws Throwable {
+        abandonSessions(mHost.getDevice());
+    }
+
+    @Override
+    protected void after() {
+        try {
+            abandonSessions(mHost.getDevice());
+        } catch (Exception ignore) {
+        }
+    }
+
+    /**
+     * Abandons all sessions to prevent interference in our tests.
+     */
+    private static void abandonSessions(ITestDevice device) throws Exception {
+        // No point in abandoning applied or failed sessions. We care about ready sessions only.
+        String cmdListReadySessions =
+                "pm list staged-sessions --only-sessionid --only-parent --only-ready";
+        String output = device.executeShellCommand(cmdListReadySessions);
+        if (output.trim().isEmpty()) {
+            // No sessions to abandon
+            return;
+        }
+        // Ensure we have sufficient privilege to abandon sessions from other apps
+        device.enableAdbRoot();
+        device.executeShellCommand("for i in $(" + cmdListReadySessions
+                + "); do pm install-abandon $i; done");
+        device.disableAdbRoot();
+    }
+}
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index c3fdd69..1e286bb 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -24,7 +24,15 @@
     name: "StagedInstallInternalTest",
     srcs: ["src/**/*.java"],
     libs: ["tradefed"],
-    static_libs: ["testng", "compatibility-tradefed"],
+    static_libs: [
+        "testng",
+        "compatibility-tradefed",
+        "module_test_util",
+    ],
+    data: [
+        ":com.android.apex.cts.shim.v2_prebuilt",
+        ":TestAppAv1",
+    ],
     test_suites: ["general-tests"],
     test_config: "StagedInstallInternalTest.xml",
 }
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 9b432f7..86d5fd8 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -19,8 +19,10 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 
 import com.android.ddmlib.Log;
+import com.android.tests.util.ModuleTestUtils;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.util.ProcessInfo;
@@ -30,6 +32,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.File;
+
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class StagedInstallInternalTest extends BaseHostJUnit4Test {
 
@@ -37,6 +41,11 @@
     private static final long SYSTEM_SERVER_TIMEOUT_MS = 60 * 1000;
     private boolean mWasRoot = false;
 
+    private static final String SHIM_V2 = "com.android.apex.cts.shim.v2.apex";
+    private static final String APK_A = "TestAppAv1.apk";
+
+    private final ModuleTestUtils mTestUtils = new ModuleTestUtils(this);
+
     /**
      * Runs the given phase of a test by calling into the device.
      * Throws an exception if the test phase fails.
@@ -87,6 +96,58 @@
         runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Verify");
     }
 
+    @Test
+    public void testAdbStagedInstallWaitForReadyFlagWorks() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mTestUtils.isApexUpdateSupported());
+
+        File apexFile = mTestUtils.getTestFile(SHIM_V2);
+        String output = getDevice().executeAdbCommand("install", "--staged",
+                "--wait-for-staged-ready", "60000", apexFile.getAbsolutePath());
+        assertThat(output).contains("Reboot device to apply staged session");
+        String sessionId = getDevice().executeShellCommand(
+                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
+        assertThat(sessionId).isNotEmpty();
+    }
+
+    @Test
+    public void testAdbStagedInstallNoWaitFlagWorks() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mTestUtils.isApexUpdateSupported());
+
+        File apexFile = mTestUtils.getTestFile(SHIM_V2);
+        String output = getDevice().executeAdbCommand("install", "--staged",
+                "--no-wait", apexFile.getAbsolutePath());
+        assertThat(output).doesNotContain("Reboot device to apply staged session");
+        assertThat(output).contains("Success");
+        String sessionId = getDevice().executeShellCommand(
+                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
+        assertThat(sessionId).isEmpty();
+    }
+
+    @Test
+    public void testAdbInstallMultiPackageCommandWorks() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mTestUtils.isApexUpdateSupported());
+
+        File apexFile = mTestUtils.getTestFile(SHIM_V2);
+        File apkFile = mTestUtils.getTestFile(APK_A);
+        String output = getDevice().executeAdbCommand("install-multi-package",
+                apexFile.getAbsolutePath(), apkFile.getAbsolutePath());
+        assertThat(output).contains("Created parent session");
+        assertThat(output).contains("Created child session");
+        assertThat(output).contains("Success. Reboot device to apply staged session");
+
+        // Ensure there is only one parent session
+        String[] sessionIds = getDevice().executeShellCommand(
+                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").split("\n");
+        assertThat(sessionIds.length).isEqualTo(1);
+        // Ensure there are two children session
+        sessionIds = getDevice().executeShellCommand(
+                "pm get-stagedsessions --only-ready --only-sessionid").split("\n");
+        assertThat(sessionIds.length).isEqualTo(3);
+    }
+
     private void restartSystemServer() throws Exception {
         // Restart the system server
         long oldStartTime = getDevice().getProcessByName("system_server").getStartTime();