Merge "Unhide FrontendSettings part 1 with super Builder class"
diff --git a/Android.bp b/Android.bp
index 6c640b3..5fcefa6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -306,7 +306,6 @@
             "rs/java",
             "sax/java",
             "telecomm/java",
-            "wifi/java",
         ],
     },
 
@@ -1126,9 +1125,10 @@
 }
 
 // Avoid including Parcelable classes as we don't want to have two copies of
-// Parcelable cross the process.
+// Parcelable cross the libraries. This is used by telephony-common (frameworks/opt/telephony)
+// and TeleService app (packages/services/Telephony).
 filegroup {
-    name: "framework-telephony-stack-shared-srcs",
+    name: "framework-telephony-common-shared-srcs",
     srcs: [
         "core/java/android/os/BasicShellCommandHandler.java",
         "core/java/android/os/RegistrantList.java",
@@ -1151,6 +1151,21 @@
 }
 
 // Avoid including Parcelable classes as we don't want to have two copies of
+// Parcelable cross the process. This is used by framework-telephony (frameworks/base/telephony).
+filegroup {
+    name: "framework-telephony-shared-srcs",
+    srcs: [
+        "core/java/android/util/RecurrenceRule.java",
+        "core/java/com/android/internal/os/SomeArgs.java",
+        "core/java/com/android/internal/util/BitwiseInputStream.java",
+        "core/java/com/android/internal/util/BitwiseOutputStream.java",
+        "core/java/com/android/internal/util/HexDump.java",
+        "core/java/com/android/internal/util/IndentingPrintWriter.java",
+        "core/java/com/android/internal/util/Preconditions.java",
+    ],
+}
+
+// Avoid including Parcelable classes as we don't want to have two copies of
 // Parcelable cross the process.
 filegroup {
     name: "framework-cellbroadcast-shared-srcs",
@@ -1274,6 +1289,7 @@
     name: "framework-telephony",
     srcs: [
         ":framework-telephony-sources",
+        ":framework-telephony-shared-srcs",
     ],
     // TODO: change to framework-system-stub to build against system APIs.
     libs: [
@@ -1292,7 +1308,7 @@
             "frameworks/native/aidl/gui",
         ]
     },
-    jarjar_rules: ":telephony-framework-jarjar-rules",
+    jarjar_rules: ":framework-telephony-jarjar-rules",
     dxflags: [
         "--core-library",
         "--multi-dex",
@@ -1311,6 +1327,6 @@
 }
 
 filegroup {
-    name: "telephony-framework-jarjar-rules",
+    name: "framework-telephony-jarjar-rules",
     srcs: ["telephony/framework-telephony-jarjar-rules.txt"],
 }
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobHandle.aidl b/apex/blobstore/framework/java/android/app/blob/BlobHandle.aidl
new file mode 100644
index 0000000..02d0740
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/BlobHandle.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 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 android.app.blob;
+
+/** {@hide} */
+parcelable BlobHandle;
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobHandle.java b/apex/blobstore/framework/java/android/app/blob/BlobHandle.java
new file mode 100644
index 0000000..6aca4a1
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/BlobHandle.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 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 android.app.blob;
+
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * An identifier to represent a blob.
+ */
+// TODO: use datagen tool?
+public final class BlobHandle implements Parcelable {
+    private static final String ALGO_SHA_256 = "SHA-256";
+
+    private static final int LIMIT_BLOB_TAG_LENGTH = 128; // characters
+
+    /**
+     * Cyrptographically secure hash algorithm used to generate hash of the blob this handle is
+     * representing.
+     *
+     * @hide
+     */
+    @NonNull public final String algorithm;
+    /**
+     * Hash of the blob this handle is representing using {@link #algorithm}.
+     *
+     * @hide
+     */
+    @NonNull public final byte[] digest;
+    /**
+     * Label of the blob that can be surfaced to the user.
+     * @hide
+     */
+    @NonNull public final CharSequence label;
+    /**
+     * Time in milliseconds after which the blob should be invalidated and not
+     * allowed to be accessed by any other app, in {@link System#currentTimeMillis()} timebase.
+     *
+     * @hide
+     */
+    @CurrentTimeMillisLong public final long expiryTimeMillis;
+    /**
+     * An opaque {@link String} associated with the blob.
+     *
+     * @hide
+     */
+    @NonNull public final String tag;
+
+    private BlobHandle(String algorithm, byte[] digest, CharSequence label, long expiryTimeMillis,
+            String tag) {
+        this.algorithm = algorithm;
+        this.digest = digest;
+        this.label = label;
+        this.expiryTimeMillis = expiryTimeMillis;
+        this.tag = tag;
+    }
+
+    private BlobHandle(Parcel in) {
+        this.algorithm = in.readString();
+        this.digest = in.createByteArray();
+        this.label = in.readCharSequence();
+        this.expiryTimeMillis = in.readLong();
+        this.tag = in.readString();
+    }
+
+    /** @hide */
+    public static @NonNull BlobHandle create(@NonNull String algorithm, @NonNull byte[] digest,
+            @NonNull CharSequence label, @CurrentTimeMillisLong long expiryTimeMillis,
+            @NonNull String tag) {
+        Preconditions.checkNotNull(algorithm, "algorithm must not be null");
+        Preconditions.checkNotNull(digest, "digest must not be null");
+        Preconditions.checkNotNull(label, "label must not be null");
+        Preconditions.checkArgumentNonnegative(expiryTimeMillis,
+                "expiryTimeMillis must not be negative");
+        Preconditions.checkNotNull(tag, "tag must not be null");
+        Preconditions.checkArgument(tag.length() <= LIMIT_BLOB_TAG_LENGTH, "tag too long");
+        return new BlobHandle(algorithm, digest, label, expiryTimeMillis, tag);
+    }
+
+    /**
+     * Create a new blob identifier.
+     *
+     * <p> For two objects of {@link BlobHandle} to be considered equal, the following arguments
+     * must be equal:
+     * <ul>
+     * <li> {@code digest}
+     * <li> {@code label}
+     * <li> {@code expiryTimeMillis}
+     * <li> {@code tag}
+     * </ul>
+     *
+     * @param digest the SHA-256 hash of the blob this is representing.
+     * @param label a label indicating what the blob is, that can be surfaced to the user.
+     * @param expiryTimeMillis the time in secs after which the blob should be invalidated and not
+     *                         allowed to be accessed by any other app,
+     *                         in {@link System#currentTimeMillis()} timebase.
+     * @param tag an opaque {@link String} associated with the blob. The length of the tag
+     *            cannot be more than 128 characters.
+     *
+     * @return a new instance of {@link BlobHandle} object.
+     */
+    public static @NonNull BlobHandle createWithSha256(@NonNull byte[] digest,
+            @NonNull CharSequence label, @CurrentTimeMillisLong long expiryTimeMillis,
+            @NonNull String tag) {
+        return create(ALGO_SHA_256, digest, label, expiryTimeMillis, tag);
+    }
+
+    /**
+     * Returns the SHA-256 hash of the blob that this object is representing.
+     *
+     * @see #createWithSha256(byte[], CharSequence, long, String)
+     */
+    public @NonNull byte[] getSha256Digest() {
+        return digest;
+    }
+
+    /**
+     * Returns the label associated with the blob that this object is representing.
+     *
+     * @see #createWithSha256(byte[], CharSequence, long, String)
+     */
+    public @NonNull CharSequence getLabel() {
+        return label;
+    }
+
+    /**
+     * Returns the expiry time in milliseconds of the blob that this object is representing, in
+     *         {@link System#currentTimeMillis()} timebase.
+     *
+     * @see #createWithSha256(byte[], CharSequence, long, String)
+     */
+    public @CurrentTimeMillisLong long getExpiryTimeMillis() {
+        return expiryTimeMillis;
+    }
+
+    /**
+     * Returns the opaque {@link String} associated with the blob this object is representing.
+     *
+     * @see #createWithSha256(byte[], CharSequence, long, String)
+     */
+    public @NonNull String getTag() {
+        return tag;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(algorithm);
+        dest.writeByteArray(digest);
+        dest.writeCharSequence(label);
+        dest.writeLong(expiryTimeMillis);
+        dest.writeString(tag);
+    }
+
+    public static final @NonNull Creator<BlobHandle> CREATOR = new Creator<BlobHandle>() {
+        @Override
+        public @NonNull BlobHandle createFromParcel(@NonNull Parcel source) {
+            return new BlobHandle(source);
+        }
+
+        @Override
+        public @NonNull BlobHandle[] newArray(int size) {
+            return new BlobHandle[size];
+        }
+    };
+}
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
index 1ed188e..4395e5a 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
@@ -15,18 +15,33 @@
  */
 package android.app.blob;
 
+import android.annotation.BytesLong;
+import android.annotation.CallbackExecutor;
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.IdRes;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelableException;
+import android.os.RemoteException;
+
+import com.android.internal.util.function.pooled.PooledLambda;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 /**
- * This class provides access to the blob store maintained by the system.
+ * This class provides access to the blob store managed by the system.
  *
  * Apps can publish data blobs which might be useful for other apps on the device to be
- * maintained by the system and apps that would like to access these data blobs can do so
+ * managed by the system and apps that would like to access these data blobs can do so
  * by addressing them via their cryptographically secure hashes.
  *
- * TODO: make this public once the APIs are added.
- * @hide
+ * TODO: More documentation.
  */
 @SystemService(Context.BLOB_STORE_SERVICE)
 public class BlobStoreManager {
@@ -34,8 +49,421 @@
     private final IBlobStoreManager mService;
 
     /** @hide */
-    public BlobStoreManager(Context context, IBlobStoreManager service) {
+    public BlobStoreManager(@NonNull Context context, @NonNull IBlobStoreManager service) {
         mContext = context;
         mService = service;
     }
+
+    /**
+     * Create a new session using the given {@link BlobHandle}, returning a unique id
+     * that represents the session. Once created, the session can be opened
+     * multiple times across multiple device boots.
+     *
+     * <p> The system may automatically destroy sessions that have not been
+     * finalized (either committed or abandoned) within a reasonable period of
+     * time, typically about a week.
+     *
+     * @param blobHandle the {@link BlobHandle} identifier for which a new session
+     *                   needs to be created.
+     * @return positive, non-zero unique id that represents the created session.
+     *         This id remains consistent across device reboots until the
+     *         session is finalized. IDs are not reused during a given boot.
+     *
+     * @throws IOException when there is an I/O error while creating the session.
+     * @throws SecurityException when the caller is not allowed to create a session, such
+     *                           as when called from an Instant app.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+     * @throws IllegalStateException when a new session could not be created, such as when the
+     *                               caller is trying to create too many sessions or when the
+     *                               device is running low on space.
+     */
+    public @IntRange(from = 1) long createSession(@NonNull BlobHandle blobHandle)
+            throws IOException {
+        try {
+            return mService.createSession(blobHandle, mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Open an existing session to actively perform work.
+     *
+     * @param sessionId a unique id obtained via {@link #createSession(BlobHandle)} that
+     *                  represents a particular session.
+     * @return the {@link Session} object corresponding to the {@code sessionId}.
+     *
+     * @throws IOException when there is an I/O error while opening the session.
+     * @throws SecurityException when the caller does not own the session, or
+     *                           the session does not exist or is invalid.
+     */
+    public @NonNull Session openSession(@IntRange(from = 1) long sessionId) throws IOException {
+        try {
+            return new Session(mService.openSession(sessionId));
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Opens an existing blob for reading from the blob store managed by the system.
+     *
+     * @param blobHandle the {@link BlobHandle} representing the blob that the caller
+     *                   wants to access.
+     * @return a {@link ParcelFileDescriptor} that can be used to read the blob content.
+     *
+     * @throws IOException when there is an I/O while opening the blob for read.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+     * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+     *                           exist or the caller does not have access to it.
+     */
+    public @NonNull ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle)
+            throws IOException {
+        try {
+            return mService.openBlob(blobHandle, mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Acquire a lease to the blob represented by {@code blobHandle}. This lease indicates to the
+     * system that the caller wants the blob to be kept around.
+     *
+     * <p> Any active leases will be automatically released when the blob's expiry time
+     * ({@link BlobHandle#getExpiryTimeMillis()}) is elapsed.
+     *
+     * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+     *                   acquire a lease for.
+     * @param descriptionResId the resource id for a short description string that can be surfaced
+     *                         to the user explaining what the blob is used for.
+     * @param leaseExpiryTimeMillis the time in milliseconds after which the lease can be
+     *                              automatically released, in {@link System#currentTimeMillis()}
+     *                              timebase. If its value is {@code 0}, then the behavior of this
+     *                              API is identical to {@link #acquireLease(BlobHandle, int)}
+     *                              where clients have to explicitly call
+     *                              {@link #releaseLease(BlobHandle)} when they don't
+     *                              need the blob anymore.
+     *
+     * @throws IOException when there is an I/O error while acquiring a lease to the blob.
+     * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+     *                           exist or the caller does not have access to it.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid or
+     *                                  if the {@code leaseExpiryTimeMillis} is greater than the
+     *                                  {@link BlobHandle#getExpiryTimeMillis()}.
+     * @throws IllegalStateException when a lease could not be acquired, such as when the
+     *                               caller is trying to acquire too many leases.
+     *
+     * @see {@link #acquireLease(BlobHandle, int)}
+     */
+    public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
+            @CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
+        try {
+            mService.acquireLease(blobHandle, descriptionResId, leaseExpiryTimeMillis,
+                    mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Acquire a lease to the blob represented by {@code blobHandle}. This lease indicates to the
+     * system that the caller wants the blob to be kept around.
+     *
+     * <p> This is similar to {@link #acquireLease(BlobHandle, int, long)} except clients don't
+     * have to specify the lease expiry time upfront using this API and need to explicitly
+     * release the lease using {@link #releaseLease(BlobHandle)} when they no longer like to keep
+     * a blob around.
+     *
+     * <p> Any active leases will be automatically released when the blob's expiry time
+     * ({@link BlobHandle#getExpiryTimeMillis()}) is elapsed.
+     *
+     * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+     *                   acquire a lease for.
+     * @param descriptionResId the resource id for a short description string that can be surfaced
+     *                         to the user explaining what the blob is used for.
+     *
+     * @throws IOException when there is an I/O error while acquiring a lease to the blob.
+     * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+     *                           exist or the caller does not have access to it.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+     * @throws IllegalStateException when a lease could not be acquired, such as when the
+     *                               caller is trying to acquire too many leases.
+     *
+     * @see {@link #acquireLease(BlobHandle, int, long)}
+     */
+    public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId)
+            throws IOException {
+        acquireLease(blobHandle, descriptionResId, 0);
+    }
+
+    /**
+     * Release all active leases to the blob represented by {@code blobHandle} which are
+     * currently held by the caller.
+     *
+     * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+     *                   release the leases for.
+     *
+     * @throws IOException when there is an I/O error while releasing the releases to the blob.
+     * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+     *                           exist or the caller does not have access to it.
+     * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+     */
+    public void releaseLease(@NonNull BlobHandle blobHandle) throws IOException {
+        try {
+            mService.releaseLease(blobHandle, mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Represents an ongoing session of a blob's contribution to the blob store managed by the
+     * system.
+     *
+     * <p> Clients that want to contribute a blob need to first create a {@link Session} using
+     * {@link #createSession(BlobHandle)} and once the session is created, clients can open and
+     * close this session multiple times using {@link #openSession(long)} and
+     * {@link Session#close()} before committing it using
+     * {@link Session#commit(Executor, Consumer)}, at which point system will take
+     * ownership of the blob and the client can no longer make any modifications to the blob's
+     * content.
+     */
+    public static class Session implements Closeable {
+        private final IBlobStoreSession mSession;
+
+        private Session(@NonNull IBlobStoreSession session) {
+            mSession = session;
+        }
+
+        /**
+         * Opens a file descriptor to write a blob into the session.
+         *
+         * <p> The returned file descriptor will start writing data at the requested offset
+         * in the underlying file, which can be used to resume a partially
+         * written file. If a valid file length is specified, the system will
+         * preallocate the underlying disk space to optimize placement on disk.
+         * It is strongly recommended to provide a valid file length when known.
+         *
+         * @param offsetBytes offset into the file to begin writing at, or 0 to
+         *                    start at the beginning of the file.
+         * @param lengthBytes total size of the file being written, used to
+         *                    preallocate the underlying disk space, or -1 if unknown.
+         *                    The system may clear various caches as needed to allocate
+         *                    this space.
+         *
+         * @return a {@link ParcelFileDescriptor} for writing to the blob file.
+         *
+         * @throws IOException when there is an I/O error while opening the file to write.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to write to the file after it is
+         *                               abandoned (using {@link #abandon()})
+         *                               or committed (using {@link #commit})
+         *                               or closed (using {@link #close()}).
+         */
+        public @NonNull ParcelFileDescriptor openWrite(@BytesLong long offsetBytes,
+                @BytesLong long lengthBytes) throws IOException {
+            try {
+                return mSession.openWrite(offsetBytes, lengthBytes);
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Gets the size of the blob file that was written to the session so far.
+         *
+         * @return the size of the blob file so far.
+         *
+         * @throws IOException when there is an I/O error while opening the file to read.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to get the file size after it is
+         *                               abandoned (using {@link #abandon()})
+         *                               or closed (using {@link #close()}).
+         */
+        public @BytesLong long getSize() throws IOException {
+            try {
+                return mSession.getSize();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Close this session. It can be re-opened for writing/reading if it has not been
+         * abandoned (using {@link #abandon}) or closed (using {@link #commit}).
+         *
+         * @throws IOException when there is an I/O error while closing the session.
+         * @throws SecurityException when the caller is not the owner of the session.
+         */
+        public void close() throws IOException {
+            try {
+                mSession.close();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Abandon this session and delete any data that was written to this session so far.
+         *
+         * @throws IOException when there is an I/O error while abandoning the session.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to abandon a session which was
+         *                               already finalized.
+         */
+        public void abandon() throws IOException {
+            try {
+                mSession.abandon();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Allow {@code packageName} with a particular signing certificate to access this blob
+         * data once it is committed using a {@link BlobHandle} representing the blob.
+         *
+         * <p> This needs to be called before committing the blob using
+         * {@link #commit(Executor, Consumer)}.
+         *
+         * @param packageName the name of the package which should be allowed to access the blob.
+         * @param certificate the input bytes representing a certificate of type
+         *                    {@link android.content.pm.PackageManager#CERT_INPUT_SHA256}.
+         *
+         * @throws IOException when there is an I/O error while changing the access.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to change access for a blob which is
+         *                               already committed.
+         */
+        public void allowPackageAccess(@NonNull String packageName, @NonNull byte[] certificate)
+                throws IOException {
+            try {
+                mSession.allowPackageAccess(packageName, certificate);
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Allow packages which are signed with the same certificate as the caller to access this
+         * blob data once it is committed using a {@link BlobHandle} representing the blob.
+         *
+         * <p> This needs to be called before committing the blob using
+         * {@link #commit(Executor, Consumer)}.
+         *
+         * @throws IOException when there is an I/O error while changing the access.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to change access for a blob which is
+         *                               already committed.
+         */
+        public void allowSameSignatureAccess() throws IOException {
+            try {
+                mSession.allowSameSignatureAccess();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Allow any app on the device to access this blob data once it is committed using
+         * a {@link BlobHandle} representing the blob.
+         *
+         * <p><strong>Note:</strong> This is only meant to be used from libraries and SDKs where
+         * the apps which we want to allow access is not known ahead of time.
+         * If a blob is being committed to be shared with a particular set of apps, it is highly
+         * recommended to use {@link #allowPackageAccess(String, byte[])} instead.
+         *
+         * <p> This needs to be called before committing the blob using
+         * {@link #commit(Executor, Consumer)}.
+         *
+         * @throws IOException when there is an I/O error while changing the access.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalStateException when the caller tries to change access for a blob which is
+         *                               already committed.
+         */
+        public void allowPublicAccess() throws IOException {
+            try {
+                mSession.allowPublicAccess();
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Commit the file that was written so far to this session to the blob store maintained by
+         * the system.
+         *
+         * <p> Once this method is called, the session is finalized and no additional
+         * mutations can be performed on the session. If the device reboots
+         * before the session has been finalized, you may commit the session again.
+         *
+         * <p> Note that this commit operation will fail if the hash of the data written so far
+         * to this session does not match with the one used for
+         * {@link BlobHandle#createWithSha256(byte[], CharSequence, long, String)}  BlobHandle}
+         * associated with this session.
+         *
+         * @param executor the executor on which result callback will be invoked.
+         * @param resultCallback a callback to receive the commit result. when the result is
+         *                       {@code 0}, it indicates success. Otherwise, failure.
+         *
+         * @throws IOException when there is an I/O error while committing the session.
+         * @throws SecurityException when the caller is not the owner of the session.
+         * @throws IllegalArgumentException when the passed parameters are not valid.
+         * @throws IllegalStateException when the caller tries to commit a session which was
+         *                               already finalized.
+         */
+        public void commit(@NonNull @CallbackExecutor Executor executor,
+                @NonNull Consumer<Integer> resultCallback) throws IOException {
+            try {
+                mSession.commit(new IBlobCommitCallback.Stub() {
+                    public void onResult(int result) {
+                        executor.execute(PooledLambda.obtainRunnable(
+                                Consumer::accept, resultCallback, result));
+                    }
+                });
+            } catch (ParcelableException e) {
+                e.maybeRethrow(IOException.class);
+                throw new RuntimeException(e);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
 }
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobCommitCallback.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobCommitCallback.aidl
new file mode 100644
index 0000000..a9b30e2
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobCommitCallback.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright 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 android.app.blob;
+
+/** {@hide} */
+oneway interface IBlobCommitCallback {
+    void onResult(int result);
+}
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
index 00c1ed4..b7a2f1a 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
@@ -15,6 +15,16 @@
  */
 package android.app.blob;
 
+import android.app.blob.BlobHandle;
+import android.app.blob.IBlobStoreSession;
+
 /** {@hide} */
 interface IBlobStoreManager {
+    long createSession(in BlobHandle handle, in String packageName);
+    IBlobStoreSession openSession(long sessionId);
+    ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName);
+
+    void acquireLease(in BlobHandle handle, int descriptionResId, long leaseTimeout,
+            in String packageName);
+    void releaseLease(in BlobHandle handle, in String packageName);
 }
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
new file mode 100644
index 0000000..bb5ef3b
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 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 android.app.blob;
+
+import android.app.blob.IBlobCommitCallback;
+import android.os.ParcelFileDescriptor;
+
+/** {@hide} */
+interface IBlobStoreSession {
+    ParcelFileDescriptor openWrite(long offsetBytes, long lengthBytes);
+
+    void allowPackageAccess(in String packageName, in byte[] certificate);
+    void allowSameSignatureAccess();
+    void allowPublicAccess();
+
+    long getSize();
+    void close();
+    void abandon();
+
+    void commit(in IBlobCommitCallback callback);
+}
\ No newline at end of file
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
index d7cab59..b204fee 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -15,8 +15,14 @@
  */
 package com.android.server.blob;
 
+import android.annotation.CurrentTimeSecondsLong;
+import android.annotation.IdRes;
+import android.annotation.NonNull;
+import android.app.blob.BlobHandle;
 import android.app.blob.IBlobStoreManager;
+import android.app.blob.IBlobStoreSession;
 import android.content.Context;
+import android.os.ParcelFileDescriptor;
 
 import com.android.server.SystemService;
 
@@ -25,8 +31,11 @@
  */
 public class BlobStoreManagerService extends SystemService {
 
+    private final Context mContext;
+
     public BlobStoreManagerService(Context context) {
         super(context);
+        mContext = context;
     }
 
     @Override
@@ -35,5 +44,29 @@
     }
 
     private class Stub extends IBlobStoreManager.Stub {
+        @Override
+        public long createSession(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
+            return 0;
+        }
+
+        @Override
+        public IBlobStoreSession openSession(long sessionId) {
+            return null;
+        }
+
+        @Override
+        public ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle,
+                @NonNull String packageName) {
+            return null;
+        }
+
+        @Override
+        public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
+                @CurrentTimeSecondsLong long leaseTimeout, @NonNull String packageName) {
+        }
+
+        @Override
+        public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
+        }
     }
 }
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
new file mode 100644
index 0000000..2c38e76
--- /dev/null
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 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.server.blob;
+
+import android.annotation.BytesLong;
+import android.annotation.NonNull;
+import android.app.blob.IBlobCommitCallback;
+import android.app.blob.IBlobStoreSession;
+import android.os.ParcelFileDescriptor;
+
+/** TODO: add doc */
+public class BlobStoreSession extends IBlobStoreSession.Stub {
+
+    @Override
+    @NonNull
+    public ParcelFileDescriptor openWrite(@BytesLong long offsetBytes,
+            @BytesLong long lengthBytes) {
+        return null;
+    }
+
+    @Override
+    @BytesLong
+    public long getSize() {
+        return 0;
+    }
+
+    @Override
+    public void allowPackageAccess(@NonNull String packageName,
+            @NonNull byte[] certificate) {
+    }
+
+    @Override
+    public void allowSameSignatureAccess() {
+    }
+
+    @Override
+    public void allowPublicAccess() {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public void abandon() {
+    }
+
+    @Override
+    public void commit(IBlobCommitCallback callback) {
+    }
+}
diff --git a/apex/statsd/aidl/Android.bp b/apex/statsd/aidl/Android.bp
index f8325d4..cc5172c6 100644
--- a/apex/statsd/aidl/Android.bp
+++ b/apex/statsd/aidl/Android.bp
@@ -23,7 +23,6 @@
         "android/os/IPullAtomResultReceiver.aidl",
         "android/os/IStatsCompanionService.aidl",
         "android/os/IStatsd.aidl",
-        "android/os/IStatsPullerCallback.aidl",
         "android/util/StatsEventParcel.aidl",
     ],
 }
diff --git a/apex/statsd/aidl/android/os/IStatsPullerCallback.aidl b/apex/statsd/aidl/android/os/IStatsPullerCallback.aidl
deleted file mode 100644
index c3e1e55..0000000
--- a/apex/statsd/aidl/android/os/IStatsPullerCallback.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.StatsLogEventWrapper;
-
-/**
-  * DEPRECATED
-  * Binder interface to pull atoms for the stats service.
-  * {@hide}
-  */
-interface IStatsPullerCallback {
-    /**
-     * Pull data for the specified atom tag. Returns an array of StatsLogEventWrapper containing
-     * the data.
-     *
-     * Note: These pulled atoms should not have uid/attribution chain. Additionally, the event
-     * timestamps will be truncated to the nearest 5 minutes.
-     */
-    StatsLogEventWrapper[] pullData(int atomTag, long elapsedNanos, long wallClocknanos);
-
-}
diff --git a/apex/statsd/aidl/android/os/IStatsd.aidl b/apex/statsd/aidl/android/os/IStatsd.aidl
index 0ecf2f0..a2564212 100644
--- a/apex/statsd/aidl/android/os/IStatsd.aidl
+++ b/apex/statsd/aidl/android/os/IStatsd.aidl
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import android.os.IStatsPullerCallback;
 import android.os.IPendingIntentRef;
 import android.os.IPullAtomCallback;
 import android.os.ParcelFileDescriptor;
@@ -183,16 +182,6 @@
      */
     void sendAppBreadcrumbAtom(int label, int state);
 
-    /**
-     * Registers a puller callback function that, when invoked, pulls the data
-     * for the specified vendor atom tag.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
-     * @deprecated please use registerPullAtomCallback.
-     */
-    oneway void registerPullerCallback(int atomTag, IStatsPullerCallback pullerCallback,
-                                       String packageName);
-
    /**
     * Registers a puller callback function that, when invoked, pulls the data
     * for the specified atom tag.
@@ -207,13 +196,6 @@
     oneway void registerNativePullAtomCallback(int atomTag, long coolDownNs, long timeoutNs,
                            in int[] additiveFields, IPullAtomCallback pullerCallback);
 
-   /**
-    * Unregisters a puller callback function for the given vendor atom.
-    *
-    * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
-    */
-    oneway void unregisterPullerCallback(int atomTag, String packageName);
-
     /**
      * Unregisters any pullAtomCallback for the given uid/atom.
      */
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index 17573bb..e5d1182 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -714,265 +714,6 @@
         }
     }
 
-    private void pullSystemElapsedRealtime(
-            int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeLong(SystemClock.elapsedRealtime());
-        pulledData.add(e);
-    }
-
-    private void pullLooperStats(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        LooperStats looperStats = LocalServices.getService(LooperStats.class);
-        if (looperStats == null) {
-            throw new IllegalStateException("looperStats null");
-        }
-
-        List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
-        looperStats.reset();
-        for (LooperStats.ExportedEntry entry : entries) {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(entry.workSourceUid);
-            e.writeString(entry.handlerClassName);
-            e.writeString(entry.threadName);
-            e.writeString(entry.messageName);
-            e.writeLong(entry.messageCount);
-            e.writeLong(entry.exceptionCount);
-            e.writeLong(entry.recordedMessageCount);
-            e.writeLong(entry.totalLatencyMicros);
-            e.writeLong(entry.cpuUsageMicros);
-            e.writeBoolean(entry.isInteractive);
-            e.writeLong(entry.maxCpuUsageMicros);
-            e.writeLong(entry.maxLatencyMicros);
-            e.writeLong(entry.recordedDelayMessageCount);
-            e.writeLong(entry.delayMillis);
-            e.writeLong(entry.maxDelayMillis);
-            pulledData.add(e);
-        }
-    }
-
-    private void pullDiskStats(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        // Run a quick-and-dirty performance test: write 512 bytes
-        byte[] junk = new byte[512];
-        for (int i = 0; i < junk.length; i++) junk[i] = (byte) i;  // Write nonzero bytes
-
-        File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
-        FileOutputStream fos = null;
-        IOException error = null;
-
-        long before = SystemClock.elapsedRealtime();
-        try {
-            fos = new FileOutputStream(tmp);
-            fos.write(junk);
-        } catch (IOException e) {
-            error = e;
-        } finally {
-            try {
-                if (fos != null) fos.close();
-            } catch (IOException e) {
-                // Do nothing.
-            }
-        }
-
-        long latency = SystemClock.elapsedRealtime() - before;
-        if (tmp.exists()) tmp.delete();
-
-        if (error != null) {
-            Slog.e(TAG, "Error performing diskstats latency test");
-            latency = -1;
-        }
-        // File based encryption.
-        boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
-
-        //Recent disk write speed. Binder call to storaged.
-        int writeSpeed = -1;
-        try {
-            IBinder binder = ServiceManager.getService("storaged");
-            if (binder == null) {
-                Slog.e(TAG, "storaged not found");
-            }
-            IStoraged storaged = IStoraged.Stub.asInterface(binder);
-            writeSpeed = storaged.getRecentPerf();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "storaged not found");
-        }
-
-        // Add info pulledData.
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeLong(latency);
-        e.writeBoolean(fileBased);
-        e.writeInt(writeSpeed);
-        pulledData.add(e);
-    }
-
-    private void pullDirectoryUsage(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
-        StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
-        StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
-
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA);
-        e.writeLong(statFsData.getAvailableBytes());
-        e.writeLong(statFsData.getTotalBytes());
-        pulledData.add(e);
-
-        e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE);
-        e.writeLong(statFsCache.getAvailableBytes());
-        e.writeLong(statFsCache.getTotalBytes());
-        pulledData.add(e);
-
-        e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM);
-        e.writeLong(statFsSystem.getAvailableBytes());
-        e.writeLong(statFsSystem.getTotalBytes());
-        pulledData.add(e);
-    }
-
-    private void pullAppSize(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        try {
-            String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
-            JSONObject json = new JSONObject(jsonStr);
-            long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
-            JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
-            JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
-            JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
-            JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
-            // Sanity check: Ensure all 4 lists have the same length.
-            int length = pkg_names.length();
-            if (app_sizes.length() != length || app_data_sizes.length() != length
-                    || app_cache_sizes.length() != length) {
-                Slog.e(TAG, "formatting error in diskstats cache file!");
-                return;
-            }
-            for (int i = 0; i < length; i++) {
-                StatsLogEventWrapper e =
-                        new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-                e.writeString(pkg_names.getString(i));
-                e.writeLong(app_sizes.optLong(i, -1L));
-                e.writeLong(app_data_sizes.optLong(i, -1L));
-                e.writeLong(app_cache_sizes.optLong(i, -1L));
-                e.writeLong(cache_time);
-                pulledData.add(e);
-            }
-        } catch (IOException | JSONException e) {
-            Slog.e(TAG, "exception reading diskstats cache file", e);
-        }
-    }
-
-    private void pullCategorySize(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        try {
-            String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
-            JSONObject json = new JSONObject(jsonStr);
-            long cacheTime = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
-
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE);
-            e.writeLong(json.optLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE);
-            e.writeLong(json.optLong(DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE);
-            e.writeLong(json.optLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS);
-            e.writeLong(json.optLong(DiskStatsFileLogger.PHOTOS_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS);
-            e.writeLong(json.optLong(DiskStatsFileLogger.VIDEOS_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO);
-            e.writeLong(json.optLong(DiskStatsFileLogger.AUDIO_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS);
-            e.writeLong(json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM);
-            e.writeLong(json.optLong(DiskStatsFileLogger.SYSTEM_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-
-            e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER);
-            e.writeLong(json.optLong(DiskStatsFileLogger.MISC_KEY, -1L));
-            e.writeLong(cacheTime);
-            pulledData.add(e);
-        } catch (IOException | JSONException e) {
-            Slog.e(TAG, "exception reading diskstats cache file", e);
-        }
-    }
-
-    private void pullNumBiometricsEnrolled(int modality, int tagId, long elapsedNanos,
-            long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
-        final PackageManager pm = mContext.getPackageManager();
-        FingerprintManager fingerprintManager = null;
-        FaceManager faceManager = null;
-
-        if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
-            fingerprintManager = mContext.getSystemService(
-                    FingerprintManager.class);
-        }
-        if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
-            faceManager = mContext.getSystemService(FaceManager.class);
-        }
-
-        if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
-            return;
-        }
-        if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
-            return;
-        }
-        UserManager userManager = mContext.getSystemService(UserManager.class);
-        if (userManager == null) {
-            return;
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        for (UserInfo user : userManager.getUsers()) {
-            final int userId = user.getUserHandle().getIdentifier();
-            int numEnrolled = 0;
-            if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
-                numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
-            } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
-                numEnrolled = faceManager.getEnrolledFaces(userId).size();
-            } else {
-                return;
-            }
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(userId);
-            e.writeInt(numEnrolled);
-            pulledData.add(e);
-        }
-        Binder.restoreCallingIdentity(token);
-    }
-
     // read high watermark for section
     private long readProcStatsHighWaterMark(int section) {
         try {
@@ -1024,39 +765,6 @@
         }
     }
 
-    private INotificationManager mNotificationManager =
-            INotificationManager.Stub.asInterface(
-                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
-
-    private void pullNotificationStats(int reportId, int tagId, long elapsedNanos,
-            long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        final long callingToken = Binder.clearCallingIdentity();
-        try {
-            // determine last pull tine. Copy file trick from pullProcessStats?
-            long lastNotificationStatsNs = wallClockNanos -
-                    TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
-
-            List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
-            long notificationStatsNs = mNotificationManager.pullStats(
-                    lastNotificationStatsNs, reportId, true, statsFiles);
-            if (statsFiles.size() != 1) {
-                return;
-            }
-            unpackStreamedData(tagId, elapsedNanos, wallClockNanos, pulledData, statsFiles);
-        } catch (IOException e) {
-            Log.e(TAG, "Getting notistats failed: ", e);
-
-        } catch (RemoteException e) {
-            Log.e(TAG, "Getting notistats failed: ", e);
-        } catch (SecurityException e) {
-            Log.e(TAG, "Getting notistats failed: ", e);
-        } finally {
-            Binder.restoreCallingIdentity(callingToken);
-        }
-
-    }
-
     static void unpackStreamedData(int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData, List<ParcelFileDescriptor> statsFiles)
             throws IOException {
@@ -1098,104 +806,6 @@
         }
     }
 
-    private void pullDiskIo(int tagId, long elapsedNanos, final long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
-                fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
-                fgFsync, bgFsync) -> {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
-                    wallClockNanos);
-            e.writeInt(uid);
-            e.writeLong(fgCharsRead);
-            e.writeLong(fgCharsWrite);
-            e.writeLong(fgBytesRead);
-            e.writeLong(fgBytesWrite);
-            e.writeLong(bgCharsRead);
-            e.writeLong(bgCharsWrite);
-            e.writeLong(bgBytesRead);
-            e.writeLong(bgBytesWrite);
-            e.writeLong(fgFsync);
-            e.writeLong(bgFsync);
-            pulledData.add(e);
-        });
-    }
-
-    private void pullProcessCpuTime(int tagId, long elapsedNanos, final long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        synchronized (this) {
-            if (mProcessCpuTracker == null) {
-                mProcessCpuTracker = new ProcessCpuTracker(false);
-                mProcessCpuTracker.init();
-            }
-            mProcessCpuTracker.update();
-            for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
-                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
-                StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
-                        wallClockNanos);
-                e.writeInt(st.uid);
-                e.writeString(st.name);
-                e.writeLong(st.base_utime);
-                e.writeLong(st.base_stime);
-                pulledData.add(e);
-            }
-        }
-    }
-
-    private void pullCpuTimePerThreadFreq(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        if (this.mKernelCpuThreadReader == null) {
-            throw new IllegalStateException("mKernelCpuThreadReader is null");
-        }
-        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
-                this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
-        if (processCpuUsages == null) {
-            throw new IllegalStateException("processCpuUsages is null");
-        }
-        int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
-        if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
-            String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
-                    + " frequencies, but got " + cpuFrequencies.length;
-            Slog.w(TAG, message);
-            throw new IllegalStateException(message);
-        }
-        for (int i = 0; i < processCpuUsages.size(); i++) {
-            KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
-            ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
-                    processCpuUsage.threadCpuUsages;
-            for (int j = 0; j < threadCpuUsages.size(); j++) {
-                KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
-                if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
-                    String message = "Unexpected number of usage times,"
-                            + " expected " + cpuFrequencies.length
-                            + " but got " + threadCpuUsage.usageTimesMillis.length;
-                    Slog.w(TAG, message);
-                    throw new IllegalStateException(message);
-                }
-
-                StatsLogEventWrapper e =
-                        new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-                e.writeInt(processCpuUsage.uid);
-                e.writeInt(processCpuUsage.processId);
-                e.writeInt(threadCpuUsage.threadId);
-                e.writeString(processCpuUsage.processName);
-                e.writeString(threadCpuUsage.threadName);
-                for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
-                    if (k < cpuFrequencies.length) {
-                        e.writeInt(cpuFrequencies[k]);
-                        e.writeInt(threadCpuUsage.usageTimesMillis[k]);
-                    } else {
-                        // If we have no more frequencies to write, we still must write empty data.
-                        // We know that this data is empty (and not just zero) because all
-                        // frequencies are expected to be greater than zero
-                        e.writeInt(0);
-                        e.writeInt(0);
-                    }
-                }
-                pulledData.add(e);
-            }
-        }
-    }
-
     private void pullDebugElapsedClock(int tagId,
             long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
         final long elapsedMillis = SystemClock.elapsedRealtime();
@@ -1246,283 +856,6 @@
         pulledData.add(e);
     }
 
-    private void pullDangerousPermissionState(int atomId, long elapsedNanos,
-            final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
-        long token = Binder.clearCallingIdentity();
-        Set<Integer> reportedUids = new HashSet<>();
-        try {
-            PackageManager pm = mContext.getPackageManager();
-
-            List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
-
-            int numUsers = users.size();
-            for (int userNum = 0; userNum < numUsers; userNum++) {
-                UserHandle user = users.get(userNum).getUserHandle();
-
-                List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
-                        PackageManager.GET_PERMISSIONS, user.getIdentifier());
-
-                int numPkgs = pkgs.size();
-                for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
-                    PackageInfo pkg = pkgs.get(pkgNum);
-
-                    if (pkg.requestedPermissions == null) {
-                        continue;
-                    }
-
-                    if (reportedUids.contains(pkg.applicationInfo.uid)) {
-                        // do not report same uid twice
-                        continue;
-                    }
-                    reportedUids.add(pkg.applicationInfo.uid);
-
-                    if (atomId == StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
-                            && ThreadLocalRandom.current().nextFloat() > 0.2f) {
-                        continue;
-                    }
-
-                    int numPerms = pkg.requestedPermissions.length;
-                    for (int permNum  = 0; permNum < numPerms; permNum++) {
-                        String permName = pkg.requestedPermissions[permNum];
-
-                        PermissionInfo permissionInfo;
-                        int permissionFlags = 0;
-                        try {
-                            permissionInfo = pm.getPermissionInfo(permName, 0);
-                            permissionFlags =
-                                    pm.getPermissionFlags(permName, pkg.packageName, user);
-
-                        } catch (PackageManager.NameNotFoundException ignored) {
-                            continue;
-                        }
-
-                        if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
-                            continue;
-                        }
-
-                        StatsLogEventWrapper e = new StatsLogEventWrapper(
-                                atomId, elapsedNanos, wallClockNanos);
-
-                        e.writeString(permName);
-                        e.writeInt(pkg.applicationInfo.uid);
-                        if (atomId == StatsLog.DANGEROUS_PERMISSION_STATE) {
-                            e.writeString(null);
-                        }
-                        e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
-                                & REQUESTED_PERMISSION_GRANTED) != 0);
-                        e.writeInt(permissionFlags);
-
-                        pulledData.add(e);
-                    }
-                }
-            }
-        } catch (Throwable t) {
-            Log.e(TAG, "Could not read permissions", t);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    private void pullAppOps(long elapsedNanos, final long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        long token = Binder.clearCallingIdentity();
-        try {
-            AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
-
-            CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
-            HistoricalOpsRequest histOpsRequest =
-                    new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).build();
-            appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
-
-            HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
-                    TimeUnit.MILLISECONDS);
-
-            for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
-                final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
-                final int uid = uidOps.getUid();
-                for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
-                    final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
-                    for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
-                        final AppOpsManager.HistoricalOp op  = packageOps.getOpAt(opIdx);
-                        StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.APP_OPS,
-                                elapsedNanos, wallClockNanos);
-
-                        e.writeInt(uid);
-                        e.writeString(packageOps.getPackageName());
-                        e.writeInt(op.getOpCode());
-                        e.writeLong(op.getForegroundAccessCount(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getForegroundRejectCount(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
-                        e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
-
-                        String perm = AppOpsManager.opToPermission(op.getOpCode());
-                        if (perm == null) {
-                            e.writeBoolean(false);
-                        } else {
-                            PermissionInfo permInfo;
-                            try {
-                                permInfo = mContext.getPackageManager().getPermissionInfo(perm, 0);
-                                e.writeBoolean(permInfo.getProtection() == PROTECTION_DANGEROUS);
-                            } catch (PackageManager.NameNotFoundException exception) {
-                                e.writeBoolean(false);
-                            }
-                        }
-
-                        pulledData.add(e);
-                    }
-                }
-            }
-        } catch (Throwable t) {
-            Log.e(TAG, "Could not read appops", t);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-
-    /**
-     * Add a RoleHolder atom for each package that holds a role.
-     *
-     * @param elapsedNanos the time since boot
-     * @param wallClockNanos the time on the clock
-     * @param pulledData the data sink to write to
-     */
-    private void pullRoleHolders(long elapsedNanos, final long wallClockNanos,
-            @NonNull List<StatsLogEventWrapper> pulledData) {
-        long callingToken = Binder.clearCallingIdentity();
-        try {
-            PackageManager pm = mContext.getPackageManager();
-            RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
-
-            List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
-
-            int numUsers = users.size();
-            for (int userNum = 0; userNum < numUsers; userNum++) {
-                int userId = users.get(userNum).getUserHandle().getIdentifier();
-
-                ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(
-                        userId);
-
-                int numRoles = roles.size();
-                for (int roleNum = 0; roleNum < numRoles; roleNum++) {
-                    String roleName = roles.keyAt(roleNum);
-                    ArraySet<String> holders = roles.valueAt(roleNum);
-
-                    int numHolders = holders.size();
-                    for (int holderNum = 0; holderNum < numHolders; holderNum++) {
-                        String holderName = holders.valueAt(holderNum);
-
-                        PackageInfo pkg;
-                        try {
-                            pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
-                        } catch (PackageManager.NameNotFoundException e) {
-                            Log.w(TAG, "Role holder " + holderName + " not found");
-                            return;
-                        }
-
-                        StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.ROLE_HOLDER,
-                                elapsedNanos, wallClockNanos);
-                        e.writeInt(pkg.applicationInfo.uid);
-                        e.writeString(holderName);
-                        e.writeString(roleName);
-                        pulledData.add(e);
-                    }
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(callingToken);
-        }
-    }
-
-    private void pullTimeZoneDataInfo(int tagId,
-            long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
-        String tzDbVersion = "Unknown";
-        try {
-            tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
-        } catch (Exception e) {
-            Log.e(TAG, "Getting tzdb version failed: ", e);
-        }
-
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-        e.writeString(tzDbVersion);
-        pulledData.add(e);
-    }
-
-    private void pullExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        StorageManager storageManager = mContext.getSystemService(StorageManager.class);
-        if (storageManager != null) {
-            List<VolumeInfo> volumes = storageManager.getVolumes();
-            for (VolumeInfo vol : volumes) {
-                final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
-                final DiskInfo diskInfo = vol.getDisk();
-                if (diskInfo != null) {
-                    if (envState.equals(Environment.MEDIA_MOUNTED)) {
-                        // Get the type of the volume, if it is adoptable or portable.
-                        int volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
-                        if (vol.getType() == TYPE_PUBLIC) {
-                            volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
-                        } else if (vol.getType() == TYPE_PRIVATE) {
-                            volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
-                        }
-                        // Get the type of external storage inserted in the device (sd cards,
-                        // usb, etc)
-                        int externalStorageType;
-                        if (diskInfo.isSd()) {
-                            externalStorageType = StorageEnums.SD_CARD;
-                        } else if (diskInfo.isUsb()) {
-                            externalStorageType = StorageEnums.USB;
-                        } else {
-                            externalStorageType = StorageEnums.OTHER;
-                        }
-                        StatsLogEventWrapper e =
-                                new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-                        e.writeInt(externalStorageType);
-                        e.writeInt(volumeType);
-                        e.writeLong(diskInfo.size);
-                        pulledData.add(e);
-                    }
-                }
-            }
-        }
-    }
-
-    private void pullAppsOnExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos,
-            List<StatsLogEventWrapper> pulledData) {
-        PackageManager pm = mContext.getPackageManager();
-        StorageManager storage = mContext.getSystemService(StorageManager.class);
-        List<ApplicationInfo> apps = pm.getInstalledApplications(/* flags = */ 0);
-        for (ApplicationInfo appInfo : apps) {
-            UUID storageUuid = appInfo.storageUuid;
-            if (storageUuid != null) {
-                VolumeInfo volumeInfo = storage.findVolumeByUuid(appInfo.storageUuid.toString());
-                if (volumeInfo != null) {
-                    DiskInfo diskInfo = volumeInfo.getDisk();
-                    if (diskInfo != null) {
-                        int externalStorageType = -1;
-                        if (diskInfo.isSd()) {
-                            externalStorageType = StorageEnums.SD_CARD;
-                        } else if (diskInfo.isUsb()) {
-                            externalStorageType = StorageEnums.USB;
-                        } else if (appInfo.isExternal()) {
-                            externalStorageType = StorageEnums.OTHER;
-                        }
-                        // App is installed on external storage.
-                        if (externalStorageType != -1) {
-                            StatsLogEventWrapper e =
-                                    new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-                            e.writeInt(externalStorageType);
-                            e.writeString(appInfo.packageName);
-                            pulledData.add(e);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
     private void pullFaceSettings(int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
         long callingToken = Binder.clearCallingIdentity();
@@ -1574,48 +907,6 @@
         long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
         switch (tagId) {
 
-            case StatsLog.SYSTEM_ELAPSED_REALTIME: {
-                pullSystemElapsedRealtime(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.LOOPER_STATS: {
-                pullLooperStats(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.DISK_STATS: {
-                pullDiskStats(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.DIRECTORY_USAGE: {
-                pullDirectoryUsage(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.APP_SIZE: {
-                pullAppSize(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.CATEGORY_SIZE: {
-                pullCategorySize(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.NUM_FINGERPRINTS_ENROLLED: {
-                pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FINGERPRINT, tagId,
-                        elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.NUM_FACES_ENROLLED: {
-                pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FACE, tagId, elapsedNanos,
-                        wallClockNanos, ret);
-                break;
-            }
-
             case StatsLog.PROC_STATS: {
                 pullProcessStats(ProcessStats.REPORT_ALL, tagId, elapsedNanos, wallClockNanos, ret);
                 break;
@@ -1627,20 +918,6 @@
                 break;
             }
 
-            case StatsLog.DISK_IO: {
-                pullDiskIo(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.PROCESS_CPU_TIME: {
-                pullProcessCpuTime(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-            case StatsLog.CPU_TIME_PER_THREAD_FREQ: {
-                pullCpuTimePerThreadFreq(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
             case StatsLog.DEBUG_ELAPSED_CLOCK: {
                 pullDebugElapsedClock(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
@@ -1651,54 +928,11 @@
                 break;
             }
 
-            case StatsLog.ROLE_HOLDER: {
-                pullRoleHolders(elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.DANGEROUS_PERMISSION_STATE: {
-                pullDangerousPermissionState(StatsLog.DANGEROUS_PERMISSION_STATE, elapsedNanos,
-                        wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED: {
-                pullDangerousPermissionState(StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED,
-                        elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.TIME_ZONE_DATA_INFO: {
-                pullTimeZoneDataInfo(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.EXTERNAL_STORAGE_INFO: {
-                pullExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO: {
-                pullAppsOnExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
             case StatsLog.FACE_SETTINGS: {
                 pullFaceSettings(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
 
-            case StatsLog.APP_OPS: {
-                pullAppOps(elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
-            case StatsLog.NOTIFICATION_REMOTE_VIEWS: {
-                pullNotificationStats(NotificationManagerService.REPORT_REMOTE_VIEWS,
-                        tagId, elapsedNanos, wallClockNanos, ret);
-                break;
-            }
-
             default:
                 Slog.w(TAG, "No such tagId data as " + tagId);
                 return null;
diff --git a/api/current.txt b/api/current.txt
index 0812019..e662783 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7451,6 +7451,41 @@
 
 }
 
+package android.app.blob {
+
+  public final class BlobHandle implements android.os.Parcelable {
+    method @NonNull public static android.app.blob.BlobHandle createWithSha256(@NonNull byte[], @NonNull CharSequence, long, @NonNull String);
+    method public int describeContents();
+    method public long getExpiryTimeMillis();
+    method @NonNull public CharSequence getLabel();
+    method @NonNull public byte[] getSha256Digest();
+    method @NonNull public String getTag();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.blob.BlobHandle> CREATOR;
+  }
+
+  public class BlobStoreManager {
+    method public void acquireLease(@NonNull android.app.blob.BlobHandle, @IdRes int, long) throws java.io.IOException;
+    method public void acquireLease(@NonNull android.app.blob.BlobHandle, @IdRes int) throws java.io.IOException;
+    method @IntRange(from=1) public long createSession(@NonNull android.app.blob.BlobHandle) throws java.io.IOException;
+    method @NonNull public android.os.ParcelFileDescriptor openBlob(@NonNull android.app.blob.BlobHandle) throws java.io.IOException;
+    method @NonNull public android.app.blob.BlobStoreManager.Session openSession(@IntRange(from=1) long) throws java.io.IOException;
+    method public void releaseLease(@NonNull android.app.blob.BlobHandle) throws java.io.IOException;
+  }
+
+  public static class BlobStoreManager.Session implements java.io.Closeable {
+    method public void abandon() throws java.io.IOException;
+    method public void allowPackageAccess(@NonNull String, @NonNull byte[]) throws java.io.IOException;
+    method public void allowPublicAccess() throws java.io.IOException;
+    method public void allowSameSignatureAccess() throws java.io.IOException;
+    method public void close() throws java.io.IOException;
+    method public void commit(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws java.io.IOException;
+    method public long getSize() throws java.io.IOException;
+    method @NonNull public android.os.ParcelFileDescriptor openWrite(long, long) throws java.io.IOException;
+  }
+
+}
+
 package android.app.job {
 
   public class JobInfo implements android.os.Parcelable {
@@ -18266,6 +18301,7 @@
     field public static final int RIGHT = 7; // 0x7
     field public static final int TOP = 8; // 0x8
     field public static final int TOP_AND_BOTTOM = 9; // 0x9
+    field public static final int TOP_AND_BOTTOM_AND_LEFT = 15; // 0xf
     field public static final int TOP_AND_BOTTOM_AND_RIGHT = 10; // 0xa
     field public static final int TOP_AND_LEFT = 11; // 0xb
     field public static final int TOP_AND_LEFT_AND_RIGHT = 12; // 0xc
@@ -18588,6 +18624,7 @@
     field public static final int CHEROKEE_SUPPLEMENT_ID = 255; // 0xff
     field public static final android.icu.lang.UCharacter.UnicodeBlock CHESS_SYMBOLS;
     field public static final int CHESS_SYMBOLS_ID = 281; // 0x119
+    field public static final int CHORASMIAN_ID = 301; // 0x12d
     field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_COMPATIBILITY;
     field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_COMPATIBILITY_FORMS;
     field public static final int CJK_COMPATIBILITY_FORMS_ID = 83; // 0x53
@@ -18615,6 +18652,7 @@
     field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_E_ID = 256; // 0x100
     field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F;
     field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F_ID = 274; // 0x112
+    field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G_ID = 302; // 0x12e
     field public static final int CJK_UNIFIED_IDEOGRAPHS_ID = 71; // 0x47
     field public static final android.icu.lang.UCharacter.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
     field public static final android.icu.lang.UCharacter.UnicodeBlock COMBINING_DIACRITICAL_MARKS_EXTENDED;
@@ -18664,6 +18702,7 @@
     field public static final int DEVANAGARI_ID = 15; // 0xf
     field public static final android.icu.lang.UCharacter.UnicodeBlock DINGBATS;
     field public static final int DINGBATS_ID = 56; // 0x38
+    field public static final int DIVES_AKURU_ID = 303; // 0x12f
     field public static final android.icu.lang.UCharacter.UnicodeBlock DOGRA;
     field public static final int DOGRA_ID = 282; // 0x11a
     field public static final android.icu.lang.UCharacter.UnicodeBlock DOMINO_TILES;
@@ -18792,6 +18831,8 @@
     field public static final int KAYAH_LI_ID = 162; // 0xa2
     field public static final android.icu.lang.UCharacter.UnicodeBlock KHAROSHTHI;
     field public static final int KHAROSHTHI_ID = 137; // 0x89
+    field public static final android.icu.lang.UCharacter.UnicodeBlock KHITAN_SMALL_SCRIPT;
+    field public static final int KHITAN_SMALL_SCRIPT_ID = 304; // 0x130
     field public static final android.icu.lang.UCharacter.UnicodeBlock KHMER;
     field public static final int KHMER_ID = 36; // 0x24
     field public static final android.icu.lang.UCharacter.UnicodeBlock KHMER_SYMBOLS;
@@ -18830,6 +18871,8 @@
     field public static final int LINEAR_B_SYLLABARY_ID = 117; // 0x75
     field public static final android.icu.lang.UCharacter.UnicodeBlock LISU;
     field public static final int LISU_ID = 176; // 0xb0
+    field public static final android.icu.lang.UCharacter.UnicodeBlock LISU_SUPPLEMENT;
+    field public static final int LISU_SUPPLEMENT_ID = 305; // 0x131
     field public static final android.icu.lang.UCharacter.UnicodeBlock LOW_SURROGATES;
     field public static final int LOW_SURROGATES_ID = 77; // 0x4d
     field public static final android.icu.lang.UCharacter.UnicodeBlock LYCIAN;
@@ -19041,6 +19084,8 @@
     field public static final int SYLOTI_NAGRI_ID = 143; // 0x8f
     field public static final android.icu.lang.UCharacter.UnicodeBlock SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A;
     field public static final int SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A_ID = 298; // 0x12a
+    field public static final android.icu.lang.UCharacter.UnicodeBlock SYMBOLS_FOR_LEGACY_COMPUTING;
+    field public static final int SYMBOLS_FOR_LEGACY_COMPUTING_ID = 306; // 0x132
     field public static final android.icu.lang.UCharacter.UnicodeBlock SYRIAC;
     field public static final int SYRIAC_ID = 13; // 0xd
     field public static final android.icu.lang.UCharacter.UnicodeBlock SYRIAC_SUPPLEMENT;
@@ -19069,6 +19114,8 @@
     field public static final android.icu.lang.UCharacter.UnicodeBlock TANGUT_COMPONENTS;
     field public static final int TANGUT_COMPONENTS_ID = 273; // 0x111
     field public static final int TANGUT_ID = 272; // 0x110
+    field public static final android.icu.lang.UCharacter.UnicodeBlock TANGUT_SUPPLEMENT;
+    field public static final int TANGUT_SUPPLEMENT_ID = 307; // 0x133
     field public static final android.icu.lang.UCharacter.UnicodeBlock TELUGU;
     field public static final int TELUGU_ID = 21; // 0x15
     field public static final android.icu.lang.UCharacter.UnicodeBlock THAANA;
@@ -19103,6 +19150,8 @@
     field public static final int WANCHO_ID = 300; // 0x12c
     field public static final android.icu.lang.UCharacter.UnicodeBlock WARANG_CITI;
     field public static final int WARANG_CITI_ID = 252; // 0xfc
+    field public static final android.icu.lang.UCharacter.UnicodeBlock YEZIDI;
+    field public static final int YEZIDI_ID = 308; // 0x134
     field public static final android.icu.lang.UCharacter.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
     field public static final int YIJING_HEXAGRAM_SYMBOLS_ID = 116; // 0x74
     field public static final android.icu.lang.UCharacter.UnicodeBlock YI_RADICALS;
@@ -19399,6 +19448,7 @@
     field public static final int CHAKMA = 118; // 0x76
     field public static final int CHAM = 66; // 0x42
     field public static final int CHEROKEE = 6; // 0x6
+    field public static final int CHORASMIAN = 189; // 0xbd
     field public static final int CIRTH = 67; // 0x43
     field public static final int COMMON = 0; // 0x0
     field public static final int COPTIC = 7; // 0x7
@@ -19408,6 +19458,7 @@
     field public static final int DEMOTIC_EGYPTIAN = 69; // 0x45
     field public static final int DESERET = 9; // 0x9
     field public static final int DEVANAGARI = 10; // 0xa
+    field public static final int DIVES_AKURU = 190; // 0xbe
     field public static final int DOGRA = 178; // 0xb2
     field public static final int DUPLOYAN = 135; // 0x87
     field public static final int EASTERN_SYRIAC = 97; // 0x61
@@ -19449,6 +19500,7 @@
     field public static final int KATAKANA_OR_HIRAGANA = 54; // 0x36
     field public static final int KAYAH_LI = 79; // 0x4f
     field public static final int KHAROSHTHI = 57; // 0x39
+    field public static final int KHITAN_SMALL_SCRIPT = 191; // 0xbf
     field public static final int KHMER = 23; // 0x17
     field public static final int KHOJKI = 157; // 0x9d
     field public static final int KHUDAWADI = 145; // 0x91
@@ -19566,6 +19618,7 @@
     field public static final int WARANG_CITI = 146; // 0x92
     field public static final int WESTERN_SYRIAC = 96; // 0x60
     field public static final int WOLEAI = 155; // 0x9b
+    field public static final int YEZIDI = 192; // 0xc0
     field public static final int YI = 41; // 0x29
     field public static final int ZANABAZAR_SQUARE = 177; // 0xb1
   }
@@ -24346,28 +24399,39 @@
     method public static boolean hasProfile(int, int);
     field public static final int QUALITY_1080P = 6; // 0x6
     field public static final int QUALITY_2160P = 8; // 0x8
+    field public static final int QUALITY_2K = 12; // 0xc
     field public static final int QUALITY_480P = 4; // 0x4
+    field public static final int QUALITY_4KDCI = 10; // 0xa
     field public static final int QUALITY_720P = 5; // 0x5
     field public static final int QUALITY_CIF = 3; // 0x3
     field public static final int QUALITY_HIGH = 1; // 0x1
     field public static final int QUALITY_HIGH_SPEED_1080P = 2004; // 0x7d4
     field public static final int QUALITY_HIGH_SPEED_2160P = 2005; // 0x7d5
     field public static final int QUALITY_HIGH_SPEED_480P = 2002; // 0x7d2
+    field public static final int QUALITY_HIGH_SPEED_4KDCI = 2008; // 0x7d8
     field public static final int QUALITY_HIGH_SPEED_720P = 2003; // 0x7d3
+    field public static final int QUALITY_HIGH_SPEED_CIF = 2006; // 0x7d6
     field public static final int QUALITY_HIGH_SPEED_HIGH = 2001; // 0x7d1
     field public static final int QUALITY_HIGH_SPEED_LOW = 2000; // 0x7d0
+    field public static final int QUALITY_HIGH_SPEED_VGA = 2007; // 0x7d7
     field public static final int QUALITY_LOW = 0; // 0x0
     field public static final int QUALITY_QCIF = 2; // 0x2
+    field public static final int QUALITY_QHD = 11; // 0xb
     field public static final int QUALITY_QVGA = 7; // 0x7
     field public static final int QUALITY_TIME_LAPSE_1080P = 1006; // 0x3ee
     field public static final int QUALITY_TIME_LAPSE_2160P = 1008; // 0x3f0
+    field public static final int QUALITY_TIME_LAPSE_2K = 1012; // 0x3f4
     field public static final int QUALITY_TIME_LAPSE_480P = 1004; // 0x3ec
+    field public static final int QUALITY_TIME_LAPSE_4KDCI = 1010; // 0x3f2
     field public static final int QUALITY_TIME_LAPSE_720P = 1005; // 0x3ed
     field public static final int QUALITY_TIME_LAPSE_CIF = 1003; // 0x3eb
     field public static final int QUALITY_TIME_LAPSE_HIGH = 1001; // 0x3e9
     field public static final int QUALITY_TIME_LAPSE_LOW = 1000; // 0x3e8
     field public static final int QUALITY_TIME_LAPSE_QCIF = 1002; // 0x3ea
+    field public static final int QUALITY_TIME_LAPSE_QHD = 1011; // 0x3f3
     field public static final int QUALITY_TIME_LAPSE_QVGA = 1007; // 0x3ef
+    field public static final int QUALITY_TIME_LAPSE_VGA = 1009; // 0x3f1
+    field public static final int QUALITY_VGA = 9; // 0x9
     field public int audioBitRate;
     field public int audioChannels;
     field public int audioCodec;
@@ -30203,6 +30267,7 @@
     method public void close();
     method public void continueCall(int) throws android.net.sip.SipException;
     method public void endCall() throws android.net.sip.SipException;
+    method @Nullable public android.net.rtp.AudioGroup getAudioGroup();
     method public android.net.sip.SipProfile getLocalProfile();
     method public android.net.sip.SipProfile getPeerProfile();
     method public int getState();
@@ -30213,6 +30278,7 @@
     method public void makeCall(android.net.sip.SipProfile, android.net.sip.SipSession, int) throws android.net.sip.SipException;
     method public void sendDtmf(int);
     method public void sendDtmf(int, android.os.Message);
+    method public void setAudioGroup(@NonNull android.net.rtp.AudioGroup);
     method public void setListener(android.net.sip.SipAudioCall.Listener);
     method public void setListener(android.net.sip.SipAudioCall.Listener, boolean);
     method public void setSpeakerMode(boolean);
@@ -30261,6 +30327,7 @@
     method public void close(String) throws android.net.sip.SipException;
     method public android.net.sip.SipSession createSipSession(android.net.sip.SipProfile, android.net.sip.SipSession.Listener) throws android.net.sip.SipException;
     method public static String getCallId(android.content.Intent);
+    method @NonNull public java.util.List<android.net.sip.SipProfile> getListOfProfiles() throws android.net.sip.SipException;
     method public static String getOfferSessionDescription(android.content.Intent);
     method public android.net.sip.SipSession getSessionFor(android.content.Intent) throws android.net.sip.SipException;
     method public static boolean isApiSupported(android.content.Context);
@@ -30278,6 +30345,11 @@
     method public void setRegistrationListener(String, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
     method public android.net.sip.SipAudioCall takeAudioCall(android.content.Intent, android.net.sip.SipAudioCall.Listener) throws android.net.sip.SipException;
     method public void unregister(android.net.sip.SipProfile, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+    field public static final String ACTION_SIP_CALL_OPTION_CHANGED = "android.net.sip.action.SIP_CALL_OPTION_CHANGED";
+    field public static final String ACTION_SIP_INCOMING_CALL = "android.net.sip.action.SIP_INCOMING_CALL";
+    field public static final String ACTION_SIP_REMOVE_PROFILE = "android.net.sip.action.SIP_REMOVE_PROFILE";
+    field public static final String ACTION_SIP_SERVICE_UP = "android.net.sip.action.SIP_SERVICE_UP";
+    field public static final String ACTION_START_SIP = "android.net.sip.action.START_SIP";
     field public static final String EXTRA_CALL_ID = "android:sipCallID";
     field public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
     field public static final int INCOMING_CALL_RESULT_CODE = 101; // 0x65
@@ -30287,6 +30359,7 @@
     method public int describeContents();
     method public String getAuthUserName();
     method public boolean getAutoRegistration();
+    method public int getCallingUid();
     method public String getDisplayName();
     method public String getPassword();
     method public int getPort();
@@ -30297,6 +30370,7 @@
     method public String getSipDomain();
     method public String getUriString();
     method public String getUserName();
+    method public void setCallingUid(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.sip.SipProfile> CREATOR;
   }
@@ -45043,6 +45117,8 @@
 package android.telephony {
 
   public final class AccessNetworkConstants {
+    field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
+    field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
   }
 
   public static final class AccessNetworkConstants.AccessNetworkType {
@@ -45391,6 +45467,7 @@
     field public static final String KEY_MMS_ALIAS_MIN_CHARS_INT = "aliasMinChars";
     field public static final String KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL = "allowAttachAudio";
     field public static final String KEY_MMS_APPEND_TRANSACTION_ID_BOOL = "enabledTransID";
+    field public static final String KEY_MMS_CLOSE_CONNECTION_BOOL = "mmsCloseConnection";
     field public static final String KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING = "emailGatewayNumber";
     field public static final String KEY_MMS_GROUP_MMS_ENABLED_BOOL = "enableGroupMms";
     field public static final String KEY_MMS_HTTP_PARAMS_STRING = "httpParams";
@@ -45588,7 +45665,8 @@
     method public int getCellConnectionStatus();
     method @NonNull public abstract android.telephony.CellIdentity getCellIdentity();
     method @NonNull public abstract android.telephony.CellSignalStrength getCellSignalStrength();
-    method public long getTimeStamp();
+    method @Deprecated public long getTimeStamp();
+    method public long getTimestampNanos();
     method public boolean isRegistered();
     field public static final int CONNECTION_NONE = 0; // 0x0
     field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1
@@ -45828,6 +45906,35 @@
     field @Deprecated public static final int UNKNOWN_RSSI = 99; // 0x63
   }
 
+  public final class NetworkRegistrationInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getAccessNetworkTechnology();
+    method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
+    method @Nullable public android.telephony.CellIdentity getCellIdentity();
+    method public int getDomain();
+    method public int getNrState();
+    method public int getTransportType();
+    method public boolean isRegistered();
+    method public boolean isRoaming();
+    method public boolean isSearching();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
+    field public static final int DOMAIN_CS = 1; // 0x1
+    field public static final int DOMAIN_CS_PS = 3; // 0x3
+    field public static final int DOMAIN_PS = 2; // 0x2
+    field public static final int DOMAIN_UNKNOWN = 0; // 0x0
+    field public static final int NR_STATE_CONNECTED = 3; // 0x3
+    field public static final int NR_STATE_NONE = 0; // 0x0
+    field public static final int NR_STATE_NOT_RESTRICTED = 2; // 0x2
+    field public static final int NR_STATE_RESTRICTED = 1; // 0x1
+    field public static final int SERVICE_TYPE_DATA = 2; // 0x2
+    field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
+    field public static final int SERVICE_TYPE_SMS = 3; // 0x3
+    field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
+    field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
+  }
+
   public class NetworkScan {
     method public void stopScan();
     field public static final int ERROR_INTERRUPTED = 10002; // 0x2712
@@ -46002,6 +46109,7 @@
     method public int getChannelNumber();
     method public int getDuplexMode();
     method public boolean getIsManualSelection();
+    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
     method public String getOperatorAlphaLong();
     method public String getOperatorAlphaShort();
     method public String getOperatorNumeric();
@@ -46038,6 +46146,7 @@
     method @Deprecated public int getGsmBitErrorRate();
     method @Deprecated public int getGsmSignalStrength();
     method public int getLevel();
+    method public long getTimestampNanos();
     method @Deprecated public boolean isGsm();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SignalStrength> CREATOR;
@@ -46060,7 +46169,9 @@
     method public void sendDataMessage(String, String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
     method @Deprecated public void sendMultimediaMessage(android.content.Context, android.net.Uri, String, android.os.Bundle, android.app.PendingIntent);
     method public void sendMultipartTextMessage(String, String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
+    method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, long);
     method public void sendTextMessage(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
+    method public void sendTextMessage(@NonNull String, @Nullable String, @NonNull String, @Nullable android.app.PendingIntent, @Nullable android.app.PendingIntent, long);
     method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.SEND_SMS}) public void sendTextMessageWithoutPersisting(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSmscAddress(@NonNull String);
     field public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
@@ -46432,6 +46543,7 @@
     method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String);
     method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String);
     method public boolean isConcurrentVoiceAndDataSupported();
+    method public boolean isDataCapable();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled();
     method public boolean isEmergencyNumber(@NonNull String);
@@ -71910,6 +72022,18 @@
     method public int lastIndexOf(@Nullable Object);
     method @NonNull public java.util.ListIterator<E> listIterator();
     method @NonNull public java.util.ListIterator<E> listIterator(int);
+    method @NonNull public static <E> java.util.List<E> of();
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull @java.lang.SafeVarargs public static <E> java.util.List<E> of(@NonNull E...);
     method public E remove(int);
     method public default void replaceAll(@NonNull java.util.function.UnaryOperator<E>);
     method public E set(int, E);
@@ -72064,6 +72188,7 @@
     method @Nullable public default V computeIfPresent(K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
     method public boolean containsKey(@Nullable Object);
     method public boolean containsValue(@Nullable Object);
+    method @NonNull public static <K, V> java.util.Map.Entry<K,V> entry(@NonNull K, @NonNull V);
     method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
     method public boolean equals(@Nullable Object);
     method public default void forEach(@NonNull java.util.function.BiConsumer<? super K,? super V>);
@@ -72073,6 +72198,18 @@
     method public boolean isEmpty();
     method @NonNull public java.util.Set<K> keySet();
     method @Nullable public default V merge(K, @NonNull V, @NonNull java.util.function.BiFunction<? super V,? super V,? extends V>);
+    method @NonNull public static <K, V> java.util.Map<K,V> of();
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull @java.lang.SafeVarargs public static <K, V> java.util.Map<K,V> ofEntries(@NonNull java.util.Map.Entry<? extends K,? extends V>...);
     method @Nullable public V put(K, V);
     method public void putAll(@NonNull java.util.Map<? extends K,? extends V>);
     method @Nullable public default V putIfAbsent(K, V);
@@ -72154,6 +72291,9 @@
   }
 
   public final class Objects {
+    method public static int checkFromIndexSize(int, int, int);
+    method public static int checkFromToIndex(int, int, int);
+    method public static int checkIndex(int, int);
     method public static <T> int compare(T, T, @NonNull java.util.Comparator<? super T>);
     method public static boolean deepEquals(@Nullable Object, @Nullable Object);
     method public static boolean equals(@Nullable Object, @Nullable Object);
@@ -72164,6 +72304,8 @@
     method @NonNull public static <T> T requireNonNull(@Nullable T);
     method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull String);
     method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull java.util.function.Supplier<java.lang.String>);
+    method @NonNull public static <T> T requireNonNullElse(@Nullable T, @NonNull T);
+    method @NonNull public static <T> T requireNonNullElseGet(@Nullable T, @NonNull java.util.function.Supplier<? extends T>);
     method @NonNull public static String toString(@Nullable Object);
     method @NonNull public static String toString(@Nullable Object, @NonNull String);
   }
@@ -72468,6 +72610,18 @@
   }
 
   public interface Set<E> extends java.util.Collection<E> {
+    method @NonNull public static <E> java.util.Set<E> of();
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull @java.lang.SafeVarargs public static <E> java.util.Set<E> of(@NonNull E...);
   }
 
   public class SimpleTimeZone extends java.util.TimeZone {
@@ -73406,6 +73560,29 @@
     method public static java.util.concurrent.ScheduledExecutorService unconfigurableScheduledExecutorService(java.util.concurrent.ScheduledExecutorService);
   }
 
+  public final class Flow {
+    method public static int defaultBufferSize();
+  }
+
+  public static interface Flow.Processor<T, R> extends java.util.concurrent.Flow.Subscriber<T> java.util.concurrent.Flow.Publisher<R> {
+  }
+
+  @java.lang.FunctionalInterface public static interface Flow.Publisher<T> {
+    method public void subscribe(java.util.concurrent.Flow.Subscriber<? super T>);
+  }
+
+  public static interface Flow.Subscriber<T> {
+    method public void onComplete();
+    method public void onError(Throwable);
+    method public void onNext(T);
+    method public void onSubscribe(java.util.concurrent.Flow.Subscription);
+  }
+
+  public static interface Flow.Subscription {
+    method public void cancel();
+    method public void request(long);
+  }
+
   public class ForkJoinPool extends java.util.concurrent.AbstractExecutorService {
     ctor public ForkJoinPool();
     ctor public ForkJoinPool(int);
diff --git a/api/lint-baseline.txt b/api/lint-baseline.txt
index 508718e..a3318c7 100644
--- a/api/lint-baseline.txt
+++ b/api/lint-baseline.txt
@@ -509,6 +509,10 @@
     
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#ELYMAIC:
     
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#KHITAN_SMALL_SCRIPT:
+    
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#LISU_SUPPLEMENT:
+    
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#NANDINAGARI:
     
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#NYIAKENG_PUACHUE_HMONG:
@@ -519,22 +523,28 @@
     
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A:
     
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#SYMBOLS_FOR_LEGACY_COMPUTING:
+    
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#TAMIL_SUPPLEMENT:
     
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#TANGUT_SUPPLEMENT:
+    
 MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#WANCHO:
     
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#YEZIDI:
+    
 MissingNullability: android.icu.text.DateTimePatternGenerator#getFieldDisplayName(int, android.icu.text.DateTimePatternGenerator.DisplayWidth):
     
 MissingNullability: android.icu.text.DateTimePatternGenerator#getFieldDisplayName(int, android.icu.text.DateTimePatternGenerator.DisplayWidth) parameter #1:
     
 MissingNullability: android.icu.util.MeasureUnit#ATMOSPHERE:
-    Missing nullability on field `ATMOSPHERE` in class `class android.icu.util.MeasureUnit`
+    
 MissingNullability: android.icu.util.MeasureUnit#PERCENT:
-    Missing nullability on field `PERCENT` in class `class android.icu.util.MeasureUnit`
+    
 MissingNullability: android.icu.util.MeasureUnit#PERMILLE:
-    Missing nullability on field `PERMILLE` in class `class android.icu.util.MeasureUnit`
+    
 MissingNullability: android.icu.util.MeasureUnit#PETABYTE:
-    Missing nullability on field `PETABYTE` in class `class android.icu.util.MeasureUnit`
+    
 MissingNullability: android.icu.util.VersionInfo#UNICODE_12_0:
     
 MissingNullability: android.icu.util.VersionInfo#UNICODE_12_1:
diff --git a/api/system-current.txt b/api/system-current.txt
index e4a16677..2dbd7f5 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5284,15 +5284,6 @@
     method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@Nullable android.net.LinkAddress);
   }
 
-  public final class StringNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
-    ctor public StringNetworkSpecifier(@NonNull String);
-    method public int describeContents();
-    method public boolean satisfiedBy(android.net.NetworkSpecifier);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.StringNetworkSpecifier> CREATOR;
-    field @NonNull public final String specifier;
-  }
-
   public final class TelephonyNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
     method public boolean satisfiedBy(android.net.NetworkSpecifier);
   }
@@ -5422,9 +5413,11 @@
   }
 
   public abstract class ChildSessionParams {
+    method public long getHardLifetime();
     method @NonNull public java.util.List<android.net.ipsec.ike.IkeTrafficSelector> getLocalTrafficSelectors();
     method @NonNull public java.util.List<android.net.ipsec.ike.IkeTrafficSelector> getRemoteTrafficSelectors();
     method @NonNull public java.util.List<android.net.ipsec.ike.ChildSaProposal> getSaProposals();
+    method public long getSoftLifetime();
   }
 
   public class IkeFqdnIdentification extends android.net.ipsec.ike.IkeIdentification {
@@ -5493,12 +5486,14 @@
   }
 
   public final class IkeSessionParams {
+    method public long getHardLifetime();
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig getLocalAuthConfig();
     method @NonNull public android.net.ipsec.ike.IkeIdentification getLocalIdentification();
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig getRemoteAuthConfig();
     method @NonNull public android.net.ipsec.ike.IkeIdentification getRemoteIdentification();
     method @NonNull public java.util.List<android.net.ipsec.ike.IkeSaProposal> getSaProposals();
     method @NonNull public java.net.InetAddress getServerAddress();
+    method public long getSoftLifetime();
     method @NonNull public android.net.IpSecManager.UdpEncapsulationSocket getUdpEncapsulationSocket();
   }
 
@@ -5510,6 +5505,7 @@
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthDigitalSignature(@Nullable java.security.cert.X509Certificate, @NonNull java.security.cert.X509Certificate, @NonNull java.util.List<java.security.cert.X509Certificate>, @NonNull java.security.PrivateKey);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthEap(@Nullable java.security.cert.X509Certificate, @NonNull android.net.eap.EapSessionConfig);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthPsk(@NonNull byte[]);
+    method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setLifetime(long, long);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setLocalIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setRemoteIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
     method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setServerAddress(@NonNull java.net.InetAddress);
@@ -5580,6 +5576,7 @@
     method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
     method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
     method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams build();
+    method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder setLifetime(long, long);
   }
 
   public final class TunnelModeChildSessionParams extends android.net.ipsec.ike.ChildSessionParams {
@@ -5597,6 +5594,7 @@
     method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
     method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
     method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams build();
+    method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder setLifetime(long, long);
   }
 
   public static interface TunnelModeChildSessionParams.ConfigRequest {
@@ -9606,8 +9604,6 @@
 
   public final class AccessNetworkConstants {
     field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
-    field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
-    field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
   }
 
   public final class BarringInfo implements android.os.Parcelable {
@@ -10252,37 +10248,18 @@
   }
 
   public final class NetworkRegistrationInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getAccessNetworkTechnology();
-    method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
-    method @Nullable public android.telephony.CellIdentity getCellIdentity();
     method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
-    method public int getDomain();
-    method public int getNrState();
     method public int getRegistrationState();
     method public int getRejectCause();
     method public int getRoamingType();
-    method public int getTransportType();
     method public boolean isEmergencyEnabled();
-    method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
-    field public static final int DOMAIN_CS = 1; // 0x1
-    field public static final int DOMAIN_CS_PS = 3; // 0x3
-    field public static final int DOMAIN_PS = 2; // 0x2
-    field public static final int DOMAIN_UNKNOWN = 0; // 0x0
     field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
     field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
     field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
     field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
     field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
     field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
-    field public static final int SERVICE_TYPE_DATA = 2; // 0x2
-    field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
-    field public static final int SERVICE_TYPE_SMS = 3; // 0x3
-    field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
-    field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
-    field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
   }
 
   public static final class NetworkRegistrationInfo.Builder {
@@ -10500,7 +10477,6 @@
     method public int getDataRegistrationState();
     method public boolean getDataRoamingFromRegistration();
     method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
-    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
     method public int getNrFrequencyRange();
@@ -10646,7 +10622,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public java.util.List<android.telephony.SmsMessage> getMessagesFromIcc();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc();
-    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+    method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int);
     field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3
@@ -10871,6 +10847,9 @@
     field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
     field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
     field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
+    field public static final int CARD_POWER_DOWN = 0; // 0x0
+    field public static final int CARD_POWER_UP = 1; // 0x1
+    field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2
     field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
@@ -11023,6 +11002,23 @@
 
 package android.telephony.data {
 
+  public class ApnSetting implements android.os.Parcelable {
+    method @NonNull public static String getApnTypesStringFromBitmask(int);
+    field public static final String TYPE_ALL_STRING = "*";
+    field public static final String TYPE_CBS_STRING = "cbs";
+    field public static final String TYPE_DEFAULT_STRING = "default";
+    field public static final String TYPE_DUN_STRING = "dun";
+    field public static final String TYPE_EMERGENCY_STRING = "emergency";
+    field public static final String TYPE_FOTA_STRING = "fota";
+    field public static final String TYPE_HIPRI_STRING = "hipri";
+    field public static final String TYPE_IA_STRING = "ia";
+    field public static final String TYPE_IMS_STRING = "ims";
+    field public static final String TYPE_MCX_STRING = "mcx";
+    field public static final String TYPE_MMS_STRING = "mms";
+    field public static final String TYPE_SUPL_STRING = "supl";
+    field public static final String TYPE_XCAP_STRING = "xcap";
+  }
+
   public final class DataCallResponse implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
@@ -11335,6 +11331,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @Nullable public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
     method public static int getVideoStateFromCallType(int);
@@ -11837,6 +11834,9 @@
     method public boolean isCapable(int);
     method public boolean isCapable(@NonNull String);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int CAPABILITY_CALL_COMPOSER = 4194304; // 0x400000
+    field public static final int CAPABILITY_CHAT_BOT = 67108864; // 0x4000000
+    field public static final int CAPABILITY_CHAT_BOT_ROLE = 134217728; // 0x8000000
     field public static final int CAPABILITY_CHAT_SESSION = 2; // 0x2
     field public static final int CAPABILITY_CHAT_SESSION_STORE_FORWARD = 4; // 0x4
     field public static final int CAPABILITY_CHAT_STANDALONE = 1; // 0x1
@@ -11853,9 +11853,13 @@
     field public static final int CAPABILITY_IMAGE_SHARE = 256; // 0x100
     field public static final int CAPABILITY_IP_VIDEO_CALL = 16384; // 0x4000
     field public static final int CAPABILITY_IP_VOICE_CALL = 8192; // 0x2000
+    field public static final int CAPABILITY_PLUG_IN = 268435456; // 0x10000000
+    field public static final int CAPABILITY_POST_CALL = 8388608; // 0x800000
     field public static final int CAPABILITY_RCS_VIDEO_CALL = 1048576; // 0x100000
     field public static final int CAPABILITY_RCS_VIDEO_ONLY_CALL = 2097152; // 0x200000
     field public static final int CAPABILITY_RCS_VOICE_CALL = 524288; // 0x80000
+    field public static final int CAPABILITY_SHARED_MAP = 16777216; // 0x1000000
+    field public static final int CAPABILITY_SHARED_SKETCH = 33554432; // 0x2000000
     field public static final int CAPABILITY_SOCIAL_PRESENCE = 2048; // 0x800
     field public static final int CAPABILITY_VIDEO_SHARE = 1024; // 0x400
     field public static final int CAPABILITY_VIDEO_SHARE_DURING_CS_CALL = 512; // 0x200
@@ -11911,6 +11915,7 @@
   public abstract class ImsFeature {
     ctor public ImsFeature();
     method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+    method public int getFeatureState();
     method public final int getSlotIndex();
     method public abstract void onFeatureReady();
     method public abstract void onFeatureRemoved();
@@ -12158,6 +12163,17 @@
     method public int updateClir(int);
     method public int updateColp(boolean);
     method public int updateColr(int);
+    field public static final int CALL_BARRING_ALL = 7; // 0x7
+    field public static final int CALL_BARRING_ALL_INCOMING = 1; // 0x1
+    field public static final int CALL_BARRING_ALL_OUTGOING = 2; // 0x2
+    field public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6; // 0x6
+    field public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9; // 0x9
+    field public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8; // 0x8
+    field public static final int CALL_BARRING_OUTGOING_INTL = 3; // 0x3
+    field public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4; // 0x4
+    field public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10; // 0xa
+    field public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5; // 0x5
+    field public static final int INVALID_RESULT = -1; // 0xffffffff
   }
 
 }
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 07b8969..973d827 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -121,6 +121,18 @@
 
 }
 
+package android.net {
+
+  @Deprecated public final class StringNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+    ctor public StringNetworkSpecifier(@NonNull String);
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.StringNetworkSpecifier> CREATOR;
+    field @NonNull public final String specifier;
+  }
+
+}
+
 package android.net.wifi {
 
   @Deprecated public class BatchedScanResult implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 28119e3..190f9fe 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3141,8 +3141,6 @@
 
   public final class AccessNetworkConstants {
     field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
-    field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
-    field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
   }
 
   public final class BarringInfo implements android.os.Parcelable {
@@ -3218,36 +3216,18 @@
   }
 
   public final class NetworkRegistrationInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getAccessNetworkTechnology();
-    method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
-    method @Nullable public android.telephony.CellIdentity getCellIdentity();
     method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
-    method public int getDomain();
     method public int getRegistrationState();
     method public int getRejectCause();
     method public int getRoamingType();
-    method public int getTransportType();
     method public boolean isEmergencyEnabled();
-    method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
-    field public static final int DOMAIN_CS = 1; // 0x1
-    field public static final int DOMAIN_CS_PS = 3; // 0x3
-    field public static final int DOMAIN_PS = 2; // 0x2
-    field public static final int DOMAIN_UNKNOWN = 0; // 0x0
     field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
     field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
     field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
     field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
     field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
     field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
-    field public static final int SERVICE_TYPE_DATA = 2; // 0x2
-    field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
-    field public static final int SERVICE_TYPE_SMS = 3; // 0x3
-    field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
-    field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
-    field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
   }
 
   public static final class NetworkRegistrationInfo.Builder {
@@ -3296,7 +3276,7 @@
 
   public final class SmsManager {
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
-    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+    method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
     field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
     field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
     field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
@@ -3393,6 +3373,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @Nullable public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
     method public static int getVideoStateFromCallType(int);
@@ -3446,6 +3427,7 @@
     field public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
     field public static final String EXTRA_EMERGENCY_CALL = "e_call";
     field public static final String EXTRA_IS_CALL_PULL = "CallPull";
+    field public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS";
     field public static final String EXTRA_OI = "oi";
     field public static final String EXTRA_OIR = "oir";
     field public static final String EXTRA_REMOTE_URI = "remote_uri";
@@ -3924,6 +3906,7 @@
   public abstract class ImsFeature {
     ctor public ImsFeature();
     method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+    method public int getFeatureState();
     method public final int getSlotIndex();
     method public abstract void onFeatureReady();
     method public abstract void onFeatureRemoved();
@@ -4171,6 +4154,17 @@
     method public int updateClir(int);
     method public int updateColp(boolean);
     method public int updateColr(int);
+    field public static final int CALL_BARRING_ALL = 7; // 0x7
+    field public static final int CALL_BARRING_ALL_INCOMING = 1; // 0x1
+    field public static final int CALL_BARRING_ALL_OUTGOING = 2; // 0x2
+    field public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6; // 0x6
+    field public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9; // 0x9
+    field public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8; // 0x8
+    field public static final int CALL_BARRING_OUTGOING_INTL = 3; // 0x3
+    field public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4; // 0x4
+    field public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10; // 0xa
+    field public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5; // 0x5
+    field public static final int INVALID_RESULT = -1; // 0xffffffff
   }
 
 }
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 8fac31a..2537eda 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -100,6 +100,7 @@
 static const int TEXT_CENTER_VALUE = INT_MAX;
 static const int TEXT_MISSING_VALUE = INT_MIN;
 static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
+static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
 static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
 static constexpr size_t TEXT_POS_LEN_MAX = 16;
 
@@ -291,10 +292,10 @@
 
     // this guest property specifies multi-display IDs to show the boot animation
     // multiple ids can be set with comma (,) as separator, for example:
-    // setprop boot.animation.displays 19260422155234049,19261083906282754
+    // setprop persist.boot.animation.displays 19260422155234049,19261083906282754
     Vector<uint64_t> physicalDisplayIds;
     char displayValue[PROPERTY_VALUE_MAX] = "";
-    property_get("boot.animation.displays", displayValue, "");
+    property_get(DISPLAYS_PROP_NAME, displayValue, "");
     bool isValid = displayValue[0] != '\0';
     if (isValid) {
         char *p = displayValue;
@@ -306,7 +307,7 @@
             p ++;
         }
         if (!isValid)
-            SLOGE("Invalid syntax for the value of system prop: boot.animation.displays");
+            SLOGE("Invalid syntax for the value of system prop: %s", DISPLAYS_PROP_NAME);
     }
     if (isValid) {
         std::istringstream stream(displayValue);
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 1c6867c3..6eafbd8 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -73,7 +73,6 @@
         "src/external/puller_util.cpp",
         "src/external/ResourceHealthManagerPuller.cpp",
         "src/external/StatsCallbackPuller.cpp",
-        "src/external/StatsCallbackPullerDeprecated.cpp",
         "src/external/StatsCompanionServicePuller.cpp",
         "src/external/StatsPuller.cpp",
         "src/external/StatsPullerManager.cpp",
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index ada2f2d..c1a8d69 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1265,16 +1265,6 @@
     return Status::ok();
 }
 
-Status StatsService::registerPullerCallback(int32_t atomTag,
-        const sp<android::os::IStatsPullerCallback>& pullerCallback,
-        const String16& packageName) {
-    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
-
-    VLOG("StatsService::registerPullerCallback called.");
-    mPullerManager->RegisterPullerCallback(atomTag, pullerCallback);
-    return Status::ok();
-}
-
 Status StatsService::registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownNs,
                                     int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
                                     const sp<android::os::IPullAtomCallback>& pullerCallback) {
@@ -1297,14 +1287,6 @@
     return Status::ok();
 }
 
-Status StatsService::unregisterPullerCallback(int32_t atomTag, const String16& packageName) {
-    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
-
-    VLOG("StatsService::unregisterPullerCallback called.");
-    mPullerManager->UnregisterPullerCallback(atomTag);
-    return Status::ok();
-}
-
 Status StatsService::unregisterPullAtomCallback(int32_t uid, int32_t atomTag) {
     ENFORCE_UID(AID_SYSTEM);
     VLOG("StatsService::unregisterPullAtomCallback called.");
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 7990e5e..f2079d9 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -171,14 +171,6 @@
     virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override;
 
     /**
-     * Binder call to register a callback function for a vendor pulled atom.
-     * Note: this atom must NOT have uid as a field.
-     */
-    virtual Status registerPullerCallback(int32_t atomTag,
-        const sp<android::os::IStatsPullerCallback>& pullerCallback,
-        const String16& packageName) override;
-
-    /**
      * Binder call to register a callback function for a pulled atom.
      */
     virtual Status registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownNs,
@@ -193,11 +185,6 @@
             const sp<android::os::IPullAtomCallback>& pullerCallback) override;
 
     /**
-     * Binder call to unregister any existing callback function for a vendor pulled atom.
-     */
-    virtual Status unregisterPullerCallback(int32_t atomTag, const String16& packageName) override;
-
-    /**
      * Binder call to unregister any existing callback for the given uid and atom.
      */
     virtual Status unregisterPullAtomCallback(int32_t uid, int32_t atomTag) override;
diff --git a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp
deleted file mode 100644
index 4f88a91..0000000
--- a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsCallbackPullerDeprecated.h"
-
-#include <android/os/IStatsPullerCallback.h>
-
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-
-using namespace android::binder;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsCallbackPullerDeprecated::StatsCallbackPullerDeprecated(
-        int tagId, const sp<IStatsPullerCallback>& callback)
-    : StatsPuller(tagId), mCallback(callback) {
-    VLOG("StatsCallbackPuller created for tag %d", tagId);
-}
-
-bool StatsCallbackPullerDeprecated::PullInternal(vector<shared_ptr<LogEvent>>* data) {
-    VLOG("StatsCallbackPuller called for tag %d", mTagId)
-    if (mCallback == nullptr) {
-        ALOGW("No callback registered");
-        return false;
-    }
-    int64_t wallClockTimeNs = getWallClockNs();
-    int64_t elapsedTimeNs = getElapsedRealtimeNs();
-    vector<StatsLogEventWrapper> returned_value;
-    Status status = mCallback->pullData(mTagId, elapsedTimeNs, wallClockTimeNs, &returned_value);
-    if (!status.isOk()) {
-        ALOGW("StatsCallbackPuller::pull failed for %d", mTagId);
-        return false;
-    }
-    data->clear();
-    for (const StatsLogEventWrapper& it : returned_value) {
-        LogEvent::createLogEvents(it, *data);
-    }
-    VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
-    return true;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h
deleted file mode 100644
index 0289029..0000000
--- a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/os/IStatsPullerCallback.h>
-#include <utils/String16.h>
-
-#include "StatsPuller.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsCallbackPullerDeprecated : public StatsPuller {
-public:
-    explicit StatsCallbackPullerDeprecated(int tagId, const sp<IStatsPullerCallback>& callback);
-
-private:
-    bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
-    const sp<IStatsPullerCallback> mCallback;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index d5cda85..b4fde16 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -21,7 +21,6 @@
 
 #include <android/os/IPullAtomCallback.h>
 #include <android/os/IStatsCompanionService.h>
-#include <android/os/IStatsPullerCallback.h>
 #include <cutils/log.h>
 #include <math.h>
 #include <stdint.h>
@@ -38,7 +37,6 @@
 #include "PowerStatsPuller.h"
 #include "ResourceHealthManagerPuller.h"
 #include "StatsCallbackPuller.h"
-#include "StatsCallbackPullerDeprecated.h"
 #include "StatsCompanionServicePuller.h"
 #include "SubsystemSleepStatePuller.h"
 #include "TrainInfoPuller.h"
@@ -68,13 +66,6 @@
         {{.atomTag = android::util::ON_DEVICE_POWER_MEASUREMENT},
          {.puller = new PowerStatsPuller()}},
 
-        // system_elapsed_realtime
-        {{.atomTag = android::util::SYSTEM_ELAPSED_REALTIME},
-         {.coolDownNs = NS_PER_SEC,
-          .puller = new StatsCompanionServicePuller(android::util::SYSTEM_ELAPSED_REALTIME),
-          .pullTimeoutNs = NS_PER_SEC / 2,
-         }},
-
         // remaining_battery_capacity
         {{.atomTag = android::util::REMAINING_BATTERY_CAPACITY},
          {.puller = new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}},
@@ -95,35 +86,6 @@
         {{.atomTag = android::util::BATTERY_CYCLE_COUNT},
          {.puller = new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}},
 
-        // looper_stats
-        {{.atomTag = android::util::LOOPER_STATS},
-         {.additiveFields = {5, 6, 7, 8, 9},
-          .puller = new StatsCompanionServicePuller(android::util::LOOPER_STATS)}},
-
-        // Disk Stats
-        {{.atomTag = android::util::DISK_STATS},
-         {.puller = new StatsCompanionServicePuller(android::util::DISK_STATS)}},
-
-        // Directory usage
-        {{.atomTag = android::util::DIRECTORY_USAGE},
-         {.puller = new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}},
-
-        // Size of app's code, data, and cache
-        {{.atomTag = android::util::APP_SIZE},
-         {.puller = new StatsCompanionServicePuller(android::util::APP_SIZE)}},
-
-        // Size of specific categories of files. Eg. Music.
-        {{.atomTag = android::util::CATEGORY_SIZE},
-         {.puller = new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}},
-
-        // Number of fingerprints enrolled for each user.
-        {{.atomTag = android::util::NUM_FINGERPRINTS_ENROLLED},
-         {.puller = new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS_ENROLLED)}},
-
-        // Number of faces enrolled for each user.
-        {{.atomTag = android::util::NUM_FACES_ENROLLED},
-         {.puller = new StatsCompanionServicePuller(android::util::NUM_FACES_ENROLLED)}},
-
         // ProcStats.
         {{.atomTag = android::util::PROC_STATS},
          {.puller = new StatsCompanionServicePuller(android::util::PROC_STATS)}},
@@ -132,20 +94,6 @@
         {{.atomTag = android::util::PROC_STATS_PKG_PROC},
          {.puller = new StatsCompanionServicePuller(android::util::PROC_STATS_PKG_PROC)}},
 
-        // Disk I/O stats per uid.
-        {{.atomTag = android::util::DISK_IO},
-         {.additiveFields = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
-          .coolDownNs = 3 * NS_PER_SEC,
-          .puller = new StatsCompanionServicePuller(android::util::DISK_IO)}},
-
-        // Process cpu stats. Min cool-down is 5 sec, inline with what AcitivityManagerService uses.
-        {{.atomTag = android::util::PROCESS_CPU_TIME},
-         {.coolDownNs = 5 * NS_PER_SEC /* min cool-down in seconds*/,
-          .puller = new StatsCompanionServicePuller(android::util::PROCESS_CPU_TIME)}},
-        {{.atomTag = android::util::CPU_TIME_PER_THREAD_FREQ},
-         {.additiveFields = {7, 9, 11, 13, 15, 17, 19, 21},
-          .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_THREAD_FREQ)}},
-
         // DebugElapsedClock.
         {{.atomTag = android::util::DEBUG_ELAPSED_CLOCK},
          {.additiveFields = {1, 2, 3, 4},
@@ -156,25 +104,9 @@
          {.additiveFields = {1, 2, 3, 4},
           .puller = new StatsCompanionServicePuller(android::util::DEBUG_FAILING_ELAPSED_CLOCK)}},
 
-        // RoleHolder.
-        {{.atomTag = android::util::ROLE_HOLDER},
-         {.puller = new StatsCompanionServicePuller(android::util::ROLE_HOLDER)}},
-
-        // PermissionState.
-        {{.atomTag = android::util::DANGEROUS_PERMISSION_STATE},
-         {.puller = new StatsCompanionServicePuller(android::util::DANGEROUS_PERMISSION_STATE)}},
-
         // TrainInfo.
         {{.atomTag = android::util::TRAIN_INFO}, {.puller = new TrainInfoPuller()}},
 
-        // TimeZoneDataInfo.
-        {{.atomTag = android::util::TIME_ZONE_DATA_INFO},
-         {.puller = new StatsCompanionServicePuller(android::util::TIME_ZONE_DATA_INFO)}},
-
-        // ExternalStorageInfo
-        {{.atomTag = android::util::EXTERNAL_STORAGE_INFO},
-         {.puller = new StatsCompanionServicePuller(android::util::EXTERNAL_STORAGE_INFO)}},
-
         // GpuStatsGlobalInfo
         {{.atomTag = android::util::GPU_STATS_GLOBAL_INFO},
          {.puller = new GpuStatsPuller(android::util::GPU_STATS_GLOBAL_INFO)}},
@@ -183,31 +115,14 @@
         {{.atomTag = android::util::GPU_STATS_APP_INFO},
          {.puller = new GpuStatsPuller(android::util::GPU_STATS_APP_INFO)}},
 
-        // AppsOnExternalStorageInfo
-        {{.atomTag = android::util::APPS_ON_EXTERNAL_STORAGE_INFO},
-         {.puller = new StatsCompanionServicePuller(android::util::APPS_ON_EXTERNAL_STORAGE_INFO)}},
-
         // Face Settings
         {{.atomTag = android::util::FACE_SETTINGS},
          {.puller = new StatsCompanionServicePuller(android::util::FACE_SETTINGS)}},
 
-        // App ops
-        {{.atomTag = android::util::APP_OPS},
-         {.puller = new StatsCompanionServicePuller(android::util::APP_OPS)}},
-
         // VmsClientStats
         {{.atomTag = android::util::VMS_CLIENT_STATS},
          {.additiveFields = {5, 6, 7, 8, 9, 10},
           .puller = new CarStatsPuller(android::util::VMS_CLIENT_STATS)}},
-
-        // NotiifcationRemoteViews.
-        {{.atomTag = android::util::NOTIFICATION_REMOTE_VIEWS},
-         {.puller = new StatsCompanionServicePuller(android::util::NOTIFICATION_REMOTE_VIEWS)}},
-
-        // PermissionStateSampled.
-        {{.atomTag = android::util::DANGEROUS_PERMISSION_STATE_SAMPLED},
-         {.puller =
-               new StatsCompanionServicePuller(android::util::DANGEROUS_PERMISSION_STATE_SAMPLED)}},
 };
 
 StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
@@ -406,21 +321,6 @@
     return totalCleared;
 }
 
-// Deprecated, remove after puller API is complete.
-void StatsPullerManager::RegisterPullerCallback(int32_t atomTag,
-        const sp<IStatsPullerCallback>& callback) {
-    AutoMutex _l(mLock);
-    // Platform pullers cannot be changed.
-    if (!isVendorPulledAtom(atomTag)) {
-        VLOG("RegisterPullerCallback: atom tag %d is not vendor pulled", atomTag);
-        return;
-    }
-    VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
-    StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
-    kAllPullAtomInfo[{.atomTag = atomTag}] = {
-            .puller = new StatsCallbackPullerDeprecated(atomTag, callback)};
-}
-
 void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag,
                                                   const int64_t coolDownNs, const int64_t timeoutNs,
                                                   const vector<int32_t>& additiveFields,
@@ -437,16 +337,6 @@
     };
 }
 
-void StatsPullerManager::UnregisterPullerCallback(int32_t atomTag) {
-    AutoMutex _l(mLock);
-    // Platform pullers cannot be changed.
-    if (!isVendorPulledAtom(atomTag)) {
-        return;
-    }
-    StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
-    kAllPullAtomInfo.erase({.atomTag = atomTag});
-}
-
 void StatsPullerManager::UnregisterPullAtomCallback(const int uid, const int32_t atomTag) {
     AutoMutex _l(mLock);
     StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 349fd47..4b6ab57 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -18,7 +18,6 @@
 
 #include <android/os/IPullAtomCallback.h>
 #include <android/os/IStatsCompanionService.h>
-#include <android/os/IStatsPullerCallback.h>
 #include <binder/IServiceManager.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
@@ -116,15 +115,10 @@
 
     void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
 
-    // Deprecated, remove after puller API is complete.
-    void RegisterPullerCallback(int32_t atomTag, const sp<IStatsPullerCallback>& callback);
-
     void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs,
                                   const int64_t timeoutNs, const vector<int32_t>& additiveFields,
                                   const sp<IPullAtomCallback>& callback);
 
-    void UnregisterPullerCallback(int32_t atomTag);
-
     void UnregisterPullAtomCallback(const int uid, const int32_t atomTag);
 
     static std::map<PullerKey, PullAtomInfo> kAllPullAtomInfo;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 692d91e..3282785 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -164,9 +164,6 @@
     // Maximum number of pushed atoms statsd stats will track above kMaxPushedAtomId.
     static const int kMaxNonPlatformPushedAtoms = 100;
 
-    // Max platform atom tag number.
-    static const int32_t kMaxPlatformAtomTag = 100000;
-
     // Vendor pulled atom start id.
     static const int32_t kVendorPulledAtomStartTag = 150000;
 
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index d39a8c4..326a076 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1675,6 +1675,10 @@
     }
 
     @UnsupportedAppUsage
+    protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
+        this(context, pm, ActivityThread.getPermissionManager());
+    }
+
     protected ApplicationPackageManager(ContextImpl context, IPackageManager pm,
             IPermissionManager permissionManager) {
         mContext = context;
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 0beceb0..0ea05d8 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -25,11 +25,9 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.os.Binder;
-import android.os.IBinder;
 import android.os.IPullAtomCallback;
 import android.os.IPullAtomResultReceiver;
 import android.os.IStatsManagerService;
-import android.os.IStatsPullerCallback;
 import android.os.IStatsd;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -476,42 +474,6 @@
     }
 
     /**
-     * Registers a callback for an atom when that atom is to be pulled. The stats service will
-     * invoke pullData in the callback when the stats service determines that this atom needs to be
-     * pulled. Currently, this only works for atoms with tags above 100,000 that do not have a uid.
-     *
-     * @param atomTag   The tag of the atom for this puller callback. Must be at least 100000.
-     * @param callback  The callback to be invoked when the stats service pulls the atom.
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     *
-     * @hide
-     * @deprecated Please use registerPullAtomCallback
-     */
-    @Deprecated
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public void setPullerCallback(int atomTag, IStatsPullerCallback callback)
-            throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsd service = getIStatsdLocked();
-                if (callback == null) {
-                    service.unregisterPullerCallback(atomTag, mContext.getOpPackageName());
-                } else {
-                    service.registerPullerCallback(atomTag, callback,
-                            mContext.getOpPackageName());
-                }
-
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to connect to statsd when registering data listener.");
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (SecurityException e) {
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
-    }
-
-
-    /**
      * Temp registration for while the migration is in progress.
      *
      * @hide
@@ -734,32 +696,6 @@
         int onPullAtom(int atomTag, @NonNull List<StatsEvent> data);
     }
 
-    private class StatsdDeathRecipient implements IBinder.DeathRecipient {
-        @Override
-        public void binderDied() {
-            synchronized (sLock) {
-                mService = null;
-            }
-        }
-    }
-
-    @GuardedBy("sLock")
-    private IStatsd getIStatsdLocked() throws StatsUnavailableException {
-        if (mService != null) {
-            return mService;
-        }
-        mService = IStatsd.Stub.asInterface(ServiceManager.getService("stats"));
-        if (mService == null) {
-            throw new StatsUnavailableException("could not be found");
-        }
-        try {
-            mService.asBinder().linkToDeath(new StatsdDeathRecipient(), 0);
-        } catch (RemoteException e) {
-            throw new StatsUnavailableException("could not connect when linkToDeath", e);
-        }
-        return mService;
-    }
-
     @GuardedBy("sLock")
     private IStatsManagerService getIStatsManagerServiceLocked() {
         if (mStatsManagerService != null) {
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 9ad3d38..a885009 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1564,6 +1564,8 @@
      * @return The desired minimum width for the wallpaper. This value should
      * be honored by applications that set the wallpaper but it is not
      * mandatory.
+     *
+     * @see #getDesiredMinimumHeight()
      */
     public int getDesiredMinimumWidth() {
         if (sGlobals.mService == null) {
@@ -1590,6 +1592,8 @@
      * @return The desired minimum height for the wallpaper. This value should
      * be honored by applications that set the wallpaper but it is not
      * mandatory.
+     *
+     * @see #getDesiredMinimumWidth()
      */
     public int getDesiredMinimumHeight() {
         if (sGlobals.mService == null) {
@@ -1609,12 +1613,11 @@
      * a virtual wallpaper that is larger than the physical screen, matching
      * the size of their workspace.
      *
-     * <p>Note developers, who don't seem to be reading this.  This is
-     * for <em>home apps</em> to tell what size wallpaper they would like.
-     * Nobody else should be calling this!  Certainly not other non-home
-     * apps that change the wallpaper.  Those apps are supposed to
-     * <b>retrieve</b> the suggested size so they can construct a wallpaper
-     * that matches it.
+     * <p class="note">Calling this method from apps other than the active
+     * home app is not guaranteed to work properly.  Other apps that supply
+     * wallpaper imagery should use {@link #getDesiredMinimumWidth()} and
+     * {@link #getDesiredMinimumHeight()} and construct a wallpaper that
+     * matches those dimensions.
      *
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#SET_WALLPAPER_HINTS}.
diff --git a/core/java/android/net/StringNetworkSpecifier.java b/core/java/android/net/StringNetworkSpecifier.java
index 83dbc63..530c84a 100644
--- a/core/java/android/net/StringNetworkSpecifier.java
+++ b/core/java/android/net/StringNetworkSpecifier.java
@@ -26,7 +26,16 @@
 
 import java.util.Objects;
 
-/** @hide */
+/**
+ * @deprecated use other subclass of {@link android.net.NetworkSpecifier},
+ *             eg. {@link android.net.TelephonyNetworkSpecifier},
+ *             {@link android.net.wifi.WifiNetworkSpecifier} instead.
+ *             @see {@link android.net.NetworkRequest#setNetworkSpecifier(String)} for details.
+ * @removed this class was tentatively made SystemApi in December 2019 in the scramble for
+ *          publishing mainline APIs, it should be removed before R release is published.
+ * @hide
+ */
+@Deprecated
 @SystemApi
 public final class StringNetworkSpecifier extends NetworkSpecifier implements Parcelable {
     /**
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 179828c..13d0c5c 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -35,6 +35,7 @@
 import com.android.server.NetworkManagementSocketTagger;
 
 import dalvik.system.RuntimeHooks;
+import dalvik.system.ThreadPrioritySetter;
 import dalvik.system.VMRuntime;
 
 import libcore.content.type.MimeMap;
@@ -204,6 +205,7 @@
      */
     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());
@@ -216,6 +218,35 @@
         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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6b27348..7181142 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -563,10 +563,12 @@
 
     <protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" />
 
-    <protected-broadcast android:name="com.android.phone.SIP_INCOMING_CALL" />
+    <protected-broadcast android:name="android.net.sip.action.SIP_INCOMING_CALL" />
     <protected-broadcast android:name="com.android.phone.SIP_ADD_PHONE" />
-    <protected-broadcast android:name="com.android.phone.SIP_REMOVE_PHONE" />
-    <protected-broadcast android:name="com.android.phone.SIP_CALL_OPTION_CHANGED" />
+    <protected-broadcast android:name="android.net.sip.action.SIP_REMOVE_PROFILE" />
+    <protected-broadcast android:name="android.net.sip.action.SIP_SERVICE_UP" />
+    <protected-broadcast android:name="android.net.sip.action.SIP_CALL_OPTION_CHANGED" />
+    <protected-broadcast android:name="android.net.sip.action.START_SIP" />
 
     <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_CONNECTED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED" />
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index e4bab74..f898931 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -99,25 +99,21 @@
 
     /**
      * Quality level corresponding to the VGA (640 x 480) resolution.
-     * @hide
      */
     public static final int QUALITY_VGA = 9;
 
     /**
      * Quality level corresponding to 4k-DCI (4096 x 2160) resolution.
-     * @hide
      */
     public static final int QUALITY_4KDCI = 10;
 
     /**
      * Quality level corresponding to QHD (2560 x 1440) resolution
-     * @hide
      */
     public static final int QUALITY_QHD = 11;
 
     /**
      * Quality level corresponding to 2K (2048 x 1080) resolution
-     * @hide
      */
     public static final int QUALITY_2K = 12;
 
@@ -172,25 +168,21 @@
 
     /**
      * Time lapse quality level corresponding to the VGA (640 x 480) resolution.
-     * @hide
      */
     public static final int QUALITY_TIME_LAPSE_VGA = 1009;
 
     /**
      * Time lapse quality level corresponding to the 4k-DCI (4096 x 2160) resolution.
-     * @hide
      */
     public static final int QUALITY_TIME_LAPSE_4KDCI = 1010;
 
     /**
      * Time lapse quality level corresponding to the QHD (2560 x 1440) resolution.
-     * @hide
      */
     public static final int QUALITY_TIME_LAPSE_QHD = 1011;
 
     /**
      * Time lapse quality level corresponding to the 2K (2048 x 1080) resolution.
-     * @hide
      */
     public static final int QUALITY_TIME_LAPSE_2K = 1012;
 
@@ -255,19 +247,16 @@
 
     /**
      * High speed ( >= 100fps) quality level corresponding to the CIF (352 x 288)
-     * @hide
      */
     public static final int QUALITY_HIGH_SPEED_CIF = 2006;
 
     /**
      * High speed ( >= 100fps) quality level corresponding to the VGA (640 x 480)
-     * @hide
      */
     public static final int QUALITY_HIGH_SPEED_VGA = 2007;
 
     /**
      * High speed ( >= 100fps) quality level corresponding to the 4K-DCI (4096 x 2160)
-     * @hide
      */
     public static final int QUALITY_HIGH_SPEED_4KDCI = 2008;
 
diff --git a/packages/CarSystemUI/res/xml/overlayable.xml b/packages/CarSystemUI/res/xml/overlayable.xml
new file mode 100644
index 0000000..2b6e66e
--- /dev/null
+++ b/packages/CarSystemUI/res/xml/overlayable.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+    <overlayable name="SystemBarsLayouts">
+        <policy type="product|signature">
+            <item type="layout" name="car_navigation_bar" />
+        </policy>
+    </overlayable>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/scripts/update_shared_lib.sh b/packages/SystemUI/scripts/update_shared_lib.sh
new file mode 100755
index 0000000..0537493
--- /dev/null
+++ b/packages/SystemUI/scripts/update_shared_lib.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+NUM_ARGS=$#
+
+has_croot() {
+  declare -F croot > /dev/null
+  return $?
+}
+
+check_environment() {
+  if ! has_croot; then
+    echo "Run script in a shell that has had envsetup run. Run '. update_shared_lib.sh' from scripts directory"
+    return 1
+  fi
+
+  if [ $NUM_ARGS -ne 1 ]; then
+    echo "Usage: . update_shared_lib PATH_TO_UNBUNDLED_LAUNCER     e.g. . update_shared_lib ~/src/ub-launcher3-master"
+    return 1
+  fi
+  return 0
+}
+
+main() {
+  if check_environment ; then
+    pushd .
+    croot
+    mma -j16 SystemUISharedLib
+    JAR_DESTINATION="$1/prebuilts/framework_intermediates/quickstep/libs/sysui_shared.jar"
+    cp out/target/product/$TARGET_PRODUCT/obj/JAVA_LIBRARIES/SystemUISharedLib_intermediates/javalib.jar $JAR_DESTINATION
+    popd
+  fi
+}
+
+main
+
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
new file mode 100644
index 0000000..70a464d
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
@@ -0,0 +1,67 @@
+/*
+ * 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.systemui.shared.system;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.SurfaceControl;
+import android.view.SurfaceView;
+
+/** Utility class that is shared between SysUI and Launcher for Universal Smartspace features. */
+public final class UniversalSmartspaceUtils {
+    public static final String ACTION_REQUEST_SMARTSPACE_VIEW =
+            "com.android.systemui.REQUEST_SMARTSPACE_VIEW";
+
+    private static final String SYSUI_PACKAGE = "com.android.systemui";
+    private static final String INTENT_KEY_INPUT_BUNDLE = "input_bundle";
+    private static final String BUNDLE_KEY_INPUT_TOKEN = "input_token";
+    private static final String INTENT_KEY_SURFACE_CONTROL = "surface_control";
+
+    /** Creates an intent to request that sysui draws the Smartspace to the SurfaceView. */
+    public static Intent createRequestSmartspaceIntent(SurfaceView surfaceView) {
+        Intent intent = new Intent(ACTION_REQUEST_SMARTSPACE_VIEW);
+
+        Bundle inputBundle = new Bundle();
+        inputBundle.putBinder(BUNDLE_KEY_INPUT_TOKEN, surfaceView.getInputToken());
+        return intent
+                .putExtra(INTENT_KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl())
+                .putExtra(INTENT_KEY_INPUT_BUNDLE, inputBundle)
+                .setPackage(SYSUI_PACKAGE)
+                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                        | Intent.FLAG_RECEIVER_FOREGROUND);
+    }
+
+    /**
+     * Retrieves the SurfaceControl from an Intent created by
+     * {@link #createRequestSmartspaceIntent(SurfaceView)}.
+     **/
+    public static SurfaceControl getSurfaceControl(Intent intent) {
+        return intent.getParcelableExtra(INTENT_KEY_SURFACE_CONTROL);
+    }
+
+    /**
+     * Retrieves the input token from an Intent created by
+     * {@link #createRequestSmartspaceIntent(SurfaceView)}.
+     **/
+    public static IBinder getInputToken(Intent intent) {
+        Bundle inputBundle = intent.getBundleExtra(INTENT_KEY_INPUT_BUNDLE);
+        return inputBundle == null ? null : inputBundle.getBinder(BUNDLE_KEY_INPUT_TOKEN);
+    }
+
+    private UniversalSmartspaceUtils() {}
+}
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index e441fb5..cf2b1f06 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -35,7 +35,7 @@
         "framework-tethering",
         "unsupportedappusage",
     ],
-
+    plugins: ["java_api_finder"],
     manifest: "AndroidManifestBase.xml",
 }
 
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index 4306cf0b..0491ad7 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -441,7 +441,8 @@
         }
 
         final Boolean setIfaceUp;
-        if (mInterfaceType == TetheringManager.TETHERING_WIFI) {
+        if (mInterfaceType == TetheringManager.TETHERING_WIFI
+                || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) {
             // The WiFi stack has ownership of the interface up/down state.
             // It is unclear whether the Bluetooth or USB stacks will manage their own
             // state.
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index 37e0cc1..8d1e0c9 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -207,6 +207,7 @@
     private Network mTetherUpstream;
     private TetherStatesParcel mTetherStatesParcel;
     private boolean mDataSaverEnabled = false;
+    private String mWifiP2pTetherInterface = null;
 
     public Tethering(TetheringDependencies deps) {
         mLog.mark("Tethering.constructed");
@@ -852,6 +853,11 @@
             }
         }
 
+        private boolean isGroupOwner(WifiP2pGroup group) {
+            return group != null && group.isGroupOwner()
+                    && !TextUtils.isEmpty(group.getInterface());
+        }
+
         private void handleWifiP2pAction(Intent intent) {
             if (mConfig.isWifiP2pLegacyTetheringMode()) return;
 
@@ -864,24 +870,31 @@
                 Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group);
             }
 
-            if (p2pInfo == null) return;
-            // When a p2p group is disconnected, p2pInfo would be cleared.
-            // group is still valid for detecting whether this device is group owner.
-            if (group == null || !group.isGroupOwner()
-                    || TextUtils.isEmpty(group.getInterface())) return;
-
             synchronized (Tethering.this.mPublicSync) {
-                // Enter below only if this device is Group Owner with a valid interface.
-                if (p2pInfo.groupFormed) {
-                    TetherState tetherState = mTetherStates.get(group.getInterface());
-                    if (tetherState == null
-                            || (tetherState.lastState != IpServer.STATE_TETHERED
-                                && tetherState.lastState != IpServer.STATE_LOCAL_ONLY)) {
-                        enableWifiIpServingLocked(group.getInterface(), IFACE_IP_MODE_LOCAL_ONLY);
-                    }
-                } else {
-                    disableWifiP2pIpServingLocked(group.getInterface());
+                // if no group is formed, bring it down if needed.
+                if (p2pInfo == null || !p2pInfo.groupFormed) {
+                    disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+                    mWifiP2pTetherInterface = null;
+                    return;
                 }
+
+                // If there is a group but the device is not the owner, bail out.
+                if (!isGroupOwner(group)) return;
+
+                // If already serving from the correct interface, nothing to do.
+                if (group.getInterface().equals(mWifiP2pTetherInterface)) return;
+
+                // If already serving from another interface, turn it down first.
+                if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) {
+                    mLog.w("P2P tethered interface " + mWifiP2pTetherInterface
+                            + "is different from current interface "
+                            + group.getInterface() + ", re-tether it");
+                    disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+                }
+
+                // Finally bring up serving on the new interface
+                mWifiP2pTetherInterface = group.getInterface();
+                enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY);
             }
         }
 
@@ -979,7 +992,9 @@
         disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState);
     }
 
-    private void disableWifiP2pIpServingLocked(String ifname) {
+    private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
+        if (TextUtils.isEmpty(ifname)) return;
+
         disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
     }
 
diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 1f50b6b..f29ad78 100644
--- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -273,7 +273,7 @@
         dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
         InOrder inOrder = inOrder(mCallback, mNetd);
         inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
-                  IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
+                  IFACE_NAME.equals(cfg.ifName) && assertNotContainsFlag(cfg.flags, IF_STATE_UP)));
         inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
         inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
         inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
@@ -547,4 +547,14 @@
         fail("Missing flag: " + match);
         return false;
     }
+
+    private boolean assertNotContainsFlag(String[] flags, String match) {
+        for (String flag : flags) {
+            if (flag.equals(match)) {
+                fail("Unexpected flag: " + match);
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
index 5910624..d6afa47 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
@@ -493,13 +493,15 @@
 
     private void sendWifiP2pConnectionChanged(
             boolean isGroupFormed, boolean isGroupOwner, String ifname) {
+        WifiP2pGroup group = null;
         WifiP2pInfo p2pInfo = new WifiP2pInfo();
         p2pInfo.groupFormed = isGroupFormed;
-        p2pInfo.isGroupOwner = isGroupOwner;
-
-        WifiP2pGroup group = mock(WifiP2pGroup.class);
-        when(group.isGroupOwner()).thenReturn(isGroupOwner);
-        when(group.getInterface()).thenReturn(ifname);
+        if (isGroupFormed) {
+            p2pInfo.isGroupOwner = isGroupOwner;
+            group = mock(WifiP2pGroup.class);
+            when(group.isGroupOwner()).thenReturn(isGroupOwner);
+            when(group.getInterface()).thenReturn(ifname);
+        }
 
         final Intent intent = mock(Intent.class);
         when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
diff --git a/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java
index 3af15c7..5e6f97e 100644
--- a/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java
+++ b/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java
@@ -20,23 +20,24 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.slice.Slice;
 import android.content.Context;
-import android.os.Handler;
 import android.os.RemoteException;
 import android.service.autofill.Dataset;
+import android.service.autofill.InlinePresentation;
 import android.util.Slog;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.autofill.AutofillId;
 import android.view.autofill.IAutoFillManagerClient;
-import android.view.inline.InlinePresentationSpec;
 import android.view.inputmethod.InlineSuggestion;
 import android.view.inputmethod.InlineSuggestionInfo;
-import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.inputmethod.InlineSuggestionsResponse;
 
 import com.android.internal.view.inline.IInlineContentCallback;
 import com.android.internal.view.inline.IInlineContentProvider;
+import com.android.server.UiThread;
+import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.autofill.ui.InlineSuggestionUi;
 
 import java.util.ArrayList;
@@ -56,23 +57,59 @@
             int sessionId,
             @NonNull Dataset[] datasets,
             @NonNull AutofillId autofillId,
-            @NonNull InlineSuggestionsRequest request,
-            @NonNull Handler uiHandler,
             @NonNull Context context,
             @NonNull IAutoFillManagerClient client) {
+        if (sDebug) Slog.d(TAG, "createAugmentedInlineSuggestionsResponse called");
+
+        final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
+        final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(context);
+        for (Dataset dataset : datasets) {
+            final int fieldIndex = dataset.getFieldIds().indexOf(autofillId);
+            if (fieldIndex < 0) {
+                Slog.w(TAG, "AutofillId=" + autofillId + " not found in dataset");
+                return null;
+            }
+            final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(
+                    fieldIndex);
+            if (inlinePresentation == null) {
+                Slog.w(TAG, "InlinePresentation not found in dataset");
+                return null;
+            }
+            InlineSuggestion inlineSuggestion = createAugmentedInlineSuggestion(sessionId, dataset,
+                    inlinePresentation, inlineSuggestionUi, client);
+            inlineSuggestions.add(inlineSuggestion);
+        }
+        return new InlineSuggestionsResponse(inlineSuggestions);
+    }
+
+    /**
+     * Creates an {@link InlineSuggestionsResponse} with the {@code datasets} provided by the
+     * autofill service.
+     */
+    public static InlineSuggestionsResponse createInlineSuggestionsResponse(int requestId,
+            @NonNull Dataset[] datasets,
+            @NonNull AutofillId autofillId,
+            @NonNull Context context,
+            @NonNull AutoFillUI.AutoFillUiCallback client) {
         if (sDebug) Slog.d(TAG, "createInlineSuggestionsResponse called");
 
         final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
         final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(context);
         for (Dataset dataset : datasets) {
-            // TODO(b/146453195): use the spec in the dataset.
-            InlinePresentationSpec spec = request.getPresentationSpecs().get(0);
-            if (spec == null) {
-                Slog.w(TAG, "InlinePresentationSpec is not provided in the response data set");
-                continue;
+            final int fieldIndex = dataset.getFieldIds().indexOf(autofillId);
+            if (fieldIndex < 0) {
+                Slog.w(TAG, "AutofillId=" + autofillId + " not found in dataset");
+                return null;
             }
-            InlineSuggestion inlineSuggestion = createAugmentedInlineSuggestion(sessionId, dataset,
-                    autofillId, spec, uiHandler, inlineSuggestionUi, client);
+            final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(
+                    fieldIndex);
+            if (inlinePresentation == null) {
+                Slog.w(TAG, "InlinePresentation not found in dataset");
+                return null;
+            }
+            InlineSuggestion inlineSuggestion = createInlineSuggestion(requestId, dataset,
+                    fieldIndex,
+                    inlinePresentation, inlineSuggestionUi, client);
             inlineSuggestions.add(inlineSuggestion);
         }
         return new InlineSuggestionsResponse(inlineSuggestions);
@@ -80,33 +117,55 @@
 
     private static InlineSuggestion createAugmentedInlineSuggestion(int sessionId,
             @NonNull Dataset dataset,
-            @NonNull AutofillId autofillId,
-            @NonNull InlinePresentationSpec spec,
-            @NonNull Handler uiHandler,
+            @NonNull InlinePresentation inlinePresentation,
             @NonNull InlineSuggestionUi inlineSuggestionUi,
             @NonNull IAutoFillManagerClient client) {
         // TODO(b/146453195): fill in the autofill hint properly.
         final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
-                spec, InlineSuggestionInfo.SOURCE_PLATFORM, new String[]{""});
-        final View.OnClickListener onClickListener = createOnClickListener(sessionId, dataset,
-                client);
+                inlinePresentation.getInlinePresentationSpec(),
+                InlineSuggestionInfo.SOURCE_PLATFORM, new String[]{""});
+        final View.OnClickListener onClickListener = v -> {
+            try {
+                client.autofill(sessionId, dataset.getFieldIds(), dataset.getFieldValues());
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Encounter exception autofilling the values");
+            }
+        };
         final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
-                createInlineContentProvider(autofillId, dataset, uiHandler, inlineSuggestionUi,
+                createInlineContentProvider(inlinePresentation.getSlice(), inlineSuggestionUi,
+                        onClickListener));
+        return inlineSuggestion;
+    }
+
+    private static InlineSuggestion createInlineSuggestion(int requestId,
+            @NonNull Dataset dataset,
+            int fieldIndex,
+            @NonNull InlinePresentation inlinePresentation,
+            @NonNull InlineSuggestionUi inlineSuggestionUi,
+            @NonNull AutoFillUI.AutoFillUiCallback client) {
+        // TODO(b/146453195): fill in the autofill hint properly.
+        final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
+                inlinePresentation.getInlinePresentationSpec(),
+                InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""});
+        final View.OnClickListener onClickListener = v -> {
+            client.fill(requestId, fieldIndex, dataset);
+        };
+        final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
+                createInlineContentProvider(inlinePresentation.getSlice(), inlineSuggestionUi,
                         onClickListener));
         return inlineSuggestion;
     }
 
     private static IInlineContentProvider.Stub createInlineContentProvider(
-            @NonNull AutofillId autofillId, @NonNull Dataset dataset, @NonNull Handler uiHandler,
-            @NonNull InlineSuggestionUi inlineSuggestionUi,
+            @NonNull Slice slice, @NonNull InlineSuggestionUi inlineSuggestionUi,
             @Nullable View.OnClickListener onClickListener) {
         return new IInlineContentProvider.Stub() {
             @Override
             public void provideContent(int width, int height,
                     IInlineContentCallback callback) {
-                uiHandler.post(() -> {
-                    SurfaceControl sc = inlineSuggestionUi.inflate(dataset, autofillId,
-                            width, height, onClickListener);
+                UiThread.getHandler().post(() -> {
+                    SurfaceControl sc = inlineSuggestionUi.inflate(slice, width, height,
+                            onClickListener);
                     try {
                         callback.onContent(sc);
                     } catch (RemoteException e) {
@@ -117,19 +176,6 @@
         };
     }
 
-    private static View.OnClickListener createOnClickListener(int sessionId,
-            @NonNull Dataset dataset,
-            @NonNull IAutoFillManagerClient client) {
-        return v -> {
-            if (sDebug) Slog.d(TAG, "Inline suggestion clicked");
-            try {
-                client.autofill(sessionId, dataset.getFieldIds(), dataset.getFieldValues());
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Encounter exception autofilling the values");
-            }
-        };
-    }
-
     private InlineSuggestionFactory() {
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index 2a7357b..5fbdd25 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -161,8 +161,7 @@
                                 @Override
                                 public void onSuccess(@Nullable Dataset[] inlineSuggestionsData) {
                                     maybeHandleInlineSuggestions(sessionId, inlineSuggestionsData,
-                                            focusedId, inlineSuggestionsRequest,
-                                            inlineSuggestionsCallback, client);
+                                            focusedId, inlineSuggestionsCallback, client);
                                     requestAutofill.complete(null);
                                 }
 
@@ -226,19 +225,15 @@
 
     private void maybeHandleInlineSuggestions(int sessionId,
             @Nullable Dataset[] inlineSuggestionsData, @NonNull AutofillId focusedId,
-            @Nullable InlineSuggestionsRequest inlineSuggestionsRequest,
             @Nullable IInlineSuggestionsResponseCallback inlineSuggestionsCallback,
             @NonNull IAutoFillManagerClient client) {
-        if (inlineSuggestionsRequest == null
-                || ArrayUtils.isEmpty(inlineSuggestionsData)
-                || inlineSuggestionsCallback == null) {
+        if (ArrayUtils.isEmpty(inlineSuggestionsData) || inlineSuggestionsCallback == null) {
             return;
         }
         try {
             inlineSuggestionsCallback.onInlineSuggestionsResponse(
-                    InlineSuggestionFactory.createAugmentedInlineSuggestionsResponse(
-                            sessionId, inlineSuggestionsData, focusedId, inlineSuggestionsRequest,
-                            getJobHandler(), mContext, client));
+                    InlineSuggestionFactory.createAugmentedInlineSuggestionsResponse(sessionId,
+                            inlineSuggestionsData, focusedId, mContext, client));
         } catch (RemoteException e) {
             Slog.w(TAG, "Exception sending inline suggestions response back to IME.");
         }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index cdd7510..ee37de5 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -71,7 +71,6 @@
 import android.service.autofill.FillContext;
 import android.service.autofill.FillRequest;
 import android.service.autofill.FillResponse;
-import android.service.autofill.InlinePresentation;
 import android.service.autofill.InternalSanitizer;
 import android.service.autofill.InternalValidator;
 import android.service.autofill.SaveInfo;
@@ -93,9 +92,6 @@
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 import android.view.autofill.IAutofillWindowPresenter;
-import android.view.inline.InlinePresentationSpec;
-import android.view.inputmethod.InlineSuggestion;
-import android.view.inputmethod.InlineSuggestionInfo;
 import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.inputmethod.InlineSuggestionsResponse;
 
@@ -106,8 +102,6 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.view.IInlineSuggestionsRequestCallback;
 import com.android.internal.view.IInlineSuggestionsResponseCallback;
-import com.android.internal.view.inline.IInlineContentCallback;
-import com.android.internal.view.inline.IInlineContentProvider;
 import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.autofill.ui.PendingUi;
 import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -148,6 +142,7 @@
     private final Handler mHandler;
     private final Object mLock;
     private final AutoFillUI mUi;
+    private final Context mContext;
 
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
@@ -773,6 +768,7 @@
         mLock = lock;
         mUi = ui;
         mHandler = handler;
+        mContext = context;
         mRemoteFillService = serviceComponentName == null ? null
                 : new RemoteFillService(context, serviceComponentName, userId, this,
                         bindInstantServiceAllowed);
@@ -2733,35 +2729,11 @@
             return false;
         }
 
-        final int size = datasets.size();
-        final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
-
-        for (int index = 0; index < size; index++) {
-            final Dataset dataset = datasets.get(index);
-            //TODO(b/146453536): Use the proper presentation/spec for currently focused view.
-            final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(0);
-            if (inlinePresentation == null) {
-                if (sDebug) Log.d(TAG, "Missing InlinePresentation on dataset=" + dataset);
-                continue;
-            }
-            final InlinePresentationSpec spec = inlinePresentation.getInlinePresentationSpec();
-            final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
-                    spec, InlineSuggestionInfo.SOURCE_AUTOFILL, new String[] { "" });
-
-            inlineSuggestions.add(new InlineSuggestion(inlineSuggestionInfo,
-                    new IInlineContentProvider.Stub() {
-                        @Override
-                        public void provideContent(int width, int height,
-                                IInlineContentCallback callback) throws RemoteException {
-                            getUiForShowing().getSuggestionSurfaceForShowing(dataset, response,
-                                    mCurrentViewId, width, height, callback);
-                        }
-                    }));
-        }
-
+        InlineSuggestionsResponse inlineSuggestionsResponse =
+                InlineSuggestionFactory.createInlineSuggestionsResponse(response.getRequestId(),
+                        datasets.toArray(new Dataset[]{}), mCurrentViewId, mContext, this);
         try  {
-            inlineContentCallback.onInlineSuggestionsResponse(
-                    new InlineSuggestionsResponse(inlineSuggestions));
+            inlineContentCallback.onInlineSuggestionsResponse(inlineSuggestionsResponse);
         } catch (RemoteException e) {
             Log.w(TAG, "onFillReady() remote error calling onInlineSuggestionsResponse()");
             return false;
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 0511bf2..26bb7c3 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -37,7 +37,6 @@
 import android.text.TextUtils;
 import android.util.Slog;
 import android.view.KeyEvent;
-import android.view.SurfaceControl;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.IAutofillWindowPresenter;
@@ -45,7 +44,6 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.view.inline.IInlineContentCallback;
 import com.android.server.LocalServices;
 import com.android.server.UiModeManagerInternal;
 import com.android.server.UiThread;
@@ -173,36 +171,6 @@
     }
 
     /**
-     * TODO(b/137800469): Fill in javadoc.
-     * TODO(b/137800469): peoperly manage lifecycle of suggestions surfaces.
-     */
-    public void getSuggestionSurfaceForShowing(@NonNull Dataset dataset,
-            @NonNull FillResponse response, AutofillId autofillId, int width, int height,
-            IInlineContentCallback cb) {
-        if (dataset == null) {
-            Slog.w(TAG, "getSuggestionSurfaceForShowing() called with null dataset");
-        }
-        mHandler.post(() -> {
-            final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(mContext);
-            final SurfaceControl suggestionSurface = inlineSuggestionUi.inflate(dataset,
-                    autofillId, width, height, v -> {
-                        Slog.d(TAG, "Inline suggestion clicked");
-                        hideFillUiUiThread(mCallback, true);
-                        if (mCallback != null) {
-                            final int datasetIndex = response.getDatasets().indexOf(dataset);
-                            mCallback.fill(response.getRequestId(), datasetIndex, dataset);
-                        }
-                    });
-
-            try {
-                cb.onContent(suggestionSurface);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "RemoteException replying onContent(" + suggestionSurface + "): " + e);
-            }
-        });
-    }
-
-    /**
      * Shows the fill UI, removing the previous fill UI if the has changed.
      *
      * @param focusedId the currently focused field
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
index 1e3ee88..2460732 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
@@ -28,17 +28,13 @@
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Icon;
 import android.os.IBinder;
-import android.service.autofill.Dataset;
 import android.util.Log;
-import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillValue;
 import android.widget.ImageView;
 import android.widget.TextView;
 
@@ -69,23 +65,18 @@
      */
     @MainThread
     @Nullable
-    public SurfaceControl inflate(@NonNull Dataset dataset, @NonNull AutofillId autofillId,
-            int width, int height, @Nullable View.OnClickListener onClickListener) {
+    public SurfaceControl inflate(@NonNull Slice slice, int width, int height,
+            @Nullable View.OnClickListener onClickListener) {
         Log.d(TAG, "Inflating the inline suggestion UI");
-        final int index = dataset.getFieldIds().indexOf(autofillId);
-        if (index < 0) {
-            Slog.w(TAG, "inflateInlineSuggestion(): AutofillId=" + autofillId
-                    + " not found in dataset");
-            return null;
-        }
-        final AutofillValue datasetValue = dataset.getFieldValues().get(index);
+
         //TODO(b/137800469): Pass in inputToken from IME.
         final SurfaceControlViewHost wvr = new SurfaceControlViewHost(mContext,
                 mContext.getDisplay(), (IBinder) null);
         final SurfaceControl sc = wvr.getSurfacePackage().getSurfaceControl();
-
-        final ViewGroup suggestionView =
-                (ViewGroup) renderSlice(dataset.getFieldInlinePresentation(index).getSlice());
+        final ViewGroup suggestionView = (ViewGroup) renderSlice(slice);
+        if (onClickListener != null) {
+            suggestionView.setOnClickListener(onClickListener);
+        }
 
         WindowManager.LayoutParams lp =
                 new WindowManager.LayoutParams(width, height,
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 4f03a8e..7324d97 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2413,43 +2413,12 @@
         Intent intent = new Intent(ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
         intent.putExtra(PHONE_CONSTANTS_STATE_KEY, dataStateToString(state));
         intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, apn);
-        intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY, getApnTypesStringFromBitmask(apnType));
+        intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY,
+                ApnSetting.getApnTypesStringFromBitmask(apnType));
         intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId);
         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
-    private static final Map<Integer, String> APN_TYPE_INT_MAP;
-    static {
-        APN_TYPE_INT_MAP = new android.util.ArrayMap<Integer, String>();
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_DEFAULT, "default");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_MMS, "mms");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_SUPL, "supl");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_DUN, "dun");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_HIPRI, "hipri");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_FOTA, "fota");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_IMS, "ims");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_CBS, "cbs");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_IA, "ia");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_EMERGENCY, "emergency");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_MCX, "mcx");
-        APN_TYPE_INT_MAP.put(ApnSetting.TYPE_XCAP, "xcap");
-    }
-
-    /**
-     * Copy of ApnSetting#getApnTypesStringFromBitmask for legacy broadcast.
-     * @param apnTypeBitmask bitmask of APN types.
-     * @return comma delimited list of APN types.
-     */
-    private static String getApnTypesStringFromBitmask(int apnTypeBitmask) {
-        List<String> types = new ArrayList<>();
-        for (Integer type : APN_TYPE_INT_MAP.keySet()) {
-            if ((apnTypeBitmask & type) == type) {
-                types.add(APN_TYPE_INT_MAP.get(type));
-            }
-        }
-        return android.text.TextUtils.join(",", types);
-    }
-
     private void enforceNotifyPermissionOrCarrierPrivilege(String method) {
         if (checkNotifyPermission()) {
             return;
diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
index dfc0080..4bf606e 100644
--- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
+++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
@@ -53,6 +53,7 @@
     public OverrideAllowedState getOverrideAllowedState(long changeId, String packageName) {
         boolean debuggableBuild = false;
         boolean finalBuild = false;
+        int minTargetSdk = mCompatConfig.minTargetSdkForChangeId(changeId);
 
         debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild();
         finalBuild = mAndroidBuildClassifier.isFinalBuild();
@@ -76,15 +77,14 @@
         if ((applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
             return new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1);
         }
-        int minTargetSdk = mCompatConfig.minTargetSdkForChangeId(changeId);
-        // Do not allow overriding non-target sdk gated changes on user builds
-        if (minTargetSdk == -1) {
-            return new OverrideAllowedState(DISABLED_NON_TARGET_SDK, appTargetSdk, minTargetSdk);
-        }
         // Allow overriding any change for debuggable apps on non-final builds.
         if (!finalBuild) {
             return new OverrideAllowedState(ALLOWED, appTargetSdk, minTargetSdk);
         }
+        // Do not allow overriding non-target sdk gated changes on user builds
+        if (minTargetSdk == -1) {
+            return new OverrideAllowedState(DISABLED_NON_TARGET_SDK, appTargetSdk, minTargetSdk);
+        }
         // Only allow to opt-in for a targetSdk gated change.
         if (applicationInfo.targetSdkVersion < minTargetSdk) {
             return new OverrideAllowedState(ALLOWED, appTargetSdk, minTargetSdk);
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 1e85688..b11ec6f 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -168,6 +168,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.MissingResourceException;
 import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
@@ -198,9 +199,16 @@
     private final Object mThermalLock = new Object();
     @GuardedBy("mThermalLock")
     private IThermalService mThermalService;
+    private final Object mStoragedLock = new Object();
+    @GuardedBy("mStoragedLock")
+    private IStoraged mStorageService;
+    private final Object mNotificationStatsLock = new Object();
+    @GuardedBy("mNotificationStatsLock")
+    private INotificationManager mNotificationManagerService;
 
     private final Context mContext;
     private StatsManager mStatsManager;
+    private StorageManager mStorageManager;
 
     public StatsPullAtomService(Context context) {
         super(context);
@@ -212,6 +220,7 @@
         mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER);
         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
         mTelephony = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class);
 
         // Used to initialize the CPU Frequency atom.
         PowerProfile powerProfile = new PowerProfile(mContext);
@@ -224,6 +233,10 @@
                     numSpeedSteps);
             firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i);
         }
+
+        // Used for CPU_TIME_PER_THREAD_FREQ
+        mKernelCpuThreadReader =
+                KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext);
     }
 
     @Override
@@ -291,7 +304,6 @@
         registerDebugFailingElapsedClock();
         registerBuildInformation();
         registerRoleHolder();
-        registerDangerousPermissionState();
         registerTimeZoneDataInfo();
         registerExternalStorageInfo();
         registerAppsOnExternalStorageInfo();
@@ -346,6 +358,51 @@
             return mThermalService;
         }
     }
+
+    private IStoraged getIStoragedService() {
+        synchronized (mStoragedLock) {
+            if (mStorageService == null) {
+                mStorageService = IStoraged.Stub.asInterface(
+                        ServiceManager.getService("storaged"));
+            }
+            if (mStorageService != null) {
+                try {
+                    mStorageService.asBinder().linkToDeath(() -> {
+                        synchronized (mStoragedLock) {
+                            mStorageService = null;
+                        }
+                    }, /* flags */ 0);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "linkToDeath with storagedService failed", e);
+                    mStorageService = null;
+                }
+            }
+        }
+        return mStorageService;
+    }
+
+    private INotificationManager getINotificationManagerService() {
+        synchronized (mNotificationStatsLock) {
+            if (mNotificationManagerService == null) {
+                mNotificationManagerService = INotificationManager.Stub.asInterface(
+                                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+            }
+            if (mNotificationManagerService != null) {
+                try {
+                    mNotificationManagerService.asBinder().linkToDeath(() -> {
+                        synchronized (mNotificationStatsLock) {
+                            mNotificationManagerService = null;
+                        }
+                    }, /* flags */ 0);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "linkToDeath with notificationManager failed", e);
+                    mNotificationManagerService = null;
+                }
+            }
+        }
+        return mNotificationManagerService;
+    }
+
     private void registerWifiBytesTransfer() {
         int tagId = StatsLog.WIFI_BYTES_TRANSFER;
         PullAtomMetadata metadata = new PullAtomMetadata.Builder()
@@ -935,12 +992,29 @@
         return StatsManager.PULL_SUCCESS;
     }
 
+    private static final long NS_PER_SEC = 1000000000;
+
     private void registerSystemElapsedRealtime() {
-        // No op.
+        int tagId = StatsLog.SYSTEM_ELAPSED_REALTIME;
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setCoolDownNs(NS_PER_SEC)
+                .setTimeoutNs(NS_PER_SEC / 2)
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullSystemElapsedRealtime(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullSystemElapsedRealtime() {
-        // No op.
+    private int pullSystemElapsedRealtime(int atomTag, List<StatsEvent> pulledData) {
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeLong(SystemClock.elapsedRealtime())
+                .build();
+        pulledData.add(e);
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerSystemUptime() {
@@ -1426,59 +1500,372 @@
     }
 
     private void registerLooperStats() {
-        // No op.
+        int tagId = StatsLog.LOOPER_STATS;
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setAdditiveFields(new int[] {5, 6, 7, 8, 9})
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullLooperStats(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullLooperStats() {
-        // No op.
+    private int pullLooperStats(int atomTag, List<StatsEvent> pulledData) {
+        LooperStats looperStats = LocalServices.getService(LooperStats.class);
+        if (looperStats == null) {
+            return StatsManager.PULL_SKIP;
+        }
+
+        List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
+        looperStats.reset();
+        for (LooperStats.ExportedEntry entry : entries) {
+            StatsEvent e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(entry.workSourceUid)
+                    .writeString(entry.handlerClassName)
+                    .writeString(entry.threadName)
+                    .writeString(entry.messageName)
+                    .writeLong(entry.messageCount)
+                    .writeLong(entry.exceptionCount)
+                    .writeLong(entry.recordedMessageCount)
+                    .writeLong(entry.totalLatencyMicros)
+                    .writeLong(entry.cpuUsageMicros)
+                    .writeBoolean(entry.isInteractive)
+                    .writeLong(entry.maxCpuUsageMicros)
+                    .writeLong(entry.maxLatencyMicros)
+                    .writeLong(entry.recordedDelayMessageCount)
+                    .writeLong(entry.delayMillis)
+                    .writeLong(entry.maxDelayMillis)
+                    .build();
+            pulledData.add(e);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerDiskStats() {
-        // No op.
+        int tagId = StatsLog.DISK_STATS;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullDiskStats(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullDiskStats() {
-        // No op.
+    private int pullDiskStats(int atomTag, List<StatsEvent> pulledData) {
+        // Run a quick-and-dirty performance test: write 512 bytes
+        byte[] junk = new byte[512];
+        for (int i = 0; i < junk.length; i++) junk[i] = (byte) i;  // Write nonzero bytes
+
+        File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
+        FileOutputStream fos = null;
+        IOException error = null;
+
+        long before = SystemClock.elapsedRealtime();
+        try {
+            fos = new FileOutputStream(tmp);
+            fos.write(junk);
+        } catch (IOException e) {
+            error = e;
+        } finally {
+            try {
+                if (fos != null) fos.close();
+            } catch (IOException e) {
+                // Do nothing.
+            }
+        }
+
+        long latency = SystemClock.elapsedRealtime() - before;
+        if (tmp.exists()) tmp.delete();
+
+        if (error != null) {
+            Slog.e(TAG, "Error performing diskstats latency test");
+            latency = -1;
+        }
+        // File based encryption.
+        boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
+
+        //Recent disk write speed. Binder call to storaged.
+        int writeSpeed = -1;
+        IStoraged storaged = getIStoragedService();
+        if (storaged == null) {
+            return StatsManager.PULL_SKIP;
+        }
+        try {
+            writeSpeed = storaged.getRecentPerf();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "storaged not found");
+        }
+
+        // Add info pulledData.
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeLong(latency)
+                .writeBoolean(fileBased)
+                .writeInt(writeSpeed)
+                .build();
+        pulledData.add(e);
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerDirectoryUsage() {
-        // No op.
+        int tagId = StatsLog.DIRECTORY_USAGE;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullDirectoryUsage(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullDirectoryUsage() {
-        // No op.
+    private int pullDirectoryUsage(int atomTag, List<StatsEvent> pulledData) {
+        StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
+        StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
+        StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
+
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA)
+                .writeLong(statFsData.getAvailableBytes())
+                .writeLong(statFsData.getTotalBytes())
+                .build();
+        pulledData.add(e);
+
+        e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE)
+                .writeLong(statFsCache.getAvailableBytes())
+                .writeLong(statFsCache.getTotalBytes())
+                .build();
+        pulledData.add(e);
+
+        e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM)
+                .writeLong(statFsSystem.getAvailableBytes())
+                .writeLong(statFsSystem.getTotalBytes())
+                .build();
+        pulledData.add(e);
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerAppSize() {
-        // No op.
+        int tagId = StatsLog.APP_SIZE;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullAppSize(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullAppSize() {
-        // No op.
+    private int pullAppSize(int atomTag, List<StatsEvent> pulledData) {
+        try {
+            String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
+            JSONObject json = new JSONObject(jsonStr);
+            long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
+            JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
+            JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
+            JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
+            JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
+            // Sanity check: Ensure all 4 lists have the same length.
+            int length = pkg_names.length();
+            if (app_sizes.length() != length || app_data_sizes.length() != length
+                    || app_cache_sizes.length() != length) {
+                Slog.e(TAG, "formatting error in diskstats cache file!");
+                return StatsManager.PULL_SKIP;
+            }
+            for (int i = 0; i < length; i++) {
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeString(pkg_names.getString(i))
+                        .writeLong(app_sizes.optLong(i, /* fallback */ -1L))
+                        .writeLong(app_data_sizes.optLong(i, /* fallback */ -1L))
+                        .writeLong(app_cache_sizes.optLong(i, /* fallback */ -1L))
+                        .writeLong(cache_time)
+                        .build();
+                pulledData.add(e);
+            }
+        } catch (IOException | JSONException e) {
+            Slog.e(TAG, "exception reading diskstats cache file", e);
+            return StatsManager.PULL_SKIP;
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerCategorySize() {
-        // No op.
+        int tagId = StatsLog.CATEGORY_SIZE;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullCategorySize(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullCategorySize() {
-        // No op.
+    private int pullCategorySize(int atomTag, List<StatsEvent> pulledData) {
+        try {
+            String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
+            JSONObject json = new JSONObject(jsonStr);
+            long cacheTime = json.optLong(
+                    DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, /* fallback */ -1L);
+
+            StatsEvent e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.APP_SIZE_AGG_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.APP_CACHE_AGG_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.PHOTOS_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS)
+                    .writeLong(
+                            json.optLong(DiskStatsFileLogger.VIDEOS_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.AUDIO_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS)
+                    .writeLong(
+                            json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.SYSTEM_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+
+            e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER)
+                    .writeLong(json.optLong(
+                            DiskStatsFileLogger.MISC_KEY, /* fallback */ -1L))
+                    .writeLong(cacheTime)
+                    .build();
+            pulledData.add(e);
+        } catch (IOException | JSONException e) {
+            Slog.e(TAG, "exception reading diskstats cache file", e);
+            return StatsManager.PULL_SKIP;
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerNumFingerprintsEnrolled() {
-        // No op.
-    }
-
-    private void pullNumFingerprintsEnrolled() {
-        // No op.
+        int tagId = StatsLog.NUM_FINGERPRINTS_ENROLLED;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullNumBiometricsEnrolled(
+                        BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
     private void registerNumFacesEnrolled() {
-        // No op.
+        int tagId = StatsLog.NUM_FACES_ENROLLED;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullNumBiometricsEnrolled(
+                        BiometricsProtoEnums.MODALITY_FACE, atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullNumFacesEnrolled() {
-        // No op.
+    private int pullNumBiometricsEnrolled(int modality, int atomTag, List<StatsEvent> pulledData) {
+        final PackageManager pm = mContext.getPackageManager();
+        FingerprintManager fingerprintManager = null;
+        FaceManager faceManager = null;
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+            fingerprintManager = mContext.getSystemService(FingerprintManager.class);
+        }
+        if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+            faceManager = mContext.getSystemService(FaceManager.class);
+        }
+
+        if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+        if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+        UserManager userManager = mContext.getSystemService(UserManager.class);
+        if (userManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            for (UserInfo user : userManager.getUsers()) {
+                final int userId = user.getUserHandle().getIdentifier();
+                int numEnrolled = 0;
+                if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
+                    numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
+                } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
+                    numEnrolled = faceManager.getEnrolledFaces(userId).size();
+                } else {
+                    return StatsManager.PULL_SKIP;
+                }
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeInt(userId)
+                        .writeInt(numEnrolled)
+                        .build();
+                pulledData.add(e);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerProcStats() {
@@ -1497,12 +1884,44 @@
         // No op.
     }
 
+    private StoragedUidIoStatsReader mStoragedUidIoStatsReader =
+            new StoragedUidIoStatsReader();
+
     private void registerDiskIO() {
-        // No op.
+        int tagId = StatsLog.DISK_IO;
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setAdditiveFields(new int[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11})
+                .setCoolDownNs(3 * NS_PER_SEC)
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullDiskIO(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullDiskIO() {
-        // No op.
+    private int pullDiskIO(int atomTag, List<StatsEvent> pulledData) {
+        mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
+                fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
+                fgFsync, bgFsync) -> {
+            StatsEvent e = StatsEvent.newBuilder()
+                    .setAtomId(atomTag)
+                    .writeInt(uid)
+                    .writeLong(fgCharsRead)
+                    .writeLong(fgCharsWrite)
+                    .writeLong(fgBytesRead)
+                    .writeLong(fgBytesWrite)
+                    .writeLong(bgCharsRead)
+                    .writeLong(bgCharsWrite)
+                    .writeLong(bgBytesRead)
+                    .writeLong(bgBytesWrite)
+                    .writeLong(fgFsync)
+                    .writeLong(bgFsync)
+                    .build();
+            pulledData.add(e);
+        });
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerPowerProfile() {
@@ -1528,20 +1947,118 @@
         return StatsManager.PULL_SUCCESS;
     }
 
+    private final Object mCpuTrackerLock = new Object();
+    @GuardedBy("mCpuTrackerLock")
+    private ProcessCpuTracker mProcessCpuTracker;
+
     private void registerProcessCpuTime() {
-        // No op.
+        int tagId = StatsLog.PROCESS_CPU_TIME;
+        // Min cool-down is 5 sec, inline with what ActivityManagerService uses.
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setCoolDownNs(5 * NS_PER_SEC)
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullProcessCpuTime(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullProcessCpuTime() {
-        // No op.
+    private int pullProcessCpuTime(int atomTag, List<StatsEvent> pulledData) {
+        synchronized (mCpuTrackerLock) {
+            if (mProcessCpuTracker == null) {
+                mProcessCpuTracker = new ProcessCpuTracker(false);
+                mProcessCpuTracker.init();
+            }
+            mProcessCpuTracker.update();
+            for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
+                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeInt(st.uid)
+                        .writeString(st.name)
+                        .writeLong(st.base_utime)
+                        .writeLong(st.base_stime)
+                        .build();
+                pulledData.add(e);
+            }
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
+    @Nullable
+    private KernelCpuThreadReaderDiff mKernelCpuThreadReader;
+    private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8;
+
     private void registerCpuTimePerThreadFreq() {
-        // No op.
+        int tagId = StatsLog.CPU_TIME_PER_THREAD_FREQ;
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setAdditiveFields(new int[] {7, 9, 11, 13, 15, 17, 19, 21})
+                .build();
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                metadata,
+                (atomTag, data) -> pullCpuTimePerThreadFreq(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullCpuTimePerThreadFreq() {
-        // No op.
+    private int pullCpuTimePerThreadFreq(int atomTag, List<StatsEvent> pulledData) {
+        if (this.mKernelCpuThreadReader == null) {
+            Slog.e(TAG, "mKernelCpuThreadReader is null");
+            return StatsManager.PULL_SKIP;
+        }
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
+                this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
+        if (processCpuUsages == null) {
+            Slog.e(TAG, "processCpuUsages is null");
+            return StatsManager.PULL_SKIP;
+        }
+        int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
+        if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
+            String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
+                    + " frequencies, but got " + cpuFrequencies.length;
+            Slog.w(TAG, message);
+            return StatsManager.PULL_SKIP;
+        }
+        for (int i = 0; i < processCpuUsages.size(); i++) {
+            KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
+            ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
+                    processCpuUsage.threadCpuUsages;
+            for (int j = 0; j < threadCpuUsages.size(); j++) {
+                KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
+                if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
+                    String message = "Unexpected number of usage times,"
+                            + " expected " + cpuFrequencies.length
+                            + " but got " + threadCpuUsage.usageTimesMillis.length;
+                    Slog.w(TAG, message);
+                    return StatsManager.PULL_SKIP;
+                }
+
+                StatsEvent.Builder e = StatsEvent.newBuilder();
+                e.setAtomId(atomTag);
+                e.writeInt(processCpuUsage.uid);
+                e.writeInt(processCpuUsage.processId);
+                e.writeInt(threadCpuUsage.threadId);
+                e.writeString(processCpuUsage.processName);
+                e.writeString(threadCpuUsage.threadName);
+                for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
+                    if (k < cpuFrequencies.length) {
+                        e.writeInt(cpuFrequencies[k]);
+                        e.writeInt(threadCpuUsage.usageTimesMillis[k]);
+                    } else {
+                        // If we have no more frequencies to write, we still must write empty data.
+                        // We know that this data is empty (and not just zero) because all
+                        // frequencies are expected to be greater than zero
+                        e.writeInt(0);
+                        e.writeInt(0);
+                    }
+                }
+                pulledData.add(e.build());
+            }
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     // TODO: move to top of file when all migrations are complete
@@ -1703,43 +2220,280 @@
     }
 
     private void registerRoleHolder() {
-        // No op.
+        int tagId = StatsLog.ROLE_HOLDER;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullRoleHolder(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullRoleHolder() {
-        // No op.
+    // Add a RoleHolder atom for each package that holds a role.
+    private int pullRoleHolder(int atomTag, List<StatsEvent> pulledData) {
+        long callingToken = Binder.clearCallingIdentity();
+        try {
+            PackageManager pm = mContext.getPackageManager();
+            RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
+
+            List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+
+            int numUsers = users.size();
+            for (int userNum = 0; userNum < numUsers; userNum++) {
+                int userId = users.get(userNum).getUserHandle().getIdentifier();
+
+                ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(userId);
+
+                int numRoles = roles.size();
+                for (int roleNum = 0; roleNum < numRoles; roleNum++) {
+                    String roleName = roles.keyAt(roleNum);
+                    ArraySet<String> holders = roles.valueAt(roleNum);
+
+                    int numHolders = holders.size();
+                    for (int holderNum = 0; holderNum < numHolders; holderNum++) {
+                        String holderName = holders.valueAt(holderNum);
+
+                        PackageInfo pkg;
+                        try {
+                            pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
+                        } catch (PackageManager.NameNotFoundException e) {
+                            Slog.w(TAG, "Role holder " + holderName + " not found");
+                            return StatsManager.PULL_SKIP;
+                        }
+
+                        StatsEvent e = StatsEvent.newBuilder()
+                                .setAtomId(atomTag)
+                                .writeInt(pkg.applicationInfo.uid)
+                                .writeString(holderName)
+                                .writeString(roleName)
+                                .build();
+                        pulledData.add(e);
+                    }
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(callingToken);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerDangerousPermissionState() {
-        // No op.
+        int tagId = StatsLog.DANGEROUS_PERMISSION_STATE;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullDangerousPermissionState(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullDangerousPermissionState() {
-        // No op.
+    private int pullDangerousPermissionState(int atomTag, List<StatsEvent> pulledData) {
+        final long token = Binder.clearCallingIdentity();
+        Set<Integer> reportedUids = new HashSet<>();
+        try {
+            PackageManager pm = mContext.getPackageManager();
+
+            List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+
+            int numUsers = users.size();
+            for (int userNum = 0; userNum < numUsers; userNum++) {
+                UserHandle user = users.get(userNum).getUserHandle();
+
+                List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
+                        PackageManager.GET_PERMISSIONS, user.getIdentifier());
+
+                int numPkgs = pkgs.size();
+                for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
+                    PackageInfo pkg = pkgs.get(pkgNum);
+
+                    if (pkg.requestedPermissions == null) {
+                        continue;
+                    }
+
+                    if (reportedUids.contains(pkg.applicationInfo.uid)) {
+                        // do not report same uid twice
+                        continue;
+                    }
+                    reportedUids.add(pkg.applicationInfo.uid);
+
+                    if (atomTag == StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
+                            && ThreadLocalRandom.current().nextFloat() > 0.2f) {
+                        continue;
+                    }
+
+                    int numPerms = pkg.requestedPermissions.length;
+                    for (int permNum  = 0; permNum < numPerms; permNum++) {
+                        String permName = pkg.requestedPermissions[permNum];
+
+                        PermissionInfo permissionInfo;
+                        int permissionFlags = 0;
+                        try {
+                            permissionInfo = pm.getPermissionInfo(permName, 0);
+                            permissionFlags =
+                                    pm.getPermissionFlags(permName, pkg.packageName, user);
+                        } catch (PackageManager.NameNotFoundException ignored) {
+                            continue;
+                        }
+
+                        if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
+                            continue;
+                        }
+
+                        StatsEvent.Builder e = StatsEvent.newBuilder();
+                        e.setAtomId(atomTag);
+                        e.writeString(permName);
+                        e.writeInt(pkg.applicationInfo.uid);
+                        if (atomTag == StatsLog.DANGEROUS_PERMISSION_STATE) {
+                            e.writeString("");
+                        }
+                        e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
+                                & REQUESTED_PERMISSION_GRANTED) != 0);
+                        e.writeInt(permissionFlags);
+
+                        pulledData.add(e.build());
+                    }
+                }
+            }
+        } catch (Throwable t) {
+            Log.e(TAG, "Could not read permissions", t);
+            return StatsManager.PULL_SKIP;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerTimeZoneDataInfo() {
-        // No op.
+        int tagId = StatsLog.TIME_ZONE_DATA_INFO;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullTimeZoneDataInfo(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullTimeZoneDataInfo() {
-        // No op.
+    private int pullTimeZoneDataInfo(int atomTag, List<StatsEvent> pulledData) {
+        String tzDbVersion = "Unknown";
+        try {
+            tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
+        } catch (MissingResourceException e) {
+            Slog.e(TAG, "Getting tzdb version failed: ", e);
+            return StatsManager.PULL_SKIP;
+        }
+
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeString(tzDbVersion)
+                .build();
+        pulledData.add(e);
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerExternalStorageInfo() {
-        // No op.
+        int tagId = StatsLog.EXTERNAL_STORAGE_INFO;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullExternalStorageInfo(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullExternalStorageInfo() {
-        // No op.
+    private int pullExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
+        if (mStorageManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+
+        List<VolumeInfo> volumes = mStorageManager.getVolumes();
+        for (VolumeInfo vol : volumes) {
+            final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
+            final DiskInfo diskInfo = vol.getDisk();
+            if (diskInfo != null && envState.equals(Environment.MEDIA_MOUNTED)) {
+                // Get the type of the volume, if it is adoptable or portable.
+                int volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
+                if (vol.getType() == TYPE_PUBLIC) {
+                    volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
+                } else if (vol.getType() == TYPE_PRIVATE) {
+                    volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
+                }
+
+                // Get the type of external storage inserted in the device (sd cards, usb, etc.)
+                int externalStorageType;
+                if (diskInfo.isSd()) {
+                    externalStorageType = StorageEnums.SD_CARD;
+                } else if (diskInfo.isUsb()) {
+                    externalStorageType = StorageEnums.USB;
+                } else {
+                    externalStorageType = StorageEnums.OTHER;
+                }
+
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeInt(externalStorageType)
+                        .writeInt(volumeType)
+                        .writeLong(diskInfo.size)
+                        .build();
+                pulledData.add(e);
+            }
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerAppsOnExternalStorageInfo() {
-        // No op.
+        int tagId = StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullAppsOnExternalStorageInfo(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullAppsOnExternalStorageInfo() {
-        // No op.
+    private int pullAppsOnExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
+        if (mStorageManager == null) {
+            return StatsManager.PULL_SKIP;
+        }
+
+        PackageManager pm = mContext.getPackageManager();
+        List<ApplicationInfo> apps = pm.getInstalledApplications(/*flags=*/ 0);
+        for (ApplicationInfo appInfo : apps) {
+            UUID storageUuid = appInfo.storageUuid;
+            if (storageUuid == null) {
+                continue;
+            }
+
+            VolumeInfo volumeInfo = mStorageManager.findVolumeByUuid(
+                    appInfo.storageUuid.toString());
+            if (volumeInfo == null) {
+                continue;
+            }
+
+            DiskInfo diskInfo = volumeInfo.getDisk();
+            if (diskInfo == null) {
+                continue;
+            }
+
+            int externalStorageType = -1;
+            if (diskInfo.isSd()) {
+                externalStorageType = StorageEnums.SD_CARD;
+            } else if (diskInfo.isUsb()) {
+                externalStorageType = StorageEnums.USB;
+            } else if (appInfo.isExternal()) {
+                externalStorageType = StorageEnums.OTHER;
+            }
+
+            // App is installed on external storage.
+            if (externalStorageType != -1) {
+                StatsEvent e = StatsEvent.newBuilder()
+                        .setAtomId(atomTag)
+                        .writeInt(externalStorageType)
+                        .writeString(appInfo.packageName)
+                        .build();
+                pulledData.add(e);
+            }
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerFaceSettings() {
@@ -1751,26 +2505,167 @@
     }
 
     private void registerAppOps() {
-        // No op.
+        int tagId = StatsLog.APP_OPS;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullAppOps(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
+
     }
 
-    private void pullAppOps() {
-        // No op.
+    private int pullAppOps(int atomTag, List<StatsEvent> pulledData) {
+        long token = Binder.clearCallingIdentity();
+        try {
+            AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+
+            CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
+            HistoricalOpsRequest histOpsRequest =
+                    new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).build();
+            appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
+
+            HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
+                    TimeUnit.MILLISECONDS);
+
+            for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
+                final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
+                final int uid = uidOps.getUid();
+                for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
+                    final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
+                    for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
+                        final AppOpsManager.HistoricalOp op  = packageOps.getOpAt(opIdx);
+
+                        StatsEvent.Builder e = StatsEvent.newBuilder();
+                        e.setAtomId(atomTag);
+                        e.writeInt(uid);
+                        e.writeString(packageOps.getPackageName());
+                        e.writeInt(op.getOpCode());
+                        e.writeLong(op.getForegroundAccessCount(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getForegroundRejectCount(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
+                        e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
+
+                        String perm = AppOpsManager.opToPermission(op.getOpCode());
+                        if (perm == null) {
+                            e.writeBoolean(false);
+                        } else {
+                            PermissionInfo permInfo;
+                            try {
+                                permInfo = mContext.getPackageManager().getPermissionInfo(perm, 0);
+                                e.writeBoolean(permInfo.getProtection() == PROTECTION_DANGEROUS);
+                            } catch (PackageManager.NameNotFoundException exception) {
+                                e.writeBoolean(false);
+                            }
+                        }
+
+                        pulledData.add(e.build());
+                    }
+                }
+            }
+        } catch (Throwable t) {
+            // TODO: catch exceptions at a more granular level
+            Slog.e(TAG, "Could not read appops", t);
+            return StatsManager.PULL_SKIP;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    static void unpackStreamedData(int atomTag, List<StatsEvent> pulledData,
+            List<ParcelFileDescriptor> statsFiles) throws IOException {
+        InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0));
+        int[] len = new int[1];
+        byte[] stats = readFully(stream, len);
+        StatsEvent e = StatsEvent.newBuilder()
+                .setAtomId(atomTag)
+                .writeByteArray(Arrays.copyOf(stats, len[0]))
+                .build();
+        pulledData.add(e);
+    }
+
+    static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
+        int pos = 0;
+        final int initialAvail = stream.available();
+        byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384];
+        while (true) {
+            int amt = stream.read(data, pos, data.length - pos);
+            if (DEBUG) {
+                Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length);
+            }
+            if (amt < 0) {
+                if (DEBUG) {
+                    Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length);
+                }
+                outLen[0] = pos;
+                return data;
+            }
+            pos += amt;
+            if (pos >= data.length) {
+                byte[] newData = new byte[pos + 16384];
+                if (DEBUG) {
+                    Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length);
+                }
+                System.arraycopy(data, 0, newData, 0, pos);
+                data = newData;
+            }
+        }
     }
 
     private void registerNotificationRemoteViews() {
-        // No op.
+        int tagId = StatsLog.NOTIFICATION_REMOTE_VIEWS;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullNotificationRemoteViews(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 
-    private void pullNotificationRemoteViews() {
-        // No op.
+    private int pullNotificationRemoteViews(int atomTag, List<StatsEvent> pulledData) {
+        INotificationManager notificationManagerService = getINotificationManagerService();
+        if (notificationManagerService == null) {
+            return StatsManager.PULL_SKIP;
+        }
+        final long callingToken = Binder.clearCallingIdentity();
+        try {
+            // determine last pull tine. Copy file trick from pullProcessStats?
+            long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
+            long lastNotificationStatsNs = wallClockNanos -
+                    TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
+
+            List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
+            notificationManagerService.pullStats(lastNotificationStatsNs,
+                    NotificationManagerService.REPORT_REMOTE_VIEWS, true, statsFiles);
+            if (statsFiles.size() != 1) {
+                return StatsManager.PULL_SKIP;
+            }
+            unpackStreamedData(atomTag, pulledData, statsFiles);
+        } catch (IOException e) {
+            Slog.e(TAG, "Getting notistats failed: ", e);
+            return StatsManager.PULL_SKIP;
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Getting notistats failed: ", e);
+            return StatsManager.PULL_SKIP;
+        } catch (SecurityException e) {
+            Slog.e(TAG, "Getting notistats failed: ", e);
+            return StatsManager.PULL_SKIP;
+        } finally {
+            Binder.restoreCallingIdentity(callingToken);
+        }
+        return StatsManager.PULL_SUCCESS;
     }
 
     private void registerDangerousPermissionStateSampled() {
-        // No op.
-    }
-
-    private void pullDangerousPermissionStateSampled() {
-        // No op.
+        int tagId = StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED;
+        mStatsManager.registerPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                (atomTag, data) -> pullDangerousPermissionState(atomTag, data),
+                BackgroundThread.getExecutor()
+        );
     }
 }
diff --git a/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
index 9cd743b..8b6526ff 100644
--- a/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
+++ b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
@@ -20,6 +20,7 @@
 #include <inttypes.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <vector>
 
 #include <jni.h>
 
diff --git a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
index ecd07bd..b14291b 100644
--- a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
@@ -188,7 +188,7 @@
     }
 
     @Test
-    public void getOverrideAllowedState_betaBuildEnabledChangeDebugApp_rejectOverride()
+    public void getOverrideAllowedState_betaBuildEnabledChangeDebugApp_allowOverride()
             throws Exception {
         CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext)
                         .addEnabledChangeWithId(1).build();
@@ -203,11 +203,11 @@
                 overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME);
 
         assertThat(allowedState)
-                .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1));
+                .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1));
     }
 
     @Test
-    public void getOverrideAllowedState_betaBuildDisabledChangeDebugApp_rejectOverride()
+    public void getOverrideAllowedState_betaBuildDisabledChangeDebugApp_allowOverride()
             throws Exception {
         CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext)
                         .addDisabledChangeWithId(1).build();
@@ -221,7 +221,7 @@
                 overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME);
 
         assertThat(allowedState)
-                .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1));
+                .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1));
     }
 
     @Test
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index c4c1e21..c3fb510 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -849,6 +849,17 @@
      */
     public static final int PRESENTATION_PAYPHONE = 4;
 
+
+    /*
+     * Values for the adb property "persist.radio.videocall.audio.output"
+     */
+    /** @hide */
+    public static final int AUDIO_OUTPUT_ENABLE_SPEAKER = 0;
+    /** @hide */
+    public static final int AUDIO_OUTPUT_DISABLE_SPEAKER = 1;
+    /** @hide */
+    public static final int AUDIO_OUTPUT_DEFAULT = AUDIO_OUTPUT_ENABLE_SPEAKER;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index b8b203d..89cd461 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -558,7 +558,7 @@
         }
 
         if (DBG) {
-            Log.d(LOG_TAG, "No READ_PRIVILEDED_PHONE_STATE permission, "
+            Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE permission, "
                     + "check carrier privilege next.");
         }
 
@@ -566,6 +566,33 @@
     }
 
     /**
+     * Ensure the caller (or self, if not processing an IPC) has
+     * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
+     * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or carrier privileges.
+     *
+     * @throws SecurityException if the caller does not have the required permission/privileges
+     */
+    public static void enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+            Context context, int subId, String message) {
+        if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+                == PERMISSION_GRANTED) {
+            return;
+        }
+
+        if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+                == PERMISSION_GRANTED) {
+            return;
+        }
+
+        if (DBG) {
+            Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE nor READ_PRECISE_PHONE_STATE permission"
+                    + ", check carrier privilege next.");
+        }
+
+        enforceCallingOrSelfCarrierPrivilege(context, subId, message);
+    }
+
+    /**
      * Make sure the caller (or self, if not processing an IPC) has carrier privileges.
      *
      * @throws SecurityException if the caller does not have the required privileges
diff --git a/telephony/framework-telephony-jarjar-rules.txt b/telephony/framework-telephony-jarjar-rules.txt
index 7cab806..212eba1 100644
--- a/telephony/framework-telephony-jarjar-rules.txt
+++ b/telephony/framework-telephony-jarjar-rules.txt
@@ -1,4 +1,9 @@
 rule android.telephony.Annotation* android.telephony.framework.Annotation@1
+rule android.util.RecurrenceRule* android.telephony.RecurrenceRule@1
 rule com.android.i18n.phonenumbers.** com.android.telephony.framework.phonenumbers.@1
-#TODO: add jarjar rules for statically linked util classes
-
+rule com.android.internal.os.SomeArgs* android.telephony.SomeArgs@1
+rule com.android.internal.util.BitwiseInputStream* android.telephony.BitwiseInputStream@1
+rule com.android.internal.util.BitwiseOutputStream* android.telephony.BitwiseOutputStream@1
+rule com.android.internal.util.Preconditions* android.telephony.Preconditions@1
+rule com.android.internal.util.IndentingPrintWriter* android.telephony.IndentingPrintWriter@1
+rule com.android.internal.util.HexDump* android.telephony.HexDump@1
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index bb28df2..d325cd8 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -50,18 +50,12 @@
 
     /**
      * Transport type for Wireless Wide Area Networks (i.e. Cellular)
-     * @hide
      */
-    @SystemApi
-    @TestApi
     public static final int TRANSPORT_TYPE_WWAN = 1;
 
     /**
      * Transport type for Wireless Local Area Networks (i.e. Wifi)
-     * @hide
      */
-    @SystemApi
-    @TestApi
     public static final int TRANSPORT_TYPE_WLAN = 2;
 
     /** @hide */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5a7c3b3..ff31d3e 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1575,7 +1575,10 @@
     public static final String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName";
     public static final String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
     public static final String KEY_MMS_USER_AGENT_STRING = "userAgent";
-    /** @hide */
+    /**
+     * If true, add "Connection: close" header to MMS HTTP requests so the connection
+     * is immediately closed (disabling keep-alive).
+     */
     public static final String KEY_MMS_CLOSE_CONNECTION_BOOL = "mmsCloseConnection";
 
     /**
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index 475c99b..ec86c14 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.SuppressLint;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.hardware.radio.V1_4.CellInfo.Info;
 import android.os.Parcel;
@@ -179,6 +180,18 @@
      *
      * @return a time stamp in nanos since boot.
      */
+    @SuppressLint("MethodNameUnits")
+    public long getTimestampNanos() {
+        return mTimeStamp;
+    }
+
+    /**
+     * Approximate time this cell information was received from the modem.
+     *
+     * @return a time stamp in nanos since boot.
+     * @deprecated Use {@link #getTimestampNanos} instead.
+     */
+    @Deprecated
     public long getTimeStamp() {
         return mTimeStamp;
     }
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index cbd5ed6..32ffb75 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -36,10 +36,7 @@
 
 /**
  * Description of a mobile network registration info
- * @hide
  */
-@SystemApi
-@TestApi
 public final class NetworkRegistrationInfo implements Parcelable {
     /**
      * Network domain
@@ -51,9 +48,9 @@
 
     /** Unknown / Unspecified domain */
     public static final int DOMAIN_UNKNOWN = 0;
-    /** Circuit switching domain */
+    /** Circuit switched domain */
     public static final int DOMAIN_CS = android.hardware.radio.V1_5.Domain.CS;
-    /** Packet switching domain */
+    /** Packet switched domain */
     public static final int DOMAIN_PS = android.hardware.radio.V1_5.Domain.PS;
     /** Applicable to both CS and PS Domain */
     public static final int DOMAIN_CS_PS = DOMAIN_CS | DOMAIN_PS;
@@ -69,17 +66,41 @@
                     REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING})
     public @interface RegistrationState {}
 
-    /** Not registered. The device is not currently searching a new operator to register. */
+    /**
+     * Not registered. The device is not currently searching a new operator to register.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0;
-    /** Registered on home network. */
+    /**
+     * Registered on home network.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_HOME = 1;
-    /** Not registered. The device is currently searching a new operator to register. */
+    /**
+     * Not registered. The device is currently searching a new operator to register.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2;
-    /** Registration denied. */
+    /**
+     * Registration denied.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_DENIED = 3;
-    /** Registration state is unknown. */
+    /**
+     * Registration state is unknown.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_UNKNOWN = 4;
-    /** Registered on roaming network. */
+    /**
+     * Registered on roaming network.
+     * @hide
+     */
+    @SystemApi @TestApi
     public static final int REGISTRATION_STATE_ROAMING = 5;
 
     /** @hide */
@@ -92,7 +113,6 @@
     /**
      * The device isn't camped on an LTE cell or the LTE cell doesn't support E-UTRA-NR
      * Dual Connectivity(EN-DC).
-     * @hide
      */
     public static final int NR_STATE_NONE = 0;
 
@@ -100,7 +120,6 @@
      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but
      * either the use of dual connectivity with NR(DCNR) is restricted or NR is not supported by
      * the selected PLMN.
-     * @hide
      */
     public static final int NR_STATE_RESTRICTED = 1;
 
@@ -108,14 +127,12 @@
      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and both
      * the use of dual connectivity with NR(DCNR) is not restricted and NR is supported by the
      * selected PLMN.
-     * @hide
      */
     public static final int NR_STATE_NOT_RESTRICTED = 2;
 
     /**
      * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and
      * also connected to at least one 5G cell as a secondary serving cell.
-     * @hide
      */
     public static final int NR_STATE_CONNECTED = 3;
 
@@ -129,22 +146,34 @@
                     SERVICE_TYPE_VIDEO, SERVICE_TYPE_EMERGENCY})
     public @interface ServiceType {}
 
-    /** Unkown service */
+    /**
+     * Unknown service
+     */
     public static final int SERVICE_TYPE_UNKNOWN    = 0;
 
-    /** Voice service */
+    /**
+     * Voice service
+     */
     public static final int SERVICE_TYPE_VOICE      = 1;
 
-    /** Data service */
+    /**
+     * Data service
+     */
     public static final int SERVICE_TYPE_DATA       = 2;
 
-    /** SMS service */
+    /**
+     * SMS service
+     */
     public static final int SERVICE_TYPE_SMS        = 3;
 
-    /** Video service */
+    /**
+     * Video service
+     */
     public static final int SERVICE_TYPE_VIDEO      = 4;
 
-    /** Emergency service */
+    /**
+     * Emergency service
+     */
     public static final int SERVICE_TYPE_EMERGENCY  = 5;
 
     @Domain
@@ -330,9 +359,7 @@
      * Get the 5G NR connection state.
      *
      * @return the 5G NR connection state.
-     * @hide
      */
-    @SystemApi
     public @NRState int getNrState() {
         return mNrState;
     }
@@ -344,7 +371,10 @@
 
     /**
      * @return The registration state.
+     *
+     * @hide
      */
+    @SystemApi @TestApi
     public @RegistrationState int getRegistrationState() {
         return mRegistrationState;
     }
@@ -352,6 +382,21 @@
     /**
      * @return {@code true} if registered on roaming network, {@code false} otherwise.
      */
+    public boolean isRegistered() {
+        return mRegistrationState == REGISTRATION_STATE_HOME
+                || mRegistrationState == REGISTRATION_STATE_ROAMING;
+    }
+
+    /**
+     * @return {@code true} if registered on roaming network, {@code false} otherwise.
+     */
+    public boolean isSearching() {
+        return mRegistrationState == REGISTRATION_STATE_NOT_REGISTERED_SEARCHING;
+    }
+
+    /**
+     * @return {@code true} if registered on roaming network, {@code false} otherwise.
+     */
     public boolean isRoaming() {
         return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING;
     }
@@ -376,15 +421,18 @@
 
     /**
      * @return the current network roaming type.
+     * @hide
      */
-
+    @SystemApi @TestApi
     public @ServiceState.RoamingType int getRoamingType() {
         return mRoamingType;
     }
 
     /**
      * @return Whether emergency is enabled.
+     * @hide
      */
+    @SystemApi @TestApi
     public boolean isEmergencyEnabled() { return mEmergencyOnly; }
 
     /**
@@ -422,7 +470,9 @@
      * @return Reason for denial if the registration state is {@link #REGISTRATION_STATE_DENIED}.
      * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
      * 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA
+     * @hide
      */
+    @SystemApi @TestApi
     public int getRejectCause() {
         return mRejectCause;
     }
@@ -445,8 +495,10 @@
 
     /**
      * @return Data registration related info
+     * @hide
      */
     @Nullable
+    @SystemApi @TestApi
     public DataSpecificRegistrationInfo getDataSpecificInfo() {
         return mDataSpecificInfo;
     }
@@ -571,7 +623,11 @@
                 && mNrState == other.mNrState;
     }
 
+    /**
+     * @hide
+     */
     @Override
+    @SystemApi @TestApi
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mDomain);
         dest.writeInt(mTransportType);
@@ -659,7 +715,9 @@
      *     .setRegistrationState(REGISTRATION_STATE_HOME)
      *     .build();
      * </code></pre>
+     * @hide
      */
+    @SystemApi @TestApi
     public static final class Builder {
         @Domain
         private int mDomain;
@@ -759,7 +817,9 @@
          * @param emergencyOnly True if this network registration is for emergency use only.
          *
          * @return The same instance of the builder.
+         * @hide
          */
+        @SystemApi @TestApi
         public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) {
             mEmergencyOnly = emergencyOnly;
             return this;
@@ -771,7 +831,9 @@
          * @param availableServices Available services.
          *
          * @return The same instance of the builder.
+         * @hide
          */
+        @SystemApi @TestApi
         public @NonNull Builder setAvailableServices(
                 @NonNull @ServiceType List<Integer> availableServices) {
             mAvailableServices = availableServices;
@@ -784,7 +846,9 @@
          * @param cellIdentity The cell identity.
          *
          * @return The same instance of the builder.
+         * @hide
          */
+        @SystemApi @TestApi
         public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) {
             mCellIdentity = cellIdentity;
             return this;
@@ -792,9 +856,10 @@
 
         /**
          * Build the NetworkRegistrationInfo.
-         *
          * @return the NetworkRegistrationInfo object.
+         * @hide
          */
+        @SystemApi @TestApi
         public @NonNull NetworkRegistrationInfo build() {
             return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
                     mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 2c8014e..1e64a81 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1855,10 +1855,8 @@
      * Get all of the available network registration info.
      *
      * @return List of {@link NetworkRegistrationInfo}
-     * @hide
      */
     @NonNull
-    @SystemApi
     public List<NetworkRegistrationInfo> getNetworkRegistrationInfoList() {
         synchronized (mNetworkRegistrationInfos) {
             List<NetworkRegistrationInfo> newList = new ArrayList<>();
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 1c58f8f..5a4dac5 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -16,9 +16,8 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
+import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -26,6 +25,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
+import android.os.SystemClock;
+
+import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -77,6 +79,9 @@
     /* The type of signal measurement */
     private static final String MEASUREMENT_TYPE_RSCP = "rscp";
 
+    // timeStamp of signalStrength in nanoseconds since boot
+    private long mTimestamp = Long.MAX_VALUE;
+
     CellSignalStrengthCdma mCdma;
     CellSignalStrengthGsm mGsm;
     CellSignalStrengthWcdma mWcdma;
@@ -134,6 +139,7 @@
         mTdscdma = tdscdma;
         mLte = lte;
         mNr = nr;
+        mTimestamp = SystemClock.elapsedRealtimeNanos();
     }
 
     /**
@@ -268,6 +274,7 @@
         mTdscdma.updateLevel(cc, ss);
         mLte.updateLevel(cc, ss);
         mNr.updateLevel(cc, ss);
+        mTimestamp = SystemClock.elapsedRealtimeNanos();
     }
 
     /**
@@ -293,6 +300,7 @@
         mTdscdma = new CellSignalStrengthTdscdma(s.mTdscdma);
         mLte = new CellSignalStrengthLte(s.mLte);
         mNr = new CellSignalStrengthNr(s.mNr);
+        mTimestamp = s.getTimestampNanos();
     }
 
     /**
@@ -310,6 +318,7 @@
         mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader());
         mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
         mNr = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
+        mTimestamp = in.readLong();
     }
 
     /**
@@ -322,9 +331,18 @@
         out.writeParcelable(mTdscdma, flags);
         out.writeParcelable(mLte, flags);
         out.writeParcelable(mNr, flags);
+        out.writeLong(mTimestamp);
     }
 
     /**
+     * @return mTimestamp in nanoseconds
+     */
+    @SuppressLint("MethodNameUnits")
+    public long getTimestampNanos() {
+        return mTimestamp;
+    }
+
+   /**
      * {@link Parcelable#describeContents}
      */
     public int describeContents() {
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index fee6d3f..2f95a50 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -424,7 +424,26 @@
             String destinationAddress, String scAddress, String text,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                true /* persistMessage*/, null);
+                true /* persistMessage*/, null, 0L /* messageId */);
+    }
+
+
+    /**
+     * Send a text based SMS. Same as {@link #sendTextMessage( String destinationAddress,
+     * String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)}, but
+     * adds an optional messageId.
+     * @param messageId An id that uniquely identifies the message requested to be sent.
+     * Used for logging and diagnostics purposes. The id may be 0.
+     *
+     * @throws IllegalArgumentException if destinationAddress or text are empty
+     *
+     */
+    public void sendTextMessage(
+            @NonNull String destinationAddress, @Nullable String scAddress, @NonNull String text,
+            @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent,
+            long messageId) {
+        sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
+                true /* persistMessage*/, null, messageId);
     }
 
     /**
@@ -542,7 +561,7 @@
 
     private void sendTextMessageInternal(String destinationAddress, String scAddress,
             String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
-            boolean persistMessage, String packageName) {
+            boolean persistMessage, String packageName, long messageId) {
         if (TextUtils.isEmpty(destinationAddress)) {
             throw new IllegalArgumentException("Invalid destinationAddress");
         }
@@ -569,10 +588,10 @@
                     try {
                         iSms.sendTextForSubscriber(subId, packageName,
                                 destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                                persistMessage);
+                                persistMessage, messageId);
                     } catch (RemoteException e) {
                         Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - "
-                                + e.getMessage());
+                                + e.getMessage() + " id: " + messageId);
                         notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
                     }
                 }
@@ -589,10 +608,10 @@
             try {
                 iSms.sendTextForSubscriber(getSubscriptionId(), packageName,
                         destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                        persistMessage);
+                        persistMessage, messageId);
             } catch (RemoteException e) {
                 Log.e(TAG, "sendTextMessageInternal (no persist): Couldn't send SMS, exception - "
-                        + e.getMessage());
+                        + e.getMessage() + " id: " + messageId);
                 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
             }
         }
@@ -634,7 +653,8 @@
             String destinationAddress, String scAddress, String text,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                false /* persistMessage */, null);
+                false /* persistMessage */, null,
+                0L /* messageId */);
     }
 
     private void sendTextMessageInternal(
@@ -921,7 +941,26 @@
             String destinationAddress, String scAddress, ArrayList<String> parts,
             ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, true /* persistMessage*/, null);
+                deliveryIntents, true /* persistMessage*/, null,
+                0L /* messageId */);
+    }
+
+    /**
+     * Send a multi-part text based SMS. Same as #sendMultipartTextMessage(String, String,
+     * ArrayList, ArrayList, ArrayList), but adds an optional messageId.
+     * @param messageId An id that uniquely identifies the message requested to be sent.
+     * Used for logging and diagnostics purposes. The id may be 0.
+     *
+     * @throws IllegalArgumentException if destinationAddress or data are empty
+     *
+     */
+    public void sendMultipartTextMessage(
+            @NonNull String destinationAddress, @Nullable String scAddress,
+            @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
+            @Nullable List<PendingIntent> deliveryIntents, long messageId) {
+        sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
+                deliveryIntents, true /* persistMessage*/, null,
+                messageId);
     }
 
     /**
@@ -946,17 +985,17 @@
     @SystemApi
     @TestApi
     public void sendMultipartTextMessage(
-            @NonNull String destinationAddress, @NonNull String scAddress,
+            @NonNull String destinationAddress, @Nullable String scAddress,
             @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
             @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, true /* persistMessage*/, packageName);
+                deliveryIntents, true /* persistMessage*/, packageName, 0L /* messageId */);
     }
 
     private void sendMultipartTextMessageInternal(
             String destinationAddress, String scAddress, List<String> parts,
             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
-            boolean persistMessage, String packageName) {
+            boolean persistMessage, String packageName, long messageId) {
         if (TextUtils.isEmpty(destinationAddress)) {
             throw new IllegalArgumentException("Invalid destinationAddress");
         }
@@ -983,10 +1022,11 @@
                             ISms iSms = getISmsServiceOrThrow();
                             iSms.sendMultipartTextForSubscriber(subId, packageName,
                                     destinationAddress, scAddress, parts, sentIntents,
-                                    deliveryIntents, persistMessage);
+                                    deliveryIntents, persistMessage, messageId);
                         } catch (RemoteException e) {
                             Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
-                                    + e.getMessage());
+                                    + e.getMessage() + " id: "
+                                    + messageId);
                             notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
                         }
                     }
@@ -1003,11 +1043,11 @@
                     if (iSms != null) {
                         iSms.sendMultipartTextForSubscriber(getSubscriptionId(), packageName,
                                 destinationAddress, scAddress, parts, sentIntents, deliveryIntents,
-                                persistMessage);
+                                persistMessage, messageId);
                     }
                 } catch (RemoteException e) {
                     Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
-                            + e.getMessage());
+                            + e.getMessage() + " id: " + messageId);
                     notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
                 }
             }
@@ -1021,7 +1061,7 @@
                 deliveryIntent = deliveryIntents.get(0);
             }
             sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
-                    sentIntent, deliveryIntent, true, packageName);
+                    sentIntent, deliveryIntent, true, packageName, messageId);
         }
     }
 
@@ -1051,7 +1091,8 @@
             String destinationAddress, String scAddress, List<String> parts,
             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, false /* persistMessage*/, null);
+                deliveryIntents, false /* persistMessage*/, null,
+                0L /* messageId */);
     }
 
     /**
@@ -2545,16 +2586,6 @@
     /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */
     public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS";
 
-    /** Represents the received SMS message for importing {@hide} */
-    public static final int SMS_TYPE_INCOMING = 0;
-    /** Represents the sent SMS message for importing {@hide} */
-    public static final int SMS_TYPE_OUTGOING = 1;
-
-    /** Message status property: whether the message has been seen. 1 means seen, 0 not {@hide} */
-    public static final String MESSAGE_STATUS_SEEN = "seen";
-    /** Message status property: whether the message has been read. 1 means read, 0 not {@hide} */
-    public static final String MESSAGE_STATUS_READ = "read";
-
     /**
      * Get carrier-dependent MMS configuration values.
      *
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c4bcc17..3a66b2c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -9534,15 +9534,20 @@
     }
 
     /**
-     * Requested state of SIM
-     *
-     * CARD_POWER_DOWN
      * Powers down the SIM. SIM must be up prior.
-     *
-     * CARD_POWER_UP
+     * @hide
+     */
+    @SystemApi
+    public static final int CARD_POWER_DOWN = 0;
+
+    /**
      * Powers up the SIM normally. SIM must be down prior.
-     *
-     * CARD_POWER_UP_PASS_THROUGH
+     * @hide
+     */
+    @SystemApi
+    public static final int CARD_POWER_UP = 1;
+
+    /**
      * Powers up the SIM in PASS_THROUGH mode. SIM must be down prior.
      * When SIM is powered up in PASS_THOUGH mode, the modem does not send
      * any command to it (for example SELECT of MF, or TERMINAL CAPABILITY),
@@ -9555,12 +9560,9 @@
      * is activated, and normal behavior occurs at the next SIM initialization,
      * unless PASS_THROUGH mode is requested again. Hence, the last power-up mode
      * is NOT persistent across boots. On reboot, SIM will power up normally.
+     * @hide
      */
-    /** @hide */
-    public static final int CARD_POWER_DOWN = 0;
-    /** @hide */
-    public static final int CARD_POWER_UP = 1;
-    /** @hide */
+    @SystemApi
     public static final int CARD_POWER_UP_PASS_THROUGH = 2;
 
     /**
@@ -10980,9 +10982,15 @@
     }
 
     /**
-     * Checks if FEATURE_TELEPHONY_DATA is enabled.
-     *
-     * @hide
+     * @return true if the current device is "data capable" over a radio on the device.
+     * <p>
+     * "Data capable" means that this device supports packet-switched
+     * data connections over the telephony network.
+     * <p>
+     * Note: the meaning of this flag is subtly different from the
+     * PackageManager.FEATURE_TELEPHONY system feature, which is available
+     * on any device with a telephony radio, even if the device is
+     * voice-only.
      */
     public boolean isDataCapable() {
         if (mContext == null) return true;
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index fab1bf2..6e630e3 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -18,6 +18,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.hardware.radio.V1_5.ApnTypes;
@@ -28,13 +29,14 @@
 import android.provider.Telephony.Carriers;
 import android.telephony.Annotation.ApnType;
 import android.telephony.Annotation.NetworkType;
-import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.net.InetAddress;
@@ -123,6 +125,122 @@
     /** Authentication type for PAP or CHAP. */
     public static final int AUTH_TYPE_PAP_OR_CHAP = 3;
 
+    /**
+     * APN types for data connections.  These are usage categories for an APN
+     * entry.  One APN entry may support multiple APN types, eg, a single APN
+     * may service regular internet traffic ("default") as well as MMS-specific
+     * connections.<br/>
+     * APN_TYPE_ALL is a special type to indicate that this APN entry can
+     * service all data connections.
+     * <p>
+     * Note: The goal is to deprecate this.  Due to the Carrier Table being used
+     * directly, this isn't feasible right now.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_ALL_STRING = "*";
+
+    /**
+     * APN type for default data traffic
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_DEFAULT_STRING = "default";
+
+
+    /**
+     * APN type for MMS traffic
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_MMS_STRING = "mms";
+
+
+    /**
+     * APN type for SUPL assisted GPS
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_SUPL_STRING = "supl";
+
+    /**
+     * APN type for DUN traffic
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_DUN_STRING = "dun";
+
+    /**
+     * APN type for HiPri traffic
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_HIPRI_STRING = "hipri";
+
+    /**
+     * APN type for FOTA
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_FOTA_STRING = "fota";
+
+    /**
+     * APN type for IMS
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_IMS_STRING = "ims";
+
+    /**
+     * APN type for CBS
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_CBS_STRING = "cbs";
+
+    /**
+     * APN type for IA Initial Attach APN
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_IA_STRING = "ia";
+
+    /**
+     * APN type for Emergency PDN. This is not an IA apn, but is used
+     * for access to carrier services in an emergency call situation.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_EMERGENCY_STRING = "emergency";
+
+    /**
+     * APN type for Mission Critical Services
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_MCX_STRING = "mcx";
+
+    /**
+     * APN type for XCAP
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String TYPE_XCAP_STRING = "xcap";
+
+
     /** @hide */
     @IntDef(prefix = { "AUTH_TYPE_" }, value = {
         AUTH_TYPE_NONE,
@@ -1289,10 +1407,13 @@
     }
 
     /**
+     * Converts the integer value of an APN type to the string version.
      * @param apnTypeBitmask bitmask of APN types.
      * @return comma delimited list of APN types.
      * @hide
      */
+    @SystemApi
+    @NonNull
     public static String getApnTypesStringFromBitmask(int apnTypeBitmask) {
         List<String> types = new ArrayList<>();
         for (Integer type : APN_TYPE_INT_MAP.keySet()) {
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index bc60d81..3f260eb 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -40,10 +41,11 @@
 import java.util.List;
 
 /**
- * Parcelable object to handle IMS call profile.
- * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111.
- * It provides the service and call type, the additional information related to the call.
- *
+ * A Parcelable object to handle the IMS call profile, which provides the service, call type, and
+ * additional information related to the call.
+ * <p>
+ * See the following specifications for more information about this class: GSMA IR.92/IR.94,
+ * 3GPP TS 24.229/TS 26.114/TS26.111.
  * @hide
  */
 @SystemApi
@@ -151,12 +153,13 @@
      */
     public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail";
 
-    // Extra string for internal use only. OEMs should not use
-    // this for packing extras.
     /**
+     * Extra key used to store a Bundle containing proprietary extras to send to the ImsService.
+     * Use {@link #getProprietaryCallExtras()} instead.
      * @hide
      */
-    public static final String EXTRA_OEM_EXTRAS = "OemCallExtras";
+    @TestApi
+    public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS";
 
     /**
      * Rule for originating identity (number) presentation, MO/MT.
@@ -687,6 +690,18 @@
         return mCallExtras;
     }
 
+    /**
+     * Get the proprietary extras set for this ImsCallProfile.
+     * @return A {@link Bundle} containing proprietary call extras that were not set by the
+     * platform.
+     */
+    public @Nullable Bundle getProprietaryCallExtras() {
+        if (mCallExtras == null) {
+            return null;
+        }
+        return mCallExtras.getBundle(EXTRA_OEM_EXTRAS);
+    }
+
     public ImsStreamMediaProfile getMediaProfile() {
         return mMediaProfile;
     }
diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
index 893a311..3e2903f 100644
--- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java
+++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
@@ -83,8 +83,23 @@
     public static final int CAPABILITY_RCS_VOICE_CALL = (1 << 19);
     /** Supports RCS video calling */
     public static final int CAPABILITY_RCS_VIDEO_CALL = (1 << 20);
-    /** Supports RCS video calling, where video media can not be dropped */
+    /** Supports RCS video calling, where video media can not be dropped. */
     public static final int CAPABILITY_RCS_VIDEO_ONLY_CALL = (1 << 21);
+    /** Supports call composer, where outgoing calls can be enriched with pre-call content.*/
+    public static final int CAPABILITY_CALL_COMPOSER = (1 << 22);
+    /** Supports post call information that is included in the call if the call is missed.*/
+    public static final int CAPABILITY_POST_CALL = (1 << 23);
+    /** Supports sharing a map where the user can draw, share markers, and share their position. */
+    public static final int CAPABILITY_SHARED_MAP = (1 << 24);
+    /** Supports sharing a canvas, where users can draw, add images, and change background colors.*/
+    public static final int CAPABILITY_SHARED_SKETCH = (1 << 25);
+    /** Supports communication with Chatbots. */
+    public static final int CAPABILITY_CHAT_BOT = (1 << 26);
+    /** Supports Chatbot roles. */
+    public static final int CAPABILITY_CHAT_BOT_ROLE = (1 << 27);
+    /** Supports the unidirectional plug-ins framework. */
+    public static final int CAPABILITY_PLUG_IN = (1 << 28);
+
 
     /** @hide*/
     @Retention(RetentionPolicy.SOURCE)
@@ -110,7 +125,14 @@
             CAPABILITY_GEOLOCATION_PULL_FILE_TRANSFER,
             CAPABILITY_RCS_VOICE_CALL,
             CAPABILITY_RCS_VIDEO_CALL,
-            CAPABILITY_RCS_VIDEO_ONLY_CALL
+            CAPABILITY_RCS_VIDEO_ONLY_CALL,
+            CAPABILITY_CALL_COMPOSER,
+            CAPABILITY_POST_CALL,
+            CAPABILITY_SHARED_MAP,
+            CAPABILITY_SHARED_SKETCH,
+            CAPABILITY_CHAT_BOT,
+            CAPABILITY_CHAT_BOT_ROLE,
+            CAPABILITY_PLUG_IN
     })
     public @interface CapabilityFlag {}
 
@@ -183,7 +205,7 @@
     }
 
     private final Uri mContactUri;
-    private int mCapabilities;
+    private long mCapabilities;
     private List<String> mExtensionTags = new ArrayList<>();
     private Map<Integer, Uri> mServiceMap = new HashMap<>();
 
@@ -198,7 +220,7 @@
 
     private RcsContactUceCapability(Parcel in) {
         mContactUri = in.readParcelable(Uri.class.getClassLoader());
-        mCapabilities = in.readInt();
+        mCapabilities = in.readLong();
         in.readStringList(mExtensionTags);
         // read mServiceMap as key,value pair
         int mapSize = in.readInt();
@@ -223,7 +245,7 @@
     @Override
     public void writeToParcel(@NonNull Parcel out, int flags) {
         out.writeParcelable(mContactUri, 0);
-        out.writeInt(mCapabilities);
+        out.writeLong(mCapabilities);
         out.writeStringList(mExtensionTags);
         // write mServiceMap as key,value pairs
         int mapSize = mServiceMap.keySet().size();
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 4cb8575..1004e1b 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -337,11 +337,10 @@
     }
 
     /**
-     * @return The current state of the feature, defined as {@link #STATE_UNAVAILABLE},
-     * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}.
-     * @hide
+     * @return The current state of the ImsFeature, set previously by {@link #setFeatureState(int)}
+     * or {@link #STATE_UNAVAILABLE} if it has not been updated  yet.
      */
-    public int getFeatureState() {
+    public @ImsState int getFeatureState() {
         synchronized (mLock) {
             return mState;
         }
diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
index feac3c2..3ec4f34 100644
--- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
@@ -16,6 +16,7 @@
 
 package android.telephony.ims.stub;
 
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.os.Bundle;
@@ -25,6 +26,9 @@
 import com.android.ims.internal.IImsUt;
 import com.android.ims.internal.IImsUtListener;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Base implementation of IMS UT interface, which implements stubs. Override these methods to
  * implement functionality.
@@ -36,6 +40,70 @@
 @SystemApi
 @TestApi
 public class ImsUtImplBase {
+    /**
+     * Bar all incoming calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_ALL_INCOMING = 1;
+
+    /**
+     * Bar all outgoing calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_ALL_OUTGOING = 2;
+
+    /**
+     * Bar all outgoing international calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_OUTGOING_INTL = 3;
+
+    /**
+     * Bar all outgoing international calls, excluding those to the home PLMN country
+     * (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4;
+
+    /**
+     * Bar all incoming calls when roaming (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5;
+
+    /**
+     * Enable Anonymous Communication Rejection (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6;
+
+    /**
+     * Bar all incoming and outgoing calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_ALL = 7;
+
+    /**
+     * Bar all outgoing service requests, including calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8;
+
+    /**
+     * Bar all incoming service requests, including calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9;
+
+    /**
+     * Bar specific incoming calls. (See 3GPP TS 24.611)
+     */
+    public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "CALL_BARRING_", value = {CALL_BARRING_ALL_INCOMING, CALL_BARRING_ALL_OUTGOING,
+            CALL_BARRING_OUTGOING_INTL, CALL_BARRING_OUTGOING_INTL_EXCL_HOME,
+            CALL_BLOCKING_INCOMING_WHEN_ROAMING, CALL_BARRING_ANONYMOUS_INCOMING,
+            CALL_BARRING_ALL, CALL_BARRING_OUTGOING_ALL_SERVICES,
+            CALL_BARRING_INCOMING_ALL_SERVICES, CALL_BARRING_SPECIFIC_INCOMING_CALLS})
+    public @interface CallBarringMode {}
+
+    /**
+     * Constant used to denote an invalid return value.
+     */
+    public static final int INVALID_RESULT = -1;
 
     private IImsUt.Stub mServiceImpl = new IImsUt.Stub() {
         @Override
@@ -247,15 +315,15 @@
     /**
      * Updates the configuration of the call barring.
      */
-    public int updateCallBarring(int cbType, int action, String[] barrList) {
+    public int updateCallBarring(@CallBarringMode int cbType, int action, String[] barrList) {
         return -1;
     }
 
     /**
      * Updates the configuration of the call barring for specified service class.
      */
-    public int updateCallBarringForServiceClass(int cbType, int action, String[] barrList,
-            int serviceClass) {
+    public int updateCallBarringForServiceClass(@CallBarringMode int cbType, int action,
+            String[] barrList, int serviceClass) {
         return -1;
     }
 
diff --git a/telephony/java/com/android/ims/ImsUtInterface.java b/telephony/java/com/android/ims/ImsUtInterface.java
index 50b63bd..15f8371 100644
--- a/telephony/java/com/android/ims/ImsUtInterface.java
+++ b/telephony/java/com/android/ims/ImsUtInterface.java
@@ -21,6 +21,7 @@
 import android.os.Message;
 import android.telephony.ims.ImsCallForwardInfo;
 import android.telephony.ims.ImsSsInfo;
+import android.telephony.ims.stub.ImsUtImplBase;
 
 /**
  * Provides APIs for the supplementary service settings using IMS (Ut interface).
@@ -58,47 +59,48 @@
      * CDIV (Communication Diversion, 3GPP TS 24.604)
      *     actions: target, no reply timer
      */
-    public static final int CDIV_CF_UNCONDITIONAL = 0;
-    public static final int CDIV_CF_BUSY = 1;
-    public static final int CDIV_CF_NO_REPLY = 2;
-    public static final int CDIV_CF_NOT_REACHABLE = 3;
+    public static final int CDIV_CF_UNCONDITIONAL = ImsCallForwardInfo.CDIV_CF_REASON_UNCONDITIONAL;
+    public static final int CDIV_CF_BUSY = ImsCallForwardInfo.CDIV_CF_REASON_BUSY;
+    public static final int CDIV_CF_NO_REPLY = ImsCallForwardInfo.CDIV_CF_REASON_NO_REPLY;
+    public static final int CDIV_CF_NOT_REACHABLE = ImsCallForwardInfo.CDIV_CF_REASON_NOT_REACHABLE;
     // For CS service code: 002
-    public static final int CDIV_CF_ALL = 4;
+    public static final int CDIV_CF_ALL = ImsCallForwardInfo.CDIV_CF_REASON_ALL;
     // For CS service code: 004
-    public static final int CDIV_CF_ALL_CONDITIONAL = 5;
+    public static final int CDIV_CF_ALL_CONDITIONAL =
+            ImsCallForwardInfo.CDIV_CF_REASON_ALL_CONDITIONAL;
     // It's only supported in the IMS service (CS does not define it).
     // IR.92 recommends that an UE activates both the CFNRc and the CFNL
     // (CDIV using condition not-registered) to the same target.
-    public static final int CDIV_CF_NOT_LOGGED_IN = 6;
+    public static final int CDIV_CF_NOT_LOGGED_IN = ImsCallForwardInfo.CDIV_CF_REASON_NOT_LOGGED_IN;
 
     /**
      * CB (Communication Barring, 3GPP TS 24.611)
      */
     // Barring of All Incoming Calls
-    public static final int CB_BAIC = 1;
+    public static final int CB_BAIC = ImsUtImplBase.CALL_BARRING_ALL_INCOMING;
     // Barring of All Outgoing Calls
-    public static final int CB_BAOC = 2;
+    public static final int CB_BAOC = ImsUtImplBase.CALL_BARRING_ALL_OUTGOING;
     // Barring of Outgoing International Calls
-    public static final int CB_BOIC = 3;
+    public static final int CB_BOIC = ImsUtImplBase.CALL_BARRING_OUTGOING_INTL;
     // Barring of Outgoing International Calls - excluding Home Country
-    public static final int CB_BOIC_EXHC = 4;
+    public static final int CB_BOIC_EXHC = ImsUtImplBase.CALL_BARRING_OUTGOING_INTL_EXCL_HOME;
     // Barring of Incoming Calls - when roaming
-    public static final int CB_BIC_WR = 5;
+    public static final int CB_BIC_WR = ImsUtImplBase.CALL_BLOCKING_INCOMING_WHEN_ROAMING;
     // Barring of Anonymous Communication Rejection (ACR) - a particular case of ICB service
-    public static final int CB_BIC_ACR = 6;
+    public static final int CB_BIC_ACR = ImsUtImplBase.CALL_BARRING_ANONYMOUS_INCOMING;
     // Barring of All Calls
-    public static final int CB_BA_ALL = 7;
+    public static final int CB_BA_ALL = ImsUtImplBase.CALL_BARRING_ALL;
     // Barring of Outgoing Services (Service Code 333 - 3GPP TS 22.030 Table B-1)
-    public static final int CB_BA_MO = 8;
+    public static final int CB_BA_MO = ImsUtImplBase.CALL_BARRING_OUTGOING_ALL_SERVICES;
     // Barring of Incoming Services (Service Code 353 - 3GPP TS 22.030 Table B-1)
-    public static final int CB_BA_MT = 9;
+    public static final int CB_BA_MT = ImsUtImplBase.CALL_BARRING_INCOMING_ALL_SERVICES;
     // Barring of Specific Incoming calls
-    public static final int CB_BS_MT = 10;
+    public static final int CB_BS_MT = ImsUtImplBase.CALL_BARRING_SPECIFIC_INCOMING_CALLS;
 
     /**
      * Invalid result value.
      */
-    public static final int INVALID = (-1);
+    public static final int INVALID = ImsUtImplBase.INVALID_RESULT;
 
 
 
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index c07a171..79cdce8 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -145,10 +145,13 @@
      *   be automatically persisted in the SMS db. It only affects messages sent
      *   by a non-default SMS app. Currently only the carrier app can set this
      *   parameter to false to skip auto message persistence.
+     * @param messageId An id that uniquely identifies the message requested to be sent.
+     *   Used for logging and diagnostics purposes. The id may be 0.
      */
     void sendTextForSubscriber(in int subId, String callingPkg, in String destAddr,
             in String scAddr, in String text, in PendingIntent sentIntent,
-            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp);
+            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp,
+            in long messageId);
 
     /**
      * Send an SMS. Internal use only.
@@ -270,11 +273,14 @@
      *   be automatically persisted in the SMS db. It only affects messages sent
      *   by a non-default SMS app. Currently only the carrier app can set this
      *   parameter to false to skip auto message persistence.
+     * @param messageId An id that uniquely identifies the message requested to be sent.
+     *   Used for logging and diagnostics purposes. The id may be 0.
      */
     void sendMultipartTextForSubscriber(in int subId, String callingPkg,
             in String destinationAddress, in String scAddress,
             in List<String> parts, in List<PendingIntent> sentIntents,
-            in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp);
+            in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp,
+            in long messageId);
 
     /**
      * Send a multi-part text based SMS with options using Subscription Id.
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index ddd3457..db0b8e5 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -61,7 +61,8 @@
     @Override
     public void sendTextForSubscriber(int subId, String callingPkg, String destAddr,
             String scAddr, String text, PendingIntent sentIntent,
-            PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp) {
+            PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp,
+            long messageId) {
         throw new UnsupportedOperationException();
     }
 
@@ -90,7 +91,8 @@
     public void sendMultipartTextForSubscriber(int subId, String callingPkg,
             String destinationAddress, String scAddress,
             List<String> parts, List<PendingIntent> sentIntents,
-            List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp) {
+            List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp,
+            long messageId) {
         throw new UnsupportedOperationException();
     }
 
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index db8c845..4d67754 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -16,6 +16,7 @@
 package com.android.internal.telephony;
 
 import android.compat.annotation.UnsupportedAppUsage;
+import android.telephony.data.ApnSetting;
 
 /**
  * @hide
@@ -125,32 +126,32 @@
      * APN_TYPE_ALL is a special type to indicate that this APN entry can
      * service all data connections.
      */
-    public static final String APN_TYPE_ALL = "*";
+    public static final String APN_TYPE_ALL = ApnSetting.TYPE_ALL_STRING;
     /** APN type for default data traffic */
-    public static final String APN_TYPE_DEFAULT = "default";
+    public static final String APN_TYPE_DEFAULT = ApnSetting.TYPE_DEFAULT_STRING;
     /** APN type for MMS traffic */
-    public static final String APN_TYPE_MMS = "mms";
+    public static final String APN_TYPE_MMS = ApnSetting.TYPE_MMS_STRING;
     /** APN type for SUPL assisted GPS */
-    public static final String APN_TYPE_SUPL = "supl";
+    public static final String APN_TYPE_SUPL = ApnSetting.TYPE_SUPL_STRING;
     /** APN type for DUN traffic */
-    public static final String APN_TYPE_DUN = "dun";
+    public static final String APN_TYPE_DUN = ApnSetting.TYPE_DUN_STRING;
     /** APN type for HiPri traffic */
-    public static final String APN_TYPE_HIPRI = "hipri";
+    public static final String APN_TYPE_HIPRI = ApnSetting.TYPE_HIPRI_STRING;
     /** APN type for FOTA */
-    public static final String APN_TYPE_FOTA = "fota";
+    public static final String APN_TYPE_FOTA = ApnSetting.TYPE_FOTA_STRING;
     /** APN type for IMS */
-    public static final String APN_TYPE_IMS = "ims";
+    public static final String APN_TYPE_IMS = ApnSetting.TYPE_IMS_STRING;
     /** APN type for CBS */
-    public static final String APN_TYPE_CBS = "cbs";
+    public static final String APN_TYPE_CBS = ApnSetting.TYPE_CBS_STRING;
     /** APN type for IA Initial Attach APN */
-    public static final String APN_TYPE_IA = "ia";
+    public static final String APN_TYPE_IA = ApnSetting.TYPE_IA_STRING;
     /** APN type for Emergency PDN. This is not an IA apn, but is used
      * for access to carrier services in an emergency call situation. */
-    public static final String APN_TYPE_EMERGENCY = "emergency";
+    public static final String APN_TYPE_EMERGENCY = ApnSetting.TYPE_EMERGENCY_STRING;
     /** APN type for Mission Critical Services */
-    public static final String APN_TYPE_MCX = "mcx";
+    public static final String APN_TYPE_MCX = ApnSetting.TYPE_MCX_STRING;
     /** APN type for XCAP */
-    public static final String APN_TYPE_XCAP = "xcap";
+    public static final String APN_TYPE_XCAP = ApnSetting.TYPE_XCAP_STRING;
     /** Array of all APN types */
     public static final String[] APN_TYPES = {APN_TYPE_DEFAULT,
             APN_TYPE_MMS,
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 4c9ee85..5ef892d 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -114,6 +114,8 @@
         ":framework-annotations",
         ":framework-wifi-updatable-sources",
     ],
+    // This is needed as IOnWifiActivityEnergyInfoListener.aidl in framework-wifi depends on
+    // WifiActivityEnergyInfo.aidl in framework-minus-apex
     aidl: {
         include_dirs: ["frameworks/base/core/java"],
     },
@@ -125,11 +127,6 @@
 java_library {
     name: "framework-wifi-stubs",
     srcs: [":framework-wifi-stubs-srcs"],
-    aidl: {
-        export_include_dirs: [
-            "java",
-        ],
-    },
     sdk_version: "core_current",
     libs: ["android_system_stubs_current"],
     installable: false,