Merge "Revert "Introduce listUIChanges API for developer UI"" into rvc-dev
diff --git a/Android.bp b/Android.bp
index da5d624..48d9559 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1299,6 +1299,13 @@
         "framework-annotations-lib",
         "android.hardware.radio-V1.5-java",
     ],
+    check_api: {
+        current: {
+            // TODO(b/147699819): remove telephony prefix when moved
+            api_file: "telephony/api/system-current.txt",
+            removed_api_file: "telephony/api/system-removed.txt",
+        },
+    },
     defaults: ["framework-module-stubs-defaults-systemapi"],
     filter_packages: ["android.telephony"],
     sdk_version: "system_current",
diff --git a/apex/Android.bp b/apex/Android.bp
index 39137fb..1943940 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -44,6 +44,12 @@
     args: mainline_stubs_args,
     installable: false,
     sdk_version: "current",
+    check_api: {
+        current: {
+            api_file: "api/current.txt",
+            removed_api_file: "api/removed.txt",
+        },
+    },
 }
 
 stubs_defaults {
@@ -52,6 +58,12 @@
     libs: ["framework-annotations-lib"],
     installable: false,
     sdk_version: "system_current",
+    check_api: {
+        current: {
+            api_file: "api/system-current.txt",
+            removed_api_file: "api/system-removed.txt",
+        },
+    },
 }
 
 // The defaults for module_libs comes in two parts - defaults for API checks
@@ -65,6 +77,12 @@
     libs: ["framework-annotations-lib"],
     installable: false,
     sdk_version: "module_current",
+    check_api: {
+        current: {
+            api_file: "api/module-lib-current.txt",
+            removed_api_file: "api/module-lib-removed.txt",
+        },
+    },
 }
 
 stubs_defaults {
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index ae8976a..9f98f8e 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -55,6 +55,10 @@
  * using the {@link JobInfo.Builder}.
  * The goal here is to provide the scheduler with high-level semantics about the work you want to
  * accomplish.
+ * <p> Prior to Android version {@link Build.VERSION_CODES#Q}, you had to specify at least one
+ * constraint on the JobInfo object that you are creating. Otherwise, the builder would throw an
+ * exception when building. From Android version {@link Build.VERSION_CODES#Q} and onwards, it is
+ * valid to schedule jobs with no constraints.
  */
 public class JobInfo implements Parcelable {
     private static String TAG = "JobInfo";
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 819f253..07a9908 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -746,7 +746,13 @@
     final Constants mConstants;
     final ConstantsObserver mConstantsObserver;
 
-    static final Comparator<JobStatus> mEnqueueTimeComparator = (o1, o2) -> {
+    private static final Comparator<JobStatus> sPendingJobComparator = (o1, o2) -> {
+        // Jobs with an override state set (via adb) should be put first as tests/developers
+        // expect the jobs to run immediately.
+        if (o1.overrideState != o2.overrideState) {
+            // Higher override state (OVERRIDE_FULL) should be before lower state (OVERRIDE_SOFT)
+            return o2.overrideState - o1.overrideState;
+        }
         if (o1.enqueueTime < o2.enqueueTime) {
             return -1;
         }
@@ -1097,7 +1103,7 @@
                 // This is a new job, we can just immediately put it on the pending
                 // list and try to run it.
                 mJobPackageTracker.notePending(jobStatus);
-                addOrderedItem(mPendingJobs, jobStatus, mEnqueueTimeComparator);
+                addOrderedItem(mPendingJobs, jobStatus, sPendingJobComparator);
                 maybeRunPendingJobsLocked();
             } else {
                 evaluateControllerStatesLocked(jobStatus);
@@ -1858,7 +1864,7 @@
                         // state is such that all ready jobs should be run immediately.
                         if (runNow != null && isReadyToBeExecutedLocked(runNow)) {
                             mJobPackageTracker.notePending(runNow);
-                            addOrderedItem(mPendingJobs, runNow, mEnqueueTimeComparator);
+                            addOrderedItem(mPendingJobs, runNow, sPendingJobComparator);
                         } else {
                             queueReadyJobsForExecutionLocked();
                         }
@@ -2030,7 +2036,7 @@
             noteJobsPending(newReadyJobs);
             mPendingJobs.addAll(newReadyJobs);
             if (mPendingJobs.size() > 1) {
-                mPendingJobs.sort(mEnqueueTimeComparator);
+                mPendingJobs.sort(sPendingJobComparator);
             }
 
             newReadyJobs.clear();
@@ -2107,7 +2113,7 @@
                 noteJobsPending(runnableJobs);
                 mPendingJobs.addAll(runnableJobs);
                 if (mPendingJobs.size() > 1) {
-                    mPendingJobs.sort(mEnqueueTimeComparator);
+                    mPendingJobs.sort(sPendingJobComparator);
                 }
             } else {
                 if (DEBUG) {
@@ -2813,11 +2819,9 @@
     }
 
     // Shell command infrastructure: run the given job immediately
-    int executeRunCommand(String pkgName, int userId, int jobId, boolean force) {
-        if (DEBUG) {
-            Slog.v(TAG, "executeRunCommand(): " + pkgName + "/" + userId
-                    + " " + jobId + " f=" + force);
-        }
+    int executeRunCommand(String pkgName, int userId, int jobId, boolean satisfied, boolean force) {
+        Slog.d(TAG, "executeRunCommand(): " + pkgName + "/" + userId
+                + " " + jobId + " s=" + satisfied + " f=" + force);
 
         try {
             final int uid = AppGlobals.getPackageManager().getPackageUid(pkgName, 0,
@@ -2832,7 +2836,8 @@
                     return JobSchedulerShellCommand.CMD_ERR_NO_JOB;
                 }
 
-                js.overrideState = (force) ? JobStatus.OVERRIDE_FULL : JobStatus.OVERRIDE_SOFT;
+                js.overrideState = (force) ? JobStatus.OVERRIDE_FULL
+                        : (satisfied ? JobStatus.OVERRIDE_SORTING : JobStatus.OVERRIDE_SOFT);
 
                 // Re-evaluate constraints after the override is set in case one of the overridden
                 // constraints was preventing another constraint from thinking it needed to update.
@@ -2841,7 +2846,7 @@
                 }
 
                 if (!js.isConstraintsSatisfied()) {
-                    js.overrideState = 0;
+                    js.overrideState = JobStatus.OVERRIDE_NONE;
                     return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS;
                 }
 
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
index 9571708..1e72062 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
@@ -136,6 +136,7 @@
         checkPermission("force scheduled jobs");
 
         boolean force = false;
+        boolean satisfied = false;
         int userId = UserHandle.USER_SYSTEM;
 
         String opt;
@@ -146,6 +147,11 @@
                     force = true;
                     break;
 
+                case "-s":
+                case "--satisfied":
+                    satisfied = true;
+                    break;
+
                 case "-u":
                 case "--user":
                     userId = Integer.parseInt(getNextArgRequired());
@@ -157,12 +163,17 @@
             }
         }
 
+        if (force && satisfied) {
+            pw.println("Cannot specify both --force and --satisfied");
+            return -1;
+        }
+
         final String pkgName = getNextArgRequired();
         final int jobId = Integer.parseInt(getNextArgRequired());
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            int ret = mInternal.executeRunCommand(pkgName, userId, jobId, force);
+            int ret = mInternal.executeRunCommand(pkgName, userId, jobId, satisfied, force);
             if (printError(ret, pkgName, userId, jobId)) {
                 return ret;
             }
@@ -424,11 +435,18 @@
         pw.println("Job scheduler (jobscheduler) commands:");
         pw.println("  help");
         pw.println("    Print this help text.");
-        pw.println("  run [-f | --force] [-u | --user USER_ID] PACKAGE JOB_ID");
-        pw.println("    Trigger immediate execution of a specific scheduled job.");
+        pw.println("  run [-f | --force] [-s | --satisfied] [-u | --user USER_ID] PACKAGE JOB_ID");
+        pw.println("    Trigger immediate execution of a specific scheduled job. For historical");
+        pw.println("    reasons, some constraints, such as battery, are ignored when this");
+        pw.println("    command is called. If you don't want any constraints to be ignored,");
+        pw.println("    include the -s flag.");
         pw.println("    Options:");
         pw.println("      -f or --force: run the job even if technical constraints such as");
-        pw.println("         connectivity are not currently met");
+        pw.println("         connectivity are not currently met. This is incompatible with -f ");
+        pw.println("         and so an error will be reported if both are given.");
+        pw.println("      -s or --satisfied: run the job only if all constraints are met.");
+        pw.println("         This is incompatible with -f and so an error will be reported");
+        pw.println("         if both are given.");
         pw.println("      -u or --user: specify which user's job is to be run; the default is");
         pw.println("         the primary or system user");
         pw.println("  timeout [-u | --user USER_ID] [PACKAGE] [JOB_ID]");
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index 81dbc87..d7c6ddb 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -131,10 +131,14 @@
     // TODO(b/129954980)
     private static final boolean STATS_LOG_ENABLED = false;
 
+    // No override.
+    public static final int OVERRIDE_NONE = 0;
+    // Override to improve sorting order. Does not affect constraint evaluation.
+    public static final int OVERRIDE_SORTING = 1;
     // Soft override: ignore constraints like time that don't affect API availability
-    public static final int OVERRIDE_SOFT = 1;
+    public static final int OVERRIDE_SOFT = 2;
     // Full override: ignore all constraints including API-affecting like connectivity
-    public static final int OVERRIDE_FULL = 2;
+    public static final int OVERRIDE_FULL = 3;
 
     /** If not specified, trigger update delay is 10 seconds. */
     public static final long DEFAULT_TRIGGER_UPDATE_DELAY = 10*1000;
@@ -304,7 +308,7 @@
     public int nextPendingWorkId = 1;
 
     // Used by shell commands
-    public int overrideState = 0;
+    public int overrideState = JobStatus.OVERRIDE_NONE;
 
     // When this job was enqueued, for ordering.  (in elapsedRealtimeMillis)
     public long enqueueTime;
diff --git a/apex/media/OWNERS b/apex/media/OWNERS
index 0ac750c..9b853c5 100644
--- a/apex/media/OWNERS
+++ b/apex/media/OWNERS
@@ -1,4 +1,4 @@
 andrewlewis@google.com
-dwkang@google.com
+aquilescanta@google.com
 marcone@google.com
 sungsoo@google.com
diff --git a/apex/media/framework/api/current.txt b/apex/media/framework/api/current.txt
new file mode 100644
index 0000000..2b7dcd33
--- /dev/null
+++ b/apex/media/framework/api/current.txt
@@ -0,0 +1,206 @@
+// Signature format: 2.0
+package android.media {
+
+  public class MediaController2 implements java.lang.AutoCloseable {
+    method public void cancelSessionCommand(@NonNull Object);
+    method public void close();
+    method @Nullable public android.media.Session2Token getConnectedToken();
+    method public boolean isPlaybackActive();
+    method @NonNull public Object sendSessionCommand(@NonNull android.media.Session2Command, @Nullable android.os.Bundle);
+  }
+
+  public static final class MediaController2.Builder {
+    ctor public MediaController2.Builder(@NonNull android.content.Context, @NonNull android.media.Session2Token);
+    method @NonNull public android.media.MediaController2 build();
+    method @NonNull public android.media.MediaController2.Builder setConnectionHints(@NonNull android.os.Bundle);
+    method @NonNull public android.media.MediaController2.Builder setControllerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaController2.ControllerCallback);
+  }
+
+  public abstract static class MediaController2.ControllerCallback {
+    ctor public MediaController2.ControllerCallback();
+    method public void onCommandResult(@NonNull android.media.MediaController2, @NonNull Object, @NonNull android.media.Session2Command, @NonNull android.media.Session2Command.Result);
+    method public void onConnected(@NonNull android.media.MediaController2, @NonNull android.media.Session2CommandGroup);
+    method public void onDisconnected(@NonNull android.media.MediaController2);
+    method public void onPlaybackActiveChanged(@NonNull android.media.MediaController2, boolean);
+    method @Nullable public android.media.Session2Command.Result onSessionCommand(@NonNull android.media.MediaController2, @NonNull android.media.Session2Command, @Nullable android.os.Bundle);
+  }
+
+  public final class MediaParser {
+    method public boolean advance(@NonNull android.media.MediaParser.SeekableInputReader) throws java.io.IOException;
+    method @NonNull public static android.media.MediaParser create(@NonNull android.media.MediaParser.OutputConsumer, @NonNull java.lang.String...);
+    method @NonNull public static android.media.MediaParser createByName(@NonNull String, @NonNull android.media.MediaParser.OutputConsumer);
+    method @Nullable public String getParserName();
+    method @NonNull public static java.util.List<java.lang.String> getParserNames(@NonNull android.media.MediaFormat);
+    method public void release();
+    method public void seek(@NonNull android.media.MediaParser.SeekPoint);
+    method @NonNull public android.media.MediaParser setParameter(@NonNull String, @NonNull Object);
+    method public boolean supportsParameter(@NonNull String);
+    field public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING = "android.media.mediaparser.adts.enableCbrSeeking";
+    field public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING = "android.media.mediaparser.amr.enableCbrSeeking";
+    field public static final String PARAMETER_FLAC_DISABLE_ID3 = "android.media.mediaparser.flac.disableId3";
+    field public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING = "android.media.mediaparser.matroska.disableCuesSeeking";
+    field public static final String PARAMETER_MP3_DISABLE_ID3 = "android.media.mediaparser.mp3.disableId3";
+    field public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING = "android.media.mediaparser.mp3.enableCbrSeeking";
+    field public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING = "android.media.mediaparser.mp3.enableIndexSeeking";
+    field public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS = "android.media.mediaparser.mp4.ignoreEditLists";
+    field public static final String PARAMETER_MP4_IGNORE_TFDT_BOX = "android.media.mediaparser.mp4.ignoreTfdtBox";
+    field public static final String PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES = "android.media.mediaparser.mp4.treatVideoFramesAsKeyframes";
+    field public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES = "android.media.mediaparser.ts.allowNonIdrAvcKeyframes";
+    field public static final String PARAMETER_TS_DETECT_ACCESS_UNITS = "android.media.mediaparser.ts.ignoreDetectAccessUnits";
+    field public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS = "android.media.mediaparser.ts.enableHdmvDtsAudioStreams";
+    field public static final String PARAMETER_TS_IGNORE_AAC_STREAM = "android.media.mediaparser.ts.ignoreAacStream";
+    field public static final String PARAMETER_TS_IGNORE_AVC_STREAM = "android.media.mediaparser.ts.ignoreAvcStream";
+    field public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM = "android.media.mediaparser.ts.ignoreSpliceInfoStream";
+    field public static final String PARAMETER_TS_MODE = "android.media.mediaparser.ts.mode";
+  }
+
+  public static interface MediaParser.InputReader {
+    method public long getLength();
+    method public long getPosition();
+    method public int read(@NonNull byte[], int, int) throws java.io.IOException;
+  }
+
+  public static interface MediaParser.OutputConsumer {
+    method public void onSampleCompleted(int, long, int, int, int, @Nullable android.media.MediaCodec.CryptoInfo);
+    method public void onSampleDataFound(int, @NonNull android.media.MediaParser.InputReader) throws java.io.IOException;
+    method public void onSeekMapFound(@NonNull android.media.MediaParser.SeekMap);
+    method public void onTrackCountFound(int);
+    method public void onTrackDataFound(int, @NonNull android.media.MediaParser.TrackData);
+  }
+
+  public static final class MediaParser.ParsingException extends java.io.IOException {
+  }
+
+  public static final class MediaParser.SeekMap {
+    method public long getDurationMicros();
+    method @NonNull public android.util.Pair<android.media.MediaParser.SeekPoint,android.media.MediaParser.SeekPoint> getSeekPoints(long);
+    method public boolean isSeekable();
+    field public static final int UNKNOWN_DURATION = -2147483648; // 0x80000000
+  }
+
+  public static final class MediaParser.SeekPoint {
+    field @NonNull public static final android.media.MediaParser.SeekPoint START;
+    field public final long position;
+    field public final long timeMicros;
+  }
+
+  public static interface MediaParser.SeekableInputReader extends android.media.MediaParser.InputReader {
+    method public void seekToPosition(long);
+  }
+
+  public static final class MediaParser.TrackData {
+    field @Nullable public final android.media.DrmInitData drmInitData;
+    field @NonNull public final android.media.MediaFormat mediaFormat;
+  }
+
+  public static final class MediaParser.UnrecognizedInputFormatException extends java.io.IOException {
+  }
+
+  public class MediaSession2 implements java.lang.AutoCloseable {
+    method public void broadcastSessionCommand(@NonNull android.media.Session2Command, @Nullable android.os.Bundle);
+    method public void cancelSessionCommand(@NonNull android.media.MediaSession2.ControllerInfo, @NonNull Object);
+    method public void close();
+    method @NonNull public java.util.List<android.media.MediaSession2.ControllerInfo> getConnectedControllers();
+    method @NonNull public String getId();
+    method @NonNull public android.media.Session2Token getToken();
+    method public boolean isPlaybackActive();
+    method @NonNull public Object sendSessionCommand(@NonNull android.media.MediaSession2.ControllerInfo, @NonNull android.media.Session2Command, @Nullable android.os.Bundle);
+    method public void setPlaybackActive(boolean);
+  }
+
+  public static final class MediaSession2.Builder {
+    ctor public MediaSession2.Builder(@NonNull android.content.Context);
+    method @NonNull public android.media.MediaSession2 build();
+    method @NonNull public android.media.MediaSession2.Builder setExtras(@NonNull android.os.Bundle);
+    method @NonNull public android.media.MediaSession2.Builder setId(@NonNull String);
+    method @NonNull public android.media.MediaSession2.Builder setSessionActivity(@Nullable android.app.PendingIntent);
+    method @NonNull public android.media.MediaSession2.Builder setSessionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaSession2.SessionCallback);
+  }
+
+  public static final class MediaSession2.ControllerInfo {
+    method @NonNull public android.os.Bundle getConnectionHints();
+    method @NonNull public String getPackageName();
+    method @NonNull public android.media.session.MediaSessionManager.RemoteUserInfo getRemoteUserInfo();
+    method public int getUid();
+  }
+
+  public abstract static class MediaSession2.SessionCallback {
+    ctor public MediaSession2.SessionCallback();
+    method public void onCommandResult(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo, @NonNull Object, @NonNull android.media.Session2Command, @NonNull android.media.Session2Command.Result);
+    method @Nullable public android.media.Session2CommandGroup onConnect(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo);
+    method public void onDisconnected(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo);
+    method public void onPostConnect(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo);
+    method @Nullable public android.media.Session2Command.Result onSessionCommand(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo, @NonNull android.media.Session2Command, @Nullable android.os.Bundle);
+  }
+
+  public abstract class MediaSession2Service extends android.app.Service {
+    ctor public MediaSession2Service();
+    method public final void addSession(@NonNull android.media.MediaSession2);
+    method @NonNull public final java.util.List<android.media.MediaSession2> getSessions();
+    method @CallSuper @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
+    method @Nullable public abstract android.media.MediaSession2 onGetSession(@NonNull android.media.MediaSession2.ControllerInfo);
+    method @Nullable public abstract android.media.MediaSession2Service.MediaNotification onUpdateNotification(@NonNull android.media.MediaSession2);
+    method public final void removeSession(@NonNull android.media.MediaSession2);
+    field public static final String SERVICE_INTERFACE = "android.media.MediaSession2Service";
+  }
+
+  public static class MediaSession2Service.MediaNotification {
+    ctor public MediaSession2Service.MediaNotification(int, @NonNull android.app.Notification);
+    method @NonNull public android.app.Notification getNotification();
+    method public int getNotificationId();
+  }
+
+  public final class Session2Command implements android.os.Parcelable {
+    ctor public Session2Command(int);
+    ctor public Session2Command(@NonNull String, @Nullable android.os.Bundle);
+    method public int describeContents();
+    method public int getCommandCode();
+    method @Nullable public String getCustomAction();
+    method @Nullable public android.os.Bundle getCustomExtras();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int COMMAND_CODE_CUSTOM = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.Session2Command> CREATOR;
+  }
+
+  public static final class Session2Command.Result {
+    ctor public Session2Command.Result(int, @Nullable android.os.Bundle);
+    method public int getResultCode();
+    method @Nullable public android.os.Bundle getResultData();
+    field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff
+    field public static final int RESULT_INFO_SKIPPED = 1; // 0x1
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+  }
+
+  public final class Session2CommandGroup implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.Set<android.media.Session2Command> getCommands();
+    method public boolean hasCommand(@NonNull android.media.Session2Command);
+    method public boolean hasCommand(int);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.Session2CommandGroup> CREATOR;
+  }
+
+  public static final class Session2CommandGroup.Builder {
+    ctor public Session2CommandGroup.Builder();
+    ctor public Session2CommandGroup.Builder(@NonNull android.media.Session2CommandGroup);
+    method @NonNull public android.media.Session2CommandGroup.Builder addCommand(@NonNull android.media.Session2Command);
+    method @NonNull public android.media.Session2CommandGroup build();
+    method @NonNull public android.media.Session2CommandGroup.Builder removeCommand(@NonNull android.media.Session2Command);
+  }
+
+  public final class Session2Token implements android.os.Parcelable {
+    ctor public Session2Token(@NonNull android.content.Context, @NonNull android.content.ComponentName);
+    method public int describeContents();
+    method @NonNull public android.os.Bundle getExtras();
+    method @NonNull public String getPackageName();
+    method @Nullable public String getServiceName();
+    method public int getType();
+    method public int getUid();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.Session2Token> CREATOR;
+    field public static final int TYPE_SESSION = 0; // 0x0
+    field public static final int TYPE_SESSION_SERVICE = 1; // 0x1
+  }
+
+}
+
diff --git a/apex/media/framework/api/module-lib-current.txt b/apex/media/framework/api/module-lib-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/media/framework/api/module-lib-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/framework/api/module-lib-removed.txt b/apex/media/framework/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/media/framework/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/framework/api/removed.txt b/apex/media/framework/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/media/framework/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/framework/api/system-current.txt b/apex/media/framework/api/system-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/media/framework/api/system-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/framework/api/system-removed.txt b/apex/media/framework/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/media/framework/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index 29c48ad..bb3f4e9 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -25,6 +25,7 @@
 
 import com.google.android.exoplayer2.C;
 import com.google.android.exoplayer2.Format;
+import com.google.android.exoplayer2.ParserException;
 import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
 import com.google.android.exoplayer2.extractor.Extractor;
 import com.google.android.exoplayer2.extractor.ExtractorInput;
@@ -103,12 +104,12 @@
  *     private int bytesWrittenCount = 0;
  *
  *     &#64;Override
- *     public void onSeekMap(int i, &#64;NonNull MediaFormat mediaFormat) {
+ *     public void onSeekMapFound(int i, &#64;NonNull MediaFormat mediaFormat) {
  *       // Do nothing.
  *     }
  *
  *     &#64;Override
- *     public void onTrackData(int i, &#64;NonNull TrackData trackData) {
+ *     public void onTrackDataFound(int i, &#64;NonNull TrackData trackData) {
  *       MediaFormat mediaFormat = trackData.mediaFormat;
  *       if (videoTrackIndex == -1 &&
  *           mediaFormat
@@ -119,7 +120,7 @@
  *     }
  *
  *     &#64;Override
- *     public void onSampleData(int trackIndex, &#64;NonNull InputReader inputReader)
+ *     public void onSampleDataFound(int trackIndex, &#64;NonNull InputReader inputReader)
  *         throws IOException {
  *       int numberOfBytesToRead = (int) inputReader.getLength();
  *       if (videoTrackIndex != trackIndex) {
@@ -386,9 +387,9 @@
          * @param flags Flags associated with the sample. See {@link MediaCodec
          *     MediaCodec.BUFFER_FLAG_*}.
          * @param size The size of the sample data, in bytes.
-         * @param offset The number of bytes that have been consumed by {@code onSampleData(int,
-         *     MediaParser.InputReader)} for the specified track, since the last byte belonging to
-         *     the sample whose metadata is being passed.
+         * @param offset The number of bytes that have been consumed by {@code
+         *     onSampleDataFound(int, MediaParser.InputReader)} for the specified track, since the
+         *     last byte belonging to the sample whose metadata is being passed.
          * @param cryptoData Encryption data required to decrypt the sample. May be null for
          *     unencrypted samples.
          */
@@ -431,63 +432,75 @@
         }
     }
 
+    /** Thrown when an error occurs while parsing a media stream. */
+    public static final class ParsingException extends IOException {
+
+        private ParsingException(ParserException cause) {
+            super(cause);
+        }
+    }
+
     // Public constants.
 
     /**
-     * Sets whether constant bitrate seeking should be enabled for exo.AdtsParser. {@code boolean}
+     * Sets whether constant bitrate seeking should be enabled for ADTS parsing. {@code boolean}
      * expected. Default value is {@code false}.
      */
     public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING =
-            "exo.AdtsParser.enableCbrSeeking";
+            "android.media.mediaparser.adts.enableCbrSeeking";
     /**
-     * Sets whether constant bitrate seeking should be enabled for exo.AmrParser. {@code boolean}
+     * Sets whether constant bitrate seeking should be enabled for AMR. {@code boolean} expected.
+     * Default value is {@code false}.
+     */
+    public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING =
+            "android.media.mediaparser.amr.enableCbrSeeking";
+    /**
+     * Sets whether the ID3 track should be disabled for FLAC. {@code boolean} expected. Default
+     * value is {@code false}.
+     */
+    public static final String PARAMETER_FLAC_DISABLE_ID3 =
+            "android.media.mediaparser.flac.disableId3";
+    /**
+     * Sets whether MP4 parsing should ignore edit lists. {@code boolean} expected. Default value is
+     * {@code false}.
+     */
+    public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS =
+            "android.media.mediaparser.mp4.ignoreEditLists";
+    /**
+     * Sets whether MP4 parsing should ignore the tfdt box. {@code boolean} expected. Default value
+     * is {@code false}.
+     */
+    public static final String PARAMETER_MP4_IGNORE_TFDT_BOX =
+            "android.media.mediaparser.mp4.ignoreTfdtBox";
+    /**
+     * Sets whether MP4 parsing should treat all video frames as key frames. {@code boolean}
      * expected. Default value is {@code false}.
      */
-    public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING = "exo.AmrParser.enableCbrSeeking";
+    public static final String PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES =
+            "android.media.mediaparser.mp4.treatVideoFramesAsKeyframes";
     /**
-     * Sets whether the ID3 track should be disabled for exo.FlacParser. {@code boolean} expected.
-     * Default value is {@code false}.
-     */
-    public static final String PARAMETER_FLAC_DISABLE_ID3 = "exo.FlacParser.disableId3";
-    /**
-     * Sets whether exo.FragmentedMp4Parser should ignore edit lists. {@code boolean} expected.
-     * Default value is {@code false}.
-     */
-    public static final String PARAMETER_FMP4_IGNORE_EDIT_LISTS =
-            "exo.FragmentedMp4Parser.ignoreEditLists";
-    /**
-     * Sets whether exo.FragmentedMp4Parser should ignore the tfdt box. {@code boolean} expected.
-     * Default value is {@code false}.
-     */
-    public static final String PARAMETER_FMP4_IGNORE_TFDT_BOX =
-            "exo.FragmentedMp4Parser.ignoreTfdtBox";
-    /**
-     * Sets whether exo.FragmentedMp4Parser should treat all video frames as key frames. {@code
-     * boolean} expected. Default value is {@code false}.
-     */
-    public static final String PARAMETER_FMP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES =
-            "exo.FragmentedMp4Parser.treatVideoFramesAsKeyframes";
-    /**
-     * Sets whether exo.MatroskaParser should avoid seeking to the cues element. {@code boolean}
+     * Sets whether Matroska parsing should avoid seeking to the cues element. {@code boolean}
      * expected. Default value is {@code false}.
      *
      * <p>If this flag is enabled and the cues element occurs after the first cluster, then the
      * media is treated as unseekable.
      */
     public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING =
-            "exo.MatroskaParser.disableCuesSeeking";
+            "android.media.mediaparser.matroska.disableCuesSeeking";
     /**
-     * Sets whether the ID3 track should be disabled for exo.Mp3Parser. {@code boolean} expected.
+     * Sets whether the ID3 track should be disabled for MP3. {@code boolean} expected. Default
+     * value is {@code false}.
+     */
+    public static final String PARAMETER_MP3_DISABLE_ID3 =
+            "android.media.mediaparser.mp3.disableId3";
+    /**
+     * Sets whether constant bitrate seeking should be enabled for MP3. {@code boolean} expected.
      * Default value is {@code false}.
      */
-    public static final String PARAMETER_MP3_DISABLE_ID3 = "exo.Mp3Parser.disableId3";
+    public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING =
+            "android.media.mediaparser.mp3.enableCbrSeeking";
     /**
-     * Sets whether constant bitrate seeking should be enabled for exo.Mp3Parser. {@code boolean}
-     * expected. Default value is {@code false}.
-     */
-    public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING = "exo.Mp3Parser.enableCbrSeeking";
-    /**
-     * Sets whether exo.Mp3Parser should generate a time-to-byte mapping. {@code boolean} expected.
+     * Sets whether MP3 parsing should generate a time-to-byte mapping. {@code boolean} expected.
      * Default value is {@code false}.
      *
      * <p>Enabling this flag may require to scan a significant portion of the file to compute a seek
@@ -500,18 +513,13 @@
      * </ul>
      */
     public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING =
-            "exo.Mp3Parser.enableIndexSeeking";
+            "android.media.mediaparser.mp3.enableIndexSeeking";
     /**
-     * Sets whether exo.Mp4Parser should ignore edit lists. {@code boolean} expected. Default value
-     * is {@code false}.
-     */
-    public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS = "exo.Mp4Parser.ignoreEditLists";
-    /**
-     * Sets the operation mode for exo.TsParser. {@code String} expected. Valid values are {@code
+     * Sets the operation mode for TS parsing. {@code String} expected. Valid values are {@code
      * "single_pmt"}, {@code "multi_pmt"}, and {@code "hls"}. Default value is {@code "single_pmt"}.
      *
-     * <p>The operation modes alter the way exo.TsParser behaves so that it can handle certain kinds
-     * of commonly-occurring malformed media.
+     * <p>The operation modes alter the way TS behaves so that it can handle certain kinds of
+     * commonly-occurring malformed media.
      *
      * <ul>
      *   <li>{@code "single_pmt"}: Only the first found PMT is parsed. Others are ignored, even if
@@ -520,47 +528,48 @@
      *   <li>{@code "hls"}: Enable {@code "single_pmt"} mode, and ignore continuity counters.
      * </ul>
      */
-    public static final String PARAMETER_TS_MODE = "exo.TsParser.mode";
+    public static final String PARAMETER_TS_MODE = "android.media.mediaparser.ts.mode";
     /**
-     * Sets whether exo.TsParser should treat samples consisting of non-IDR I slices as
-     * synchronization samples (key-frames). {@code boolean} expected. Default value is {@code
-     * false}.
+     * Sets whether TS should treat samples consisting of non-IDR I slices as synchronization
+     * samples (key-frames). {@code boolean} expected. Default value is {@code false}.
      */
     public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES =
-            "exo.TsParser.allowNonIdrAvcKeyframes";
+            "android.media.mediaparser.ts.allowNonIdrAvcKeyframes";
     /**
-     * Sets whether exo.TsParser should ignore AAC elementary streams. {@code boolean} expected.
+     * Sets whether TS parsing should ignore AAC elementary streams. {@code boolean} expected.
      * Default value is {@code false}.
      */
-    public static final String PARAMETER_TS_IGNORE_AAC_STREAM = "exo.TsParser.ignoreAacStream";
+    public static final String PARAMETER_TS_IGNORE_AAC_STREAM =
+            "android.media.mediaparser.ts.ignoreAacStream";
     /**
-     * Sets whether exo.TsParser should ignore AVC elementary streams. {@code boolean} expected.
+     * Sets whether TS parsing should ignore AVC elementary streams. {@code boolean} expected.
      * Default value is {@code false}.
      */
-    public static final String PARAMETER_TS_IGNORE_AVC_STREAM = "exo.TsParser.ignoreAvcStream";
+    public static final String PARAMETER_TS_IGNORE_AVC_STREAM =
+            "android.media.mediaparser.ts.ignoreAvcStream";
     /**
-     * Sets whether exo.TsParser should ignore splice information streams. {@code boolean} expected.
+     * Sets whether TS parsing should ignore splice information streams. {@code boolean} expected.
      * Default value is {@code false}.
      */
     public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM =
-            "exo.TsParser.ignoreSpliceInfoStream";
+            "android.media.mediaparser.ts.ignoreSpliceInfoStream";
     /**
-     * Sets whether exo.TsParser should split AVC stream into access units based on slice headers.
+     * Sets whether TS parsing should split AVC stream into access units based on slice headers.
      * {@code boolean} expected. Default value is {@code false}.
      *
      * <p>This flag should be left disabled if the stream contains access units delimiters in order
      * to avoid unnecessary computational costs.
      */
     public static final String PARAMETER_TS_DETECT_ACCESS_UNITS =
-            "exo.TsParser.ignoreDetectAccessUnits";
+            "android.media.mediaparser.ts.ignoreDetectAccessUnits";
     /**
-     * Sets whether exo.TsParser should handle HDMV DTS audio streams. {@code boolean} expected.
+     * Sets whether TS parsing should handle HDMV DTS audio streams. {@code boolean} expected.
      * Default value is {@code false}.
      *
      * <p>Enabling this flag will disable the detection of SCTE subtitles.
      */
     public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS =
-            "exo.TsParser.enableHdmvDtsAudioStreams";
+            "android.media.mediaparser.ts.enableHdmvDtsAudioStreams";
 
     // Private constants.
 
@@ -768,6 +777,8 @@
         int result = 0;
         try {
             result = mExtractor.read(mExtractorInput, mPositionHolder);
+        } catch (ParserException e) {
+            throw new ParsingException(e);
         } catch (InterruptedException e) {
             // TODO: Remove this exception replacement once we update the ExoPlayer version.
             throw new InterruptedIOException();
@@ -1174,15 +1185,14 @@
         expectedTypeByParameterName.put(PARAMETER_ADTS_ENABLE_CBR_SEEKING, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_AMR_ENABLE_CBR_SEEKING, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_FLAC_DISABLE_ID3, Boolean.class);
-        expectedTypeByParameterName.put(PARAMETER_FMP4_IGNORE_EDIT_LISTS, Boolean.class);
-        expectedTypeByParameterName.put(PARAMETER_FMP4_IGNORE_TFDT_BOX, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_EDIT_LISTS, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_TFDT_BOX, Boolean.class);
         expectedTypeByParameterName.put(
-                PARAMETER_FMP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES, Boolean.class);
+                PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_MATROSKA_DISABLE_CUES_SEEKING, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_MP3_DISABLE_ID3, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_CBR_SEEKING, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_INDEX_SEEKING, Boolean.class);
-        expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_EDIT_LISTS, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_TS_MODE, String.class);
         expectedTypeByParameterName.put(PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_AAC_STREAM, Boolean.class);
diff --git a/apex/permission/framework/api/current.txt b/apex/permission/framework/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/permission/framework/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/permission/framework/api/module-lib-current.txt b/apex/permission/framework/api/module-lib-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/permission/framework/api/module-lib-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/permission/framework/api/module-lib-removed.txt b/apex/permission/framework/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/permission/framework/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/permission/framework/api/removed.txt b/apex/permission/framework/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/permission/framework/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/permission/framework/api/system-current.txt b/apex/permission/framework/api/system-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/permission/framework/api/system-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/permission/framework/api/system-removed.txt b/apex/permission/framework/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/permission/framework/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/current.txt b/apex/sdkextensions/framework/api/current.txt
new file mode 100644
index 0000000..9041262
--- /dev/null
+++ b/apex/sdkextensions/framework/api/current.txt
@@ -0,0 +1,10 @@
+// Signature format: 2.0
+package android.os.ext.test {
+
+  @Deprecated public class Test {
+    ctor @Deprecated public Test();
+    method @Deprecated public void testE();
+  }
+
+}
+
diff --git a/apex/sdkextensions/framework/api/module-lib-current.txt b/apex/sdkextensions/framework/api/module-lib-current.txt
new file mode 100644
index 0000000..494c12f
--- /dev/null
+++ b/apex/sdkextensions/framework/api/module-lib-current.txt
@@ -0,0 +1,9 @@
+// Signature format: 2.0
+package android.os.ext.test {
+
+  @Deprecated public class Test {
+    method @Deprecated public void testD();
+  }
+
+}
+
diff --git a/apex/sdkextensions/framework/api/module-lib-removed.txt b/apex/sdkextensions/framework/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/sdkextensions/framework/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/removed.txt b/apex/sdkextensions/framework/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/sdkextensions/framework/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/system-current.txt b/apex/sdkextensions/framework/api/system-current.txt
new file mode 100644
index 0000000..056eb41
--- /dev/null
+++ b/apex/sdkextensions/framework/api/system-current.txt
@@ -0,0 +1,18 @@
+// Signature format: 2.0
+package android.os.ext {
+
+  public class SdkExtensions {
+    method public static int getExtensionVersion(int);
+  }
+
+}
+
+package android.os.ext.test {
+
+  @Deprecated public class Test {
+    method @Deprecated public void testF();
+    method @Deprecated public void testG();
+  }
+
+}
+
diff --git a/apex/sdkextensions/framework/api/system-removed.txt b/apex/sdkextensions/framework/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/sdkextensions/framework/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
index 8185bb0..986682e 100644
--- a/apex/statsd/framework/Android.bp
+++ b/apex/statsd/framework/Android.bp
@@ -166,10 +166,8 @@
 
 android_test {
     name: "FrameworkStatsdTest",
-    platform_apis: true,
+    sdk_version: "module_current",
     srcs: [
-        // TODO(b/147705194): Use framework-statsd as a lib dependency instead.
-        ":framework-statsd-sources",
         "test/**/*.java",
     ],
     manifest: "test/AndroidManifest.xml",
@@ -180,6 +178,7 @@
     libs: [
         "android.test.runner.stubs",
         "android.test.base.stubs",
+        "framework-statsd",
     ],
     test_suites: [
         "device-tests",
diff --git a/apex/statsd/framework/api/current.txt b/apex/statsd/framework/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/statsd/framework/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/statsd/framework/api/module-lib-current.txt b/apex/statsd/framework/api/module-lib-current.txt
new file mode 100644
index 0000000..8b6e217
--- /dev/null
+++ b/apex/statsd/framework/api/module-lib-current.txt
@@ -0,0 +1,10 @@
+// Signature format: 2.0
+package android.os {
+
+  public class StatsFrameworkInitializer {
+    method public static void registerServiceWrappers();
+    method public static void setStatsServiceManager(@NonNull android.os.StatsServiceManager);
+  }
+
+}
+
diff --git a/apex/statsd/framework/api/module-lib-removed.txt b/apex/statsd/framework/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/statsd/framework/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/statsd/framework/api/removed.txt b/apex/statsd/framework/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/statsd/framework/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/statsd/framework/api/system-current.txt b/apex/statsd/framework/api/system-current.txt
new file mode 100644
index 0000000..3ea5724
--- /dev/null
+++ b/apex/statsd/framework/api/system-current.txt
@@ -0,0 +1,111 @@
+// Signature format: 2.0
+package android.app {
+
+  public final class StatsManager {
+    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void addConfig(long, byte[]) throws android.app.StatsManager.StatsUnavailableException;
+    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean addConfiguration(long, byte[]);
+    method @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM) public void clearPullAtomCallback(int);
+    method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getData(long);
+    method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getMetadata();
+    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] getRegisteredExperimentIds() throws android.app.StatsManager.StatsUnavailableException;
+    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getReports(long) throws android.app.StatsManager.StatsUnavailableException;
+    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
+    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
+    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
+    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
+    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setBroadcastSubscriber(android.app.PendingIntent, long, long) throws android.app.StatsManager.StatsUnavailableException;
+    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
+    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
+    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setFetchReportsOperation(android.app.PendingIntent, long) throws android.app.StatsManager.StatsUnavailableException;
+    method @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM) public void setPullAtomCallback(int, @Nullable android.app.StatsManager.PullAtomMetadata, @NonNull java.util.concurrent.Executor, @NonNull android.app.StatsManager.StatsPullAtomCallback);
+    field public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
+    field public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS = "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
+    field public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES = "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
+    field public static final String EXTRA_STATS_CONFIG_KEY = "android.app.extra.STATS_CONFIG_KEY";
+    field public static final String EXTRA_STATS_CONFIG_UID = "android.app.extra.STATS_CONFIG_UID";
+    field public static final String EXTRA_STATS_DIMENSIONS_VALUE = "android.app.extra.STATS_DIMENSIONS_VALUE";
+    field public static final String EXTRA_STATS_SUBSCRIPTION_ID = "android.app.extra.STATS_SUBSCRIPTION_ID";
+    field public static final String EXTRA_STATS_SUBSCRIPTION_RULE_ID = "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
+    field public static final int PULL_SKIP = 1; // 0x1
+    field public static final int PULL_SUCCESS = 0; // 0x0
+  }
+
+  public static class StatsManager.PullAtomMetadata {
+    method @Nullable public int[] getAdditiveFields();
+    method public long getCoolDownMillis();
+    method public long getTimeoutMillis();
+  }
+
+  public static class StatsManager.PullAtomMetadata.Builder {
+    ctor public StatsManager.PullAtomMetadata.Builder();
+    method @NonNull public android.app.StatsManager.PullAtomMetadata build();
+    method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setAdditiveFields(@NonNull int[]);
+    method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setCoolDownMillis(long);
+    method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setTimeoutMillis(long);
+  }
+
+  public static interface StatsManager.StatsPullAtomCallback {
+    method public int onPullAtom(int, @NonNull java.util.List<android.util.StatsEvent>);
+  }
+
+  public static class StatsManager.StatsUnavailableException extends android.util.AndroidException {
+    ctor public StatsManager.StatsUnavailableException(String);
+    ctor public StatsManager.StatsUnavailableException(String, Throwable);
+  }
+
+}
+
+package android.os {
+
+  public final class StatsDimensionsValue implements android.os.Parcelable {
+    method public int describeContents();
+    method public boolean getBooleanValue();
+    method public int getField();
+    method public float getFloatValue();
+    method public int getIntValue();
+    method public long getLongValue();
+    method public String getStringValue();
+    method public java.util.List<android.os.StatsDimensionsValue> getTupleValueList();
+    method public int getValueType();
+    method public boolean isValueType(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int BOOLEAN_VALUE_TYPE = 5; // 0x5
+    field @NonNull public static final android.os.Parcelable.Creator<android.os.StatsDimensionsValue> CREATOR;
+    field public static final int FLOAT_VALUE_TYPE = 6; // 0x6
+    field public static final int INT_VALUE_TYPE = 3; // 0x3
+    field public static final int LONG_VALUE_TYPE = 4; // 0x4
+    field public static final int STRING_VALUE_TYPE = 2; // 0x2
+    field public static final int TUPLE_VALUE_TYPE = 7; // 0x7
+  }
+
+}
+
+package android.util {
+
+  public final class StatsEvent {
+    method @NonNull public static android.util.StatsEvent.Builder newBuilder();
+  }
+
+  public static final class StatsEvent.Builder {
+    method @NonNull public android.util.StatsEvent.Builder addBooleanAnnotation(byte, boolean);
+    method @NonNull public android.util.StatsEvent.Builder addIntAnnotation(byte, int);
+    method @NonNull public android.util.StatsEvent build();
+    method @NonNull public android.util.StatsEvent.Builder setAtomId(int);
+    method @NonNull public android.util.StatsEvent.Builder usePooledBuffer();
+    method @NonNull public android.util.StatsEvent.Builder writeAttributionChain(@NonNull int[], @NonNull String[]);
+    method @NonNull public android.util.StatsEvent.Builder writeBoolean(boolean);
+    method @NonNull public android.util.StatsEvent.Builder writeByteArray(@NonNull byte[]);
+    method @NonNull public android.util.StatsEvent.Builder writeFloat(float);
+    method @NonNull public android.util.StatsEvent.Builder writeInt(int);
+    method @NonNull public android.util.StatsEvent.Builder writeKeyValuePairs(@Nullable android.util.SparseIntArray, @Nullable android.util.SparseLongArray, @Nullable android.util.SparseArray<java.lang.String>, @Nullable android.util.SparseArray<java.lang.Float>);
+    method @NonNull public android.util.StatsEvent.Builder writeLong(long);
+    method @NonNull public android.util.StatsEvent.Builder writeString(@NonNull String);
+  }
+
+  public final class StatsLog {
+    method public static void write(@NonNull android.util.StatsEvent);
+    method public static void writeRaw(@NonNull byte[], int);
+  }
+
+}
+
diff --git a/apex/statsd/framework/api/system-removed.txt b/apex/statsd/framework/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/statsd/framework/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/api/current.txt b/api/current.txt
index c0ab513..4f52862 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -288,9 +288,9 @@
     field public static final int alignmentMode = 16843642; // 0x101037a
     field public static final int allContactsName = 16843468; // 0x10102cc
     field public static final int allowAudioPlaybackCapture = 16844289; // 0x1010601
+    field public static final int allowAutoRevokePermissionsExemption = 16844309; // 0x1010615
     field public static final int allowBackup = 16843392; // 0x1010280
     field public static final int allowClearUserData = 16842757; // 0x1010005
-    field public static final int allowDontAutoRevokePermissions = 16844309; // 0x1010615
     field public static final int allowEmbedded = 16843765; // 0x10103f5
     field public static final int allowNativeHeapPointerTagging = 16844307; // 0x1010613
     field public static final int allowParallelSyncs = 16843570; // 0x1010332
@@ -1140,7 +1140,7 @@
     field public static final int reqKeyboardType = 16843304; // 0x1010228
     field public static final int reqNavigation = 16843306; // 0x101022a
     field public static final int reqTouchScreen = 16843303; // 0x1010227
-    field public static final int requestDontAutoRevokePermissions = 16844308; // 0x1010614
+    field public static final int requestAutoRevokePermissionsExemption = 16844308; // 0x1010614
     field public static final int requestLegacyExternalStorage = 16844291; // 0x1010603
     field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
     field public static final int required = 16843406; // 0x101028e
@@ -4049,6 +4049,7 @@
     method @RequiresPermission(android.Manifest.permission.REORDER_TASKS) public void moveTaskToFront(int, int);
     method @RequiresPermission(android.Manifest.permission.REORDER_TASKS) public void moveTaskToFront(int, int, android.os.Bundle);
     method @Deprecated public void restartPackage(String);
+    method public void setProcessStateSummary(@Nullable byte[]);
     method public static void setVrThread(int);
     method public void setWatchHeapLimit(long);
     field public static final String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT";
@@ -4561,12 +4562,14 @@
     method public int getPackageUid();
     method public int getPid();
     method @NonNull public String getProcessName();
+    method @Nullable public byte[] getProcessStateSummary();
     method public long getPss();
     method public int getRealUid();
     method public int getReason();
     method public long getRss();
     method public int getStatus();
     method public long getTimestamp();
+    method @Nullable public java.io.InputStream getTraceInputStream() throws java.io.IOException;
     method @NonNull public android.os.UserHandle getUserHandle();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.ApplicationExitInfo> CREATOR;
@@ -5995,7 +5998,7 @@
     method public android.service.notification.StatusBarNotification[] getActiveNotifications();
     method public android.app.AutomaticZenRule getAutomaticZenRule(String);
     method public java.util.Map<java.lang.String,android.app.AutomaticZenRule> getAutomaticZenRules();
-    method @Nullable public android.app.NotificationManager.Policy getConsolidatedNotificationPolicy();
+    method @NonNull public android.app.NotificationManager.Policy getConsolidatedNotificationPolicy();
     method public final int getCurrentInterruptionFilter();
     method public int getImportance();
     method public android.app.NotificationChannel getNotificationChannel(String);
@@ -6942,7 +6945,7 @@
     method public boolean isApplicationHidden(@NonNull android.content.ComponentName, String);
     method public boolean isBackupServiceEnabled(@NonNull android.content.ComponentName);
     method @Deprecated public boolean isCallerApplicationRestrictionsManagingPackage();
-    method public boolean isCommonCriteriaModeEnabled(@NonNull android.content.ComponentName);
+    method public boolean isCommonCriteriaModeEnabled(@Nullable android.content.ComponentName);
     method public boolean isDeviceIdAttestationSupported();
     method public boolean isDeviceOwnerApp(String);
     method public boolean isEphemeralUser(@NonNull android.content.ComponentName);
@@ -11721,6 +11724,7 @@
     ctor public LauncherApps.ShortcutQuery();
     method public android.content.pm.LauncherApps.ShortcutQuery setActivity(@Nullable android.content.ComponentName);
     method public android.content.pm.LauncherApps.ShortcutQuery setChangedSince(long);
+    method @NonNull public android.content.pm.LauncherApps.ShortcutQuery setLocusIds(@Nullable java.util.List<android.content.LocusId>);
     method public android.content.pm.LauncherApps.ShortcutQuery setPackage(@Nullable String);
     method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
     method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(@Nullable java.util.List<java.lang.String>);
@@ -23600,13 +23604,13 @@
     method @FloatRange(from=0, to=63) public double getCn0DbHz();
     method @NonNull public String getCodeType();
     method public int getConstellationType();
+    method public double getFullInterSignalBiasNanos();
+    method @FloatRange(from=0.0) public double getFullInterSignalBiasUncertaintyNanos();
     method public int getMultipathIndicator();
     method public double getPseudorangeRateMetersPerSecond();
     method public double getPseudorangeRateUncertaintyMetersPerSecond();
     method public long getReceivedSvTimeNanos();
     method public long getReceivedSvTimeUncertaintyNanos();
-    method public double getReceiverInterSignalBiasNanos();
-    method @FloatRange(from=0.0) public double getReceiverInterSignalBiasUncertaintyNanos();
     method public double getSatelliteInterSignalBiasNanos();
     method @FloatRange(from=0.0) public double getSatelliteInterSignalBiasUncertaintyNanos();
     method public double getSnrInDb();
@@ -23620,8 +23624,8 @@
     method @Deprecated public boolean hasCarrierPhase();
     method @Deprecated public boolean hasCarrierPhaseUncertainty();
     method public boolean hasCodeType();
-    method public boolean hasReceiverInterSignalBiasNanos();
-    method public boolean hasReceiverInterSignalBiasUncertaintyNanos();
+    method public boolean hasFullInterSignalBiasNanos();
+    method public boolean hasFullInterSignalBiasUncertaintyNanos();
     method public boolean hasSatelliteInterSignalBiasNanos();
     method public boolean hasSatelliteInterSignalBiasUncertaintyNanos();
     method public boolean hasSnrInDb();
@@ -26427,24 +26431,23 @@
     method public void seek(@NonNull android.media.MediaParser.SeekPoint);
     method @NonNull public android.media.MediaParser setParameter(@NonNull String, @NonNull Object);
     method public boolean supportsParameter(@NonNull String);
-    field public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING = "exo.AdtsParser.enableCbrSeeking";
-    field public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING = "exo.AmrParser.enableCbrSeeking";
-    field public static final String PARAMETER_FLAC_DISABLE_ID3 = "exo.FlacParser.disableId3";
-    field public static final String PARAMETER_FMP4_IGNORE_EDIT_LISTS = "exo.FragmentedMp4Parser.ignoreEditLists";
-    field public static final String PARAMETER_FMP4_IGNORE_TFDT_BOX = "exo.FragmentedMp4Parser.ignoreTfdtBox";
-    field public static final String PARAMETER_FMP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES = "exo.FragmentedMp4Parser.treatVideoFramesAsKeyframes";
-    field public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING = "exo.MatroskaParser.disableCuesSeeking";
-    field public static final String PARAMETER_MP3_DISABLE_ID3 = "exo.Mp3Parser.disableId3";
-    field public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING = "exo.Mp3Parser.enableCbrSeeking";
-    field public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING = "exo.Mp3Parser.enableIndexSeeking";
-    field public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS = "exo.Mp4Parser.ignoreEditLists";
-    field public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES = "exo.TsParser.allowNonIdrAvcKeyframes";
-    field public static final String PARAMETER_TS_DETECT_ACCESS_UNITS = "exo.TsParser.ignoreDetectAccessUnits";
-    field public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS = "exo.TsParser.enableHdmvDtsAudioStreams";
-    field public static final String PARAMETER_TS_IGNORE_AAC_STREAM = "exo.TsParser.ignoreAacStream";
-    field public static final String PARAMETER_TS_IGNORE_AVC_STREAM = "exo.TsParser.ignoreAvcStream";
-    field public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM = "exo.TsParser.ignoreSpliceInfoStream";
-    field public static final String PARAMETER_TS_MODE = "exo.TsParser.mode";
+    field public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING = "android.media.mediaparser.adts.enableCbrSeeking";
+    field public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING = "android.media.mediaparser.amr.enableCbrSeeking";
+    field public static final String PARAMETER_FLAC_DISABLE_ID3 = "android.media.mediaparser.flac.disableId3";
+    field public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING = "android.media.mediaparser.matroska.disableCuesSeeking";
+    field public static final String PARAMETER_MP3_DISABLE_ID3 = "android.media.mediaparser.mp3.disableId3";
+    field public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING = "android.media.mediaparser.mp3.enableCbrSeeking";
+    field public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING = "android.media.mediaparser.mp3.enableIndexSeeking";
+    field public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS = "android.media.mediaparser.mp4.ignoreEditLists";
+    field public static final String PARAMETER_MP4_IGNORE_TFDT_BOX = "android.media.mediaparser.mp4.ignoreTfdtBox";
+    field public static final String PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES = "android.media.mediaparser.mp4.treatVideoFramesAsKeyframes";
+    field public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES = "android.media.mediaparser.ts.allowNonIdrAvcKeyframes";
+    field public static final String PARAMETER_TS_DETECT_ACCESS_UNITS = "android.media.mediaparser.ts.ignoreDetectAccessUnits";
+    field public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS = "android.media.mediaparser.ts.enableHdmvDtsAudioStreams";
+    field public static final String PARAMETER_TS_IGNORE_AAC_STREAM = "android.media.mediaparser.ts.ignoreAacStream";
+    field public static final String PARAMETER_TS_IGNORE_AVC_STREAM = "android.media.mediaparser.ts.ignoreAvcStream";
+    field public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM = "android.media.mediaparser.ts.ignoreSpliceInfoStream";
+    field public static final String PARAMETER_TS_MODE = "android.media.mediaparser.ts.mode";
   }
 
   public static interface MediaParser.InputReader {
@@ -26461,6 +26464,9 @@
     method public void onTrackDataFound(int, @NonNull android.media.MediaParser.TrackData);
   }
 
+  public static final class MediaParser.ParsingException extends java.io.IOException {
+  }
+
   public static final class MediaParser.SeekMap {
     method public long getDurationMicros();
     method @NonNull public android.util.Pair<android.media.MediaParser.SeekPoint,android.media.MediaParser.SeekPoint> getSeekPoints(long);
@@ -32450,7 +32456,7 @@
     method public boolean categoryAllowsForegroundPreference(String);
     method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
     method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
-    method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getDescriptionForPreferredPaymentService();
+    method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService();
     method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
     method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService();
     method public int getSelectionModeForCategory(String);
@@ -48107,7 +48113,7 @@
     method public long getDataLimitBytes();
     method public long getDataUsageBytes();
     method public long getDataUsageTime();
-    method @Nullable public int[] getNetworkTypes();
+    method @NonNull public int[] getNetworkTypes();
     method @Nullable public CharSequence getSummary();
     method @Nullable public CharSequence getTitle();
     method public void writeToParcel(android.os.Parcel, int);
@@ -48127,7 +48133,7 @@
     method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
     method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
     method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
-    method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@Nullable int[]);
+    method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@NonNull int[]);
     method public android.telephony.SubscriptionPlan.Builder setSummary(@Nullable CharSequence);
     method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence);
   }
@@ -48210,7 +48216,6 @@
     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);
@@ -53617,6 +53622,7 @@
 
   public static final class SurfaceControlViewHost.SurfacePackage implements android.os.Parcelable {
     method public int describeContents();
+    method public void release();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.view.SurfaceControlViewHost.SurfacePackage> CREATOR;
   }
@@ -55570,7 +55576,8 @@
   }
 
   public interface WindowInsetsAnimationControlListener {
-    method public void onCancelled();
+    method public void onCancelled(@Nullable android.view.WindowInsetsAnimationController);
+    method public void onFinished(@NonNull android.view.WindowInsetsAnimationController);
     method public void onReady(@NonNull android.view.WindowInsetsAnimationController, int);
   }
 
@@ -55582,6 +55589,9 @@
     method @NonNull public android.graphics.Insets getHiddenStateInsets();
     method @NonNull public android.graphics.Insets getShownStateInsets();
     method public int getTypes();
+    method public boolean isCancelled();
+    method public boolean isFinished();
+    method public default boolean isReady();
     method public void setInsetsAndAlpha(@Nullable android.graphics.Insets, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
   }
 
diff --git a/api/system-current.txt b/api/system-current.txt
index ab3bcc1..b13a420 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -148,6 +148,7 @@
     field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
     field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP";
     field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
+    field public static final String NETWORK_STATS_PROVIDER = "android.permission.NETWORK_STATS_PROVIDER";
     field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -205,7 +206,7 @@
     field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES";
     field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
     field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
-    field public static final String SECURE_ELEMENT_PRIVILEGED = "android.permission.SECURE_ELEMENT_PRIVILEGED";
+    field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION";
     field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY";
     field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS";
     field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION";
@@ -350,7 +351,6 @@
     method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public static void setPersistentVrThread(int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean switchUser(@NonNull android.os.UserHandle);
     method public void unregisterHomeVisibilityObserver(@NonNull android.app.HomeVisibilityObserver);
-    method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
   }
 
   public static interface ActivityManager.OnUidImportanceListener {
@@ -387,6 +387,7 @@
     field public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME = "android:audio_notification_volume";
     field public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
     field public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
+    field public static final String OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER = "android:auto_revoke_managed_by_installer";
     field public static final String OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = "android:auto_revoke_permissions_if_unused";
     field public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE = "android:bind_accessibility_service";
     field public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
@@ -1410,7 +1411,8 @@
   }
 
   public class NetworkStatsManager {
-    method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.net.netstats.provider.NetworkStatsProviderCallback registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.AbstractNetworkStatsProvider);
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider);
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider);
   }
 
   public static final class UsageEvents.Event {
@@ -2102,10 +2104,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.AppUsageLimit> CREATOR;
   }
 
-  public static class LauncherApps.ShortcutQuery {
-    method @NonNull public android.content.pm.LauncherApps.ShortcutQuery setLocusIds(@Nullable java.util.List<android.content.LocusId>);
-  }
-
   public class PackageInstaller {
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
     field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2
@@ -2316,7 +2314,6 @@
     field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000
     field public static final int PROTECTION_FLAG_RETAIL_DEMO = 16777216; // 0x1000000
     field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
-    field public static final int PROTECTION_FLAG_TELEPHONY = 4194304; // 0x400000
     field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000
     field @Nullable public final String backgroundPermission;
     field @StringRes public int requestRes;
@@ -4889,16 +4886,10 @@
     method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public void shareFrontendFromTuner(@NonNull android.media.tv.tuner.Tuner);
     method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int tune(@NonNull android.media.tv.tuner.frontend.FrontendSettings);
     method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public void updateResourcePriority(int, int);
-  }
-
-  public static interface Tuner.OnResourceLostListener {
-    method public void onResourceLost(@NonNull android.media.tv.tuner.Tuner);
-  }
-
-  public final class TunerConstants {
     field public static final int INVALID_AV_SYNC_ID = -1; // 0xffffffff
     field public static final int INVALID_FILTER_ID = -1; // 0xffffffff
     field public static final int INVALID_STREAM_ID = 65535; // 0xffff
+    field public static final long INVALID_TIMESTAMP = -1L; // 0xffffffffffffffffL
     field public static final int INVALID_TS_PID = 65535; // 0xffff
     field public static final int RESULT_INVALID_ARGUMENT = 4; // 0x4
     field public static final int RESULT_INVALID_STATE = 3; // 0x3
@@ -4912,6 +4903,10 @@
     field public static final int SCAN_TYPE_UNDEFINED = 0; // 0x0
   }
 
+  public static interface Tuner.OnResourceLostListener {
+    method public void onResourceLost(@NonNull android.media.tv.tuner.Tuner);
+  }
+
 }
 
 package android.media.tv.tuner.dvr {
@@ -5272,7 +5267,6 @@
     method public long getSourceTime();
     method public long getTimeStamp();
     method public int setCurrentTimestamp(long);
-    field public static final long TIMESTAMP_UNAVAILABLE = -1L; // 0xffffffffffffffffL
   }
 
   public final class TlvFilterConfiguration extends android.media.tv.tuner.filter.FilterConfiguration {
@@ -6326,11 +6320,11 @@
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
-    method @NonNull public java.util.List<java.lang.Integer> getAdministratorUids();
+    method @NonNull public int[] getAdministratorUids();
     method @Nullable public String getSSID();
     method @NonNull public int[] getTransportTypes();
     method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
-    method @NonNull public android.net.NetworkCapabilities setAdministratorUids(@NonNull java.util.List<java.lang.Integer>);
+    method @NonNull public android.net.NetworkCapabilities setAdministratorUids(@NonNull int[]);
     method @NonNull public android.net.NetworkCapabilities setRequestorPackageName(@NonNull String);
     method @NonNull public android.net.NetworkCapabilities setRequestorUid(int);
     method @NonNull public android.net.NetworkCapabilities setSSID(@Nullable String);
@@ -6414,14 +6408,13 @@
   public final class NetworkStats implements android.os.Parcelable {
     ctor public NetworkStats(long, int);
     method @NonNull public android.net.NetworkStats add(@NonNull android.net.NetworkStats);
-    method @NonNull public android.net.NetworkStats addValues(@NonNull android.net.NetworkStats.Entry);
+    method @NonNull public android.net.NetworkStats addEntry(@NonNull android.net.NetworkStats.Entry);
     method public int describeContents();
     method @NonNull public android.net.NetworkStats subtract(@NonNull android.net.NetworkStats);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStats> CREATOR;
     field public static final int DEFAULT_NETWORK_NO = 0; // 0x0
     field public static final int DEFAULT_NETWORK_YES = 1; // 0x1
-    field @Nullable public static final String IFACE_ALL;
     field public static final String IFACE_VT = "vt_data0";
     field public static final int METERED_NO = 0; // 0x0
     field public static final int METERED_YES = 1; // 0x1
@@ -6821,21 +6814,17 @@
 
 package android.net.netstats.provider {
 
-  public abstract class AbstractNetworkStatsProvider {
-    ctor public AbstractNetworkStatsProvider();
-    method public abstract void requestStatsUpdate(int);
-    method public abstract void setAlert(long);
-    method public abstract void setLimit(@NonNull String, long);
+  public abstract class NetworkStatsProvider {
+    ctor public NetworkStatsProvider();
+    method public void notifyAlertReached();
+    method public void notifyLimitReached();
+    method public void notifyStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats);
+    method public abstract void onRequestStatsUpdate(int);
+    method public abstract void onSetAlert(long);
+    method public abstract void onSetLimit(@NonNull String, long);
     field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff
   }
 
-  public class NetworkStatsProviderCallback {
-    method public void onAlertReached();
-    method public void onLimitReached();
-    method public void onStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats);
-    method public void unregister();
-  }
-
 }
 
 package android.net.sip {
@@ -7459,7 +7448,15 @@
   }
 
   public final class WifiMigration {
+    method @Nullable public static java.io.InputStream convertAndRetrieveSharedConfigStoreFile(int);
+    method @Nullable public static java.io.InputStream convertAndRetrieveUserConfigStoreFile(int, @NonNull android.os.UserHandle);
     method @NonNull public static android.net.wifi.WifiMigration.SettingsMigrationData loadFromSettings(@NonNull android.content.Context);
+    method public static void removeSharedConfigStoreFile(int);
+    method public static void removeUserConfigStoreFile(int, @NonNull android.os.UserHandle);
+    field public static final int STORE_FILE_SHARED_GENERAL = 0; // 0x0
+    field public static final int STORE_FILE_SHARED_SOFTAP = 1; // 0x1
+    field public static final int STORE_FILE_USER_GENERAL = 2; // 0x2
+    field public static final int STORE_FILE_USER_NETWORK_SUGGESTIONS = 3; // 0x3
   }
 
   public static final class WifiMigration.SettingsMigrationData implements android.os.Parcelable {
@@ -9292,7 +9289,6 @@
     field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
     field public static final String CARRIER_APP_NAMES = "carrier_app_names";
     field public static final String CARRIER_APP_WHITELIST = "carrier_app_whitelist";
-    field public static final String COMMON_CRITERIA_MODE = "common_criteria_mode";
     field public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
     field public static final String DEVICE_DEMO_MODE = "device_demo_mode";
     field public static final String DEVICE_PROVISIONING_MOBILE_DATA_ENABLED = "device_provisioning_mobile_data";
@@ -9352,32 +9348,6 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE) public static boolean putString(@NonNull android.content.ContentResolver, @NonNull String, @Nullable String, boolean);
   }
 
-  public static interface Telephony.CarrierColumns extends android.provider.BaseColumns {
-    field @NonNull public static final android.net.Uri CONTENT_URI;
-    field public static final String EXPIRATION_TIME = "expiration_time";
-    field public static final String KEY_IDENTIFIER = "key_identifier";
-    field public static final String KEY_TYPE = "key_type";
-    field public static final String LAST_MODIFIED = "last_modified";
-    field public static final String MCC = "mcc";
-    field public static final String MNC = "mnc";
-    field public static final String MVNO_MATCH_DATA = "mvno_match_data";
-    field public static final String MVNO_TYPE = "mvno_type";
-    field public static final String PUBLIC_KEY = "public_key";
-  }
-
-  public static final class Telephony.CarrierId.All implements android.provider.BaseColumns {
-    field public static final String APN = "apn";
-    field @NonNull public static final android.net.Uri CONTENT_URI;
-    field public static final String GID1 = "gid1";
-    field public static final String GID2 = "gid2";
-    field public static final String ICCID_PREFIX = "iccid_prefix";
-    field public static final String IMSI_PREFIX_XPATTERN = "imsi_prefix_xpattern";
-    field public static final String MCCMNC = "mccmnc";
-    field public static final String PLMN = "plmn";
-    field public static final String PRIVILEGE_ACCESS_RULE = "privilege_access_rule";
-    field public static final String SPN = "spn";
-  }
-
   public static final class Telephony.Carriers implements android.provider.BaseColumns {
     field public static final String APN_SET_ID = "apn_set_id";
     field public static final int CARRIER_EDITED = 4; // 0x4
@@ -9541,7 +9511,7 @@
 package android.se.omapi {
 
   public final class Reader {
-    method @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED) public boolean reset();
+    method @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION) public boolean reset();
   }
 
 }
@@ -10718,27 +10688,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
   }
 
-  public final class CallForwardingInfo implements android.os.Parcelable {
-    ctor public CallForwardingInfo(int, int, @Nullable String, int);
-    method public int describeContents();
-    method @Nullable public String getNumber();
-    method public int getReason();
-    method public int getStatus();
-    method public int getTimeoutSeconds();
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallForwardingInfo> CREATOR;
-    field public static final int REASON_ALL = 4; // 0x4
-    field public static final int REASON_ALL_CONDITIONAL = 5; // 0x5
-    field public static final int REASON_BUSY = 1; // 0x1
-    field public static final int REASON_NOT_REACHABLE = 3; // 0x3
-    field public static final int REASON_NO_REPLY = 2; // 0x2
-    field public static final int REASON_UNCONDITIONAL = 0; // 0x0
-    field public static final int STATUS_ACTIVE = 1; // 0x1
-    field public static final int STATUS_FDN_CHECK_FAILURE = 2; // 0x2
-    field public static final int STATUS_INACTIVE = 0; // 0x0
-    field public static final int STATUS_NOT_SUPPORTED = 4; // 0x4
-    field public static final int STATUS_UNKNOWN_ERROR = 3; // 0x3
-  }
-
   public final class CallQuality implements android.os.Parcelable {
     ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
     ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean);
@@ -11119,7 +11068,6 @@
     method public void onRadioPowerStateChanged(int);
     method public void onSrvccStateChanged(int);
     method public void onVoiceActivationStateChanged(int);
-    field @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH = 512; // 0x200
     field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
     field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
     field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
@@ -11150,7 +11098,6 @@
   }
 
   public final class PreciseDataConnectionState implements android.os.Parcelable {
-    ctor public PreciseDataConnectionState(int, int, int, @NonNull String, @Nullable android.net.LinkProperties, int, @Nullable android.telephony.data.ApnSetting);
     method @Deprecated @NonNull public String getDataConnectionApn();
     method @Deprecated public int getDataConnectionApnTypeBitMask();
     method @Deprecated public int getDataConnectionFailCause();
@@ -11502,8 +11449,6 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes();
     method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
-    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CallForwardingInfo getCallForwarding(int);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCallWaitingStatus();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -11584,8 +11529,6 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAlwaysAllowMmsData(boolean);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallForwarding(@NonNull android.telephony.CallForwardingInfo);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallWaitingStatus(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
@@ -11624,15 +11567,10 @@
     field public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED";
     field public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED = "android.intent.action.EMERGENCY_CALL_STATE_CHANGED";
     field public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE = "com.android.omadm.service.CONFIGURATION_UPDATE";
-    field public static final String ACTION_SERVICE_PROVIDERS_UPDATED = "android.telephony.action.SERVICE_PROVIDERS_UPDATED";
     field public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS = "android.telephony.action.SHOW_NOTICE_ECM_BLOCK_OTHERS";
     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 CALL_WAITING_STATUS_ACTIVE = 1; // 0x1
-    field public static final int CALL_WAITING_STATUS_INACTIVE = 2; // 0x2
-    field public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; // 0x4
-    field public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; // 0x3
     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
@@ -11646,7 +11584,6 @@
     field public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt";
     field @Deprecated public static final String EXTRA_APN_TYPE = "apnType";
     field public static final String EXTRA_APN_TYPE_INT = "apnTypeInt";
-    field public static final String EXTRA_DATA_SPN = "android.telephony.extra.DATA_SPN";
     field public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable";
     field public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE = "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE";
     field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4; // 0x4
@@ -11659,16 +11596,12 @@
     field public static final String EXTRA_PCO_VALUE = "pcoValue";
     field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE";
     field public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = "android.telephony.extra.PHONE_IN_EMERGENCY_CALL";
-    field public static final String EXTRA_PLMN = "android.telephony.extra.PLMN";
     field public static final String EXTRA_REDIRECTION_URL = "redirectionUrl";
-    field public static final String EXTRA_SHOW_PLMN = "android.telephony.extra.SHOW_PLMN";
-    field public static final String EXTRA_SHOW_SPN = "android.telephony.extra.SHOW_SPN";
     field public static final String EXTRA_SIM_COMBINATION_NAMES = "android.telephony.extra.SIM_COMBINATION_NAMES";
     field public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE = "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
     field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1; // 0x1
     field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0; // 0x0
     field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
-    field public static final String EXTRA_SPN = "android.telephony.extra.SPN";
     field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
     field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff
diff --git a/api/test-current.txt b/api/test-current.txt
index a1a652f..286408d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -83,7 +83,6 @@
     method public static void resumeAppSwitches() throws android.os.RemoteException;
     method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
     method @RequiresPermission("android.permission.MANAGE_USERS") public boolean switchUser(@NonNull android.os.UserHandle);
-    method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
     field public static final int PROCESS_CAPABILITY_ALL = 7; // 0x7
     field public static final int PROCESS_CAPABILITY_ALL_EXPLICIT = 1; // 0x1
     field public static final int PROCESS_CAPABILITY_ALL_IMPLICIT = 6; // 0x6
@@ -965,7 +964,6 @@
     method @NonNull public abstract String getServicesSystemSharedLibraryPackageName();
     method @NonNull public abstract String getSharedSystemSharedLibraryPackageName();
     method @Nullable public String getSystemTextClassifierPackageName();
-    method @Nullable public String[] getTelephonyPackageNames();
     method @Nullable public String getWellbeingPackageName();
     method @RequiresPermission("android.permission.GRANT_RUNTIME_PERMISSIONS") public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
     method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
@@ -1008,7 +1006,6 @@
     field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000
     field public static final int PROTECTION_FLAG_RETAIL_DEMO = 16777216; // 0x1000000
     field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
-    field public static final int PROTECTION_FLAG_TELEPHONY = 4194304; // 0x400000
     field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000
     field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000
     field @Nullable public final String backgroundPermission;
@@ -1356,8 +1353,8 @@
     method @Deprecated public void resetCarrierPhase();
     method @Deprecated public void resetCarrierPhaseUncertainty();
     method public void resetCodeType();
-    method public void resetReceiverInterSignalBiasNanos();
-    method public void resetReceiverInterSignalBiasUncertaintyNanos();
+    method public void resetFullInterSignalBiasNanos();
+    method public void resetFullInterSignalBiasUncertaintyNanos();
     method public void resetSatelliteInterSignalBiasNanos();
     method public void resetSatelliteInterSignalBiasUncertaintyNanos();
     method public void resetSnrInDb();
@@ -1374,13 +1371,13 @@
     method public void setCn0DbHz(double);
     method public void setCodeType(@NonNull String);
     method public void setConstellationType(int);
+    method public void setFullInterSignalBiasNanos(double);
+    method public void setFullInterSignalBiasUncertaintyNanos(@FloatRange(from=0.0) double);
     method public void setMultipathIndicator(int);
     method public void setPseudorangeRateMetersPerSecond(double);
     method public void setPseudorangeRateUncertaintyMetersPerSecond(double);
     method public void setReceivedSvTimeNanos(long);
     method public void setReceivedSvTimeUncertaintyNanos(long);
-    method public void setReceiverInterSignalBiasNanos(double);
-    method public void setReceiverInterSignalBiasUncertaintyNanos(@FloatRange(from=0.0) double);
     method public void setSatelliteInterSignalBiasNanos(double);
     method public void setSatelliteInterSignalBiasUncertaintyNanos(@FloatRange(from=0.0) double);
     method public void setSnrInDb(double);
diff --git a/api/test-lint-baseline.txt b/api/test-lint-baseline.txt
index 94db346..caf8fdb 100644
--- a/api/test-lint-baseline.txt
+++ b/api/test-lint-baseline.txt
@@ -421,9 +421,9 @@
     
 GetterSetterNames: android.location.GnssMeasurement#setCodeType(String):
 
-GetterSetterNames: android.location.GnssMeasurement#setReceiverInterSignalBiasNanos(double):
+GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasNanos(double):
 
-GetterSetterNames: android.location.GnssMeasurement#setReceiverInterSignalBiasUncertaintyNanos(double):
+GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasUncertaintyNanos(double):
 
 GetterSetterNames: android.location.GnssMeasurement#setSatelliteInterSignalBiasNanos(double):
 
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index d79123b..60d1ac7 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -267,28 +267,29 @@
     bool workerDone = false;
     FdBuffer buffer;
 
-    // Create shared data and pipe
-    WorkerThreadData data(this);
-    if (!data.pipe.init()) {
+    // Create shared data and pipe. Don't put data on the stack since this thread may exit early.
+    sp<WorkerThreadData> data = new WorkerThreadData(this);
+    if (!data->pipe.init()) {
         return -errno;
     }
-
-    std::thread([&]() {
+    data->incStrong(this);
+    std::thread([data, this]() {
         // Don't crash the service if writing to a closed pipe (may happen if dumping times out)
         signal(SIGPIPE, sigpipe_handler);
-        status_t err = data.section->BlockingCall(data.pipe.writeFd());
+        status_t err = data->section->BlockingCall(data->pipe.writeFd());
         {
-            std::unique_lock<std::mutex> lock(data.lock);
-            data.workerDone = true;
-            data.workerError = err;
+            std::scoped_lock<std::mutex> lock(data->lock);
+            data->workerDone = true;
+            data->workerError = err;
             // unique_fd is not thread safe. If we don't lock it, reset() may pause half way while
             // the other thread executes to the end, calling ~Fpipe, which is a race condition.
-            data.pipe.writeFd().reset();
+            data->pipe.writeFd().reset();
         }
+        data->decStrong(this);
     }).detach();
 
     // Loop reading until either the timeout or the worker side is done (i.e. eof).
-    err = buffer.read(data.pipe.readFd().get(), this->timeoutMs);
+    err = buffer.read(data->pipe.readFd().get(), this->timeoutMs);
     if (err != NO_ERROR) {
         ALOGE("[%s] reader failed with error '%s'", this->name.string(), strerror(-err));
     }
@@ -296,13 +297,13 @@
     // If the worker side is finished, then return its error (which may overwrite
     // our possible error -- but it's more interesting anyway). If not, then we timed out.
     {
-        std::unique_lock<std::mutex> lock(data.lock);
-        data.pipe.close();
-        if (data.workerError != NO_ERROR) {
-            err = data.workerError;
+        std::scoped_lock<std::mutex> lock(data->lock);
+        data->pipe.close();
+        if (data->workerError != NO_ERROR) {
+            err = data->workerError;
             ALOGE("[%s] worker failed with error '%s'", this->name.string(), strerror(-err));
         }
-        workerDone = data.workerDone;
+        workerDone = data->workerDone;
     }
 
     writer->setSectionStats(buffer);
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 33bfe51..4529dff 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -189,6 +189,34 @@
     ],
 }
 
+genrule {
+    name: "statslog_statsdtest.h",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_statsdtest.h --module statsdtest --namespace android,os,statsd,util",
+    out: [
+        "statslog_statsdtest.h",
+    ],
+}
+
+genrule {
+    name: "statslog_statsdtest.cpp",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_statsdtest.cpp --module statsdtest --namespace android,os,statsd,util --importHeader statslog_statsdtest.h",
+    out: [
+        "statslog_statsdtest.cpp",
+    ],
+}
+
+cc_library_static {
+    name: "libstatslog_statsdtest",
+    generated_sources: ["statslog_statsdtest.cpp"],
+    generated_headers: ["statslog_statsdtest.h"],
+    export_generated_headers: ["statslog_statsdtest.h"],
+    shared_libs: [
+        "libstatssocket",
+    ]
+}
+
 cc_library_static {
     name: "libstatslog_statsd",
     generated_sources: ["statslog_statsd.cpp"],
@@ -331,7 +359,7 @@
     static_libs: [
         "libgmock",
         "libplatformprotos",
-        "libstatslog", //TODO(b/150976524): remove this when the tests no longer hardcode atoms.
+        "libstatslog_statsdtest",
         "libstatssocket_private",
     ],
 
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 713e923..f0a5b51 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -81,12 +81,16 @@
         BleScanStateChanged ble_scan_state_changed = 2 [(module) = "bluetooth"];
         ProcessStateChanged process_state_changed = 3 [(module) = "framework"];
         BleScanResultReceived ble_scan_result_received = 4 [(module) = "bluetooth"];
-        SensorStateChanged sensor_state_changed = 5 [(module) = "framework"];
+        SensorStateChanged sensor_state_changed =
+                5 [(module) = "framework", (module) = "statsdtest"];
         GpsScanStateChanged gps_scan_state_changed = 6 [(module) = "framework"];
-        SyncStateChanged sync_state_changed = 7 [(module) = "framework"];
-        ScheduledJobStateChanged scheduled_job_state_changed = 8 [(module) = "framework"];
-        ScreenBrightnessChanged screen_brightness_changed = 9 [(module) = "framework"];
-        WakelockStateChanged wakelock_state_changed = 10 [(module) = "framework"];
+        SyncStateChanged sync_state_changed = 7 [(module) = "framework", (module) = "statsdtest"];
+        ScheduledJobStateChanged scheduled_job_state_changed =
+                8 [(module) = "framework", (module) = "statsdtest"];
+        ScreenBrightnessChanged screen_brightness_changed =
+                9 [(module) = "framework", (module) = "statsdtest"];
+        WakelockStateChanged wakelock_state_changed =
+                10 [(module) = "framework", (module) = "statsdtest"];
         LongPartialWakelockStateChanged long_partial_wakelock_state_changed =
                 11 [(module) = "framework"];
         MobileRadioPowerStateChanged mobile_radio_power_state_changed = 12 [(module) = "framework"];
@@ -98,17 +102,22 @@
         CachedKillReported cached_kill_reported = 17 [(module) = "framework"];
         ProcessMemoryStatReported process_memory_stat_reported = 18 [(module) = "framework"];
         LauncherUIChanged launcher_event = 19 [(module) = "sysui"];
-        BatterySaverModeStateChanged battery_saver_mode_state_changed = 20 [(module) = "framework"];
+        BatterySaverModeStateChanged battery_saver_mode_state_changed =
+                20 [(module) = "framework", (module) = "statsdtest"];
         DeviceIdleModeStateChanged device_idle_mode_state_changed = 21 [(module) = "framework"];
         DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22 [(module) = "framework"];
         AudioStateChanged audio_state_changed = 23 [(module) = "framework"];
         MediaCodecStateChanged media_codec_state_changed = 24 [(module) = "framework"];
         CameraStateChanged camera_state_changed = 25 [(module) = "framework"];
         FlashlightStateChanged flashlight_state_changed = 26 [(module) = "framework"];
-        UidProcessStateChanged uid_process_state_changed = 27 [(module) = "framework"];
-        ProcessLifeCycleStateChanged process_life_cycle_state_changed = 28 [(module) = "framework"];
-        ScreenStateChanged screen_state_changed = 29 [(module) = "framework"];
-        BatteryLevelChanged battery_level_changed = 30 [(module) = "framework"];
+        UidProcessStateChanged uid_process_state_changed =
+                27 [(module) = "framework", (module) = "statsdtest"];
+        ProcessLifeCycleStateChanged process_life_cycle_state_changed =
+                28 [(module) = "framework", (module) = "statsdtest"];
+        ScreenStateChanged screen_state_changed =
+                29 [(module) = "framework", (module) = "statsdtest"];
+        BatteryLevelChanged battery_level_changed =
+                30 [(module) = "framework", (module) = "statsdtest"];
         ChargingStateChanged charging_state_changed = 31 [(module) = "framework"];
         PluggedStateChanged plugged_state_changed = 32 [(module) = "framework"];
         InteractiveStateChanged interactive_state_changed = 33 [(module) = "framework"];
@@ -121,14 +130,15 @@
         PhoneSignalStrengthChanged phone_signal_strength_changed = 40 [(module) = "framework"];
         SettingChanged setting_changed = 41 [(module) = "framework"];
         ActivityForegroundStateChanged activity_foreground_state_changed =
-                42 [(module) = "framework"];
-        IsolatedUidChanged isolated_uid_changed = 43 [(module) = "framework", (module) = "statsd"];
+                42 [(module) = "framework", (module) = "statsdtest"];
+        IsolatedUidChanged isolated_uid_changed =
+                43 [(module) = "framework", (module) = "statsd", (module) = "statsdtest"];
         PacketWakeupOccurred packet_wakeup_occurred = 44 [(module) = "framework"];
         WallClockTimeShifted wall_clock_time_shifted = 45 [(module) = "framework"];
         AnomalyDetected anomaly_detected = 46 [(module) = "statsd"];
         AppBreadcrumbReported app_breadcrumb_reported =
                 47 [(allow_from_any_uid) = true, (module) = "statsd"];
-        AppStartOccurred app_start_occurred = 48 [(module) = "framework"];
+        AppStartOccurred app_start_occurred = 48 [(module) = "framework", (module) = "statsdtest"];
         AppStartCanceled app_start_canceled = 49 [(module) = "framework"];
         AppStartFullyDrawn app_start_fully_drawn = 50 [(module) = "framework"];
         LmkKillOccurred lmk_kill_occurred = 51 [(module) = "lmkd"];
@@ -139,7 +149,8 @@
         ShutdownSequenceReported shutdown_sequence_reported = 56 [(module) = "framework"];
         BootSequenceReported boot_sequence_reported = 57;
         DaveyOccurred davey_occurred = 58 [(allow_from_any_uid) = true, (module) = "statsd"];
-        OverlayStateChanged overlay_state_changed = 59 [(module) = "framework"];
+        OverlayStateChanged overlay_state_changed =
+                59 [(module) = "framework", (module) = "statsdtest"];
         ForegroundServiceStateChanged foreground_service_state_changed
                 = 60 [(module) = "framework"];
         CallStateChanged call_state_changed = 61 [(module) = "telecom"];
@@ -160,7 +171,7 @@
         MobileConnectionStateChanged mobile_connection_state_changed = 75 [(module) = "telephony"];
         MobileRadioTechnologyChanged mobile_radio_technology_changed = 76 [(module) = "telephony"];
         UsbDeviceAttached usb_device_attached = 77 [(module) = "framework"];
-        AppCrashOccurred app_crash_occurred = 78 [(module) = "framework"];
+        AppCrashOccurred app_crash_occurred = 78 [(module) = "framework", (module) = "statsdtest"];
         ANROccurred anr_occurred = 79 [(module) = "framework"];
         WTFOccurred wtf_occurred = 80 [(module) = "framework"];
         LowMemReported low_mem_reported = 81 [(module) = "framework"];
@@ -398,6 +409,8 @@
             256  [(module) = "framework"];
         DisplayJankReported display_jank_reported = 257;
         AppStandbyBucketChanged app_standby_bucket_changed = 258 [(module) = "framework"];
+        SharesheetStarted sharesheet_started = 259 [(module) = "framework"];
+        RankingSelected ranking_selected = 260 [(module) = "framework"];
         SdkExtensionStatus sdk_extension_status = 354;
     }
 
@@ -410,9 +423,9 @@
         MobileBytesTransferByFgBg mobile_bytes_transfer_by_fg_bg = 10003 [(module) = "framework"];
         BluetoothBytesTransfer bluetooth_bytes_transfer = 10006 [(module) = "framework"];
         KernelWakelock kernel_wakelock = 10004 [(module) = "framework"];
-        SubsystemSleepState subsystem_sleep_state = 10005;
+        SubsystemSleepState subsystem_sleep_state = 10005 [(module) = "statsdtest"];
         CpuTimePerFreq cpu_time_per_freq = 10008 [(module) = "framework"];
-        CpuTimePerUid cpu_time_per_uid = 10009 [(module) = "framework"];
+        CpuTimePerUid cpu_time_per_uid = 10009 [(module) = "framework", (module) = "statsdtest"];
         CpuTimePerUidFreq cpu_time_per_uid_freq =
                 10010 [(module) = "framework", (module) = "statsd"];
         WifiActivityInfo wifi_activity_info = 10011 [(module) = "framework"];
@@ -420,13 +433,13 @@
         BluetoothActivityInfo bluetooth_activity_info = 10007 [(module) = "framework"];
         ProcessMemoryState process_memory_state = 10013 [(module) = "framework"];
         SystemElapsedRealtime system_elapsed_realtime = 10014 [(module) = "framework"];
-        SystemUptime system_uptime = 10015 [(module) = "framework"];
+        SystemUptime system_uptime = 10015 [(module) = "framework", (module) = "statsdtest"];
         CpuActiveTime cpu_active_time = 10016 [(module) = "framework"];
-        CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework"];
-        DiskSpace disk_space = 10018 [deprecated=true];
+        CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework", (module) = "statsdtest"];
+        DiskSpace disk_space = 10018 [deprecated=true, (module) = "statsdtest"];
         RemainingBatteryCapacity remaining_battery_capacity = 10019 [(module) = "framework"];
         FullBatteryCapacity full_battery_capacity = 10020 [(module) = "framework"];
-        Temperature temperature = 10021 [(module) = "framework"];
+        Temperature temperature = 10021 [(module) = "framework", (module) = "statsdtest"];
         BinderCalls binder_calls = 10022 [(module) = "framework", (module) = "statsd"];
         BinderCallsExceptions binder_calls_exceptions = 10023 [(module) = "framework"];
         LooperStats looper_stats = 10024 [(module) = "framework", (module) = "statsd"];
@@ -8914,3 +8927,64 @@
     // UsageStatsManager.java.
     optional int32 sub_reason = 5;
 }
+
+/**
+* Reports a started sharesheet transaction.
+*
+* Logged from:
+*   frameworks/base/core/java/com/android/internal/app/ChooserActivity.java
+*/
+message SharesheetStarted {
+    // The event_id (as for UiEventReported).
+    optional int32 event_id = 1;
+    // The calling app's package name.
+    optional string package_name = 2;
+    // An identifier to tie together multiple logs relating to the same share event
+    optional int32 instance_id = 3;
+    // The mime type of the share
+    optional string mime_type = 4;
+    // The number of direct targets the calling app is providing that will be shown.
+    optional int32 num_app_provided_direct_targets = 5;
+    // The number of app targets the calling app is providing that will be shown.
+    optional int32 num_app_provided_app_targets = 6;
+    // True if the share originates from the workprofile
+    optional bool is_workprofile = 7;
+
+    enum SharesheetPreviewType {  // Constants from ChooserActivity.java
+        CONTENT_PREVIEW_IMAGE = 1;  // The preview shown in the sharesheet is an image.
+        CONTENT_PREVIEW_FILE = 2;  // The preview shown in the sharesheet is a file.
+        CONTENT_PREVIEW_TEXT = 3;  // The preview shown in the sharesheet is text.
+    }
+    // How the sharesheet preview is presented.
+    optional SharesheetPreviewType previewType = 8;
+
+    enum ResolverActivityIntent { // Intents handled by ResolverActivity.java
+        INTENT_DEFAULT = 0;
+        INTENT_ACTION_VIEW = 1;
+        INTENT_ACTION_EDIT = 2;
+        INTENT_ACTION_SEND = 3;
+        INTENT_ACTION_SENDTO = 4;
+        INTENT_ACTION_SEND_MULTIPLE = 5;
+        INTENT_ACTION_IMAGE_CAPTURE = 6;
+        INTENT_ACTION_MAIN = 7;
+    }
+    // The intent being processed (only SEND and SEND_MULTIPLE are system sharesheet)
+    optional ResolverActivityIntent intentType = 9;
+}
+
+/**
+ * Reports a ranking selection event.
+ *
+ * Logged from:
+ *   frameworks/base/core/java/com/android/internal/app/ChooserActivity.java (sharesheet)
+ */
+message RankingSelected {
+    // The event_id (as for UiEventReported).
+    optional int32 event_id = 1;
+    // The relevant app's package name (can be source or picked package).
+    optional string package_name = 2;
+    // An identifier to tie together multiple logs relating to the same share event.
+    optional int32 instance_id = 3;
+    // Which of the ranked targets got picked, default starting position 0.
+    optional int32 position_picked = 4;
+}
diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h
index aeca2a5..154750e 100644
--- a/cmds/statsd/src/state/StateTracker.h
+++ b/cmds/statsd/src/state/StateTracker.h
@@ -30,7 +30,7 @@
 
 class StateTracker : public virtual RefBase {
 public:
-    StateTracker(const int32_t atomId, const util::StateAtomFieldOptions& stateAtomInfo);
+    StateTracker(const int32_t atomId, const android::util::StateAtomFieldOptions& stateAtomInfo);
 
     virtual ~StateTracker(){};
 
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index aec0956..ade25d6 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -23,24 +23,26 @@
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 #include "guardrail/StatsdStats.h"
 
+using android::util::ProtoOutputStream;
+
 namespace android {
 namespace os {
 namespace statsd {
 
 void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& values,
-                                 util::ProtoOutputStream* protoOutput);
+                                 ProtoOutputStream* protoOutput);
 void writeDimensionToProto(const HashableDimensionKey& dimension, std::set<string> *str_set,
-                           util::ProtoOutputStream* protoOutput);
+                           ProtoOutputStream* protoOutput);
 
 void writeDimensionLeafNodesToProto(const HashableDimensionKey& dimension,
                                     const int dimensionLeafFieldId,
                                     std::set<string> *str_set,
-                                    util::ProtoOutputStream* protoOutput);
+                                    ProtoOutputStream* protoOutput);
 
 void writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers,
-                               util::ProtoOutputStream* protoOutput);
+                               ProtoOutputStream* protoOutput);
 
-void writeStateToProto(const FieldValue& state, util::ProtoOutputStream* protoOutput);
+void writeStateToProto(const FieldValue& state, ProtoOutputStream* protoOutput);
 
 // Convert the TimeUnit enum to the bucket size in millis with a guardrail on
 // bucket size.
@@ -73,14 +75,14 @@
 
 // Helper function to write PulledAtomStats to ProtoOutputStream
 void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>& pair,
-                              util::ProtoOutputStream* protoOutput);
+                              ProtoOutputStream* protoOutput);
 
 // Helper function to write AtomMetricStats to ProtoOutputStream
 void writeAtomMetricStatsToStream(const std::pair<int64_t, StatsdStats::AtomMetricStats> &pair,
-                                  util::ProtoOutputStream *protoOutput);
+                                  ProtoOutputStream *protoOutput);
 
 template<class T>
-bool parseProtoOutputStream(util::ProtoOutputStream& protoOutput, T* message) {
+bool parseProtoOutputStream(ProtoOutputStream& protoOutput, T* message) {
     std::string pbBytes;
     sp<android::util::ProtoReader> reader = protoOutput.data();
     while (reader->readBuffer() != NULL) {
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index 81d6f72..d6498f4 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -21,7 +21,7 @@
 #include "logd/LogEvent.h"
 #include "packages/UidMap.h"
 #include "storage/StorageManager.h"
-#include "statslog.h"
+#include "statslog_statsdtest.h"
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
index af6de06..a49c18f 100644
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ b/cmds/statsd/tests/UidMap_test.cpp
@@ -18,7 +18,7 @@
 #include "guardrail/StatsdStats.h"
 #include "logd/LogEvent.h"
 #include "hash.h"
-#include "statslog.h"
+#include "statslog_statsdtest.h"
 #include "statsd_test_util.h"
 
 #include <android/util/ProtoOutputStream.h>
@@ -49,7 +49,7 @@
 //    StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
 //                        [](const ConfigKey& key) { return true; },
 //                        [](const int&, const vector<int64_t>&) {return true;});
-//    LogEvent addEvent(android::util::ISOLATED_UID_CHANGED, 1);
+//    LogEvent addEvent(util::ISOLATED_UID_CHANGED, 1);
 //    addEvent.write(100);  // parent UID
 //    addEvent.write(101);  // isolated UID
 //    addEvent.write(1);    // Indicates creation.
@@ -60,7 +60,7 @@
 //    p.OnLogEvent(&addEvent);
 //    EXPECT_EQ(100, m->getHostUidOrSelf(101));
 //
-//    LogEvent removeEvent(android::util::ISOLATED_UID_CHANGED, 1);
+//    LogEvent removeEvent(util::ISOLATED_UID_CHANGED, 1);
 //    removeEvent.write(100);  // parent UID
 //    removeEvent.write(101);  // isolated UID
 //    removeEvent.write(0);    // Indicates removal.
diff --git a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
index e0eebef..9c6965d 100644
--- a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
@@ -39,7 +39,7 @@
     countMetric->set_id(123456);
     countMetric->set_what(wakelockAcquireMatcher.id());
     *countMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
-            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
     countMetric->set_bucket(FIVE_MINUTES);
 
     auto alert = config.add_alert();
@@ -83,12 +83,12 @@
     std::vector<int> attributionUids5 = {222};
     std::vector<string> attributionTags5 = {"GMSCoreModule1"};
 
-    FieldValue fieldValue1(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
+    FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
                            Value((int32_t)111));
     HashableDimensionKey whatKey1({fieldValue1});
     MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
 
-    FieldValue fieldValue2(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
+    FieldValue fieldValue2(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
                            Value((int32_t)222));
     HashableDimensionKey whatKey2({fieldValue2});
     MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
@@ -194,7 +194,7 @@
     std::vector<int> attributionUids2 = {111, 222};
     std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
 
-    FieldValue fieldValue1(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
+    FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
                            Value((int32_t)111));
     HashableDimensionKey whatKey1({fieldValue1});
     MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
diff --git a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
index fe45b55..4f9f315 100644
--- a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
@@ -45,7 +45,7 @@
 
     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
     FieldMatcher dimensions = CreateAttributionUidDimensions(
-            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
     dimensions.add_child()->set_field(3);  // The wakelock tag is set in field 3 of the wakelock.
     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
     holdingWakelockPredicate.mutable_simple_predicate()->set_count_nesting(nesting);
@@ -57,7 +57,7 @@
     durationMetric->set_condition(screenIsOffPredicate.id());
     durationMetric->set_aggregation_type(aggregationType);
     *durationMetric->mutable_dimensions_in_what() =
-        CreateAttributionUidDimensions(android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+        CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
     durationMetric->set_bucket(FIVE_MINUTES);
 
     auto alert = config.add_alert();
@@ -79,13 +79,13 @@
 std::vector<string> attributionTags3 = {"GMSCoreModule1"};
 
 MetricDimensionKey dimensionKey1(
-        HashableDimensionKey({FieldValue(Field(android::util::WAKELOCK_STATE_CHANGED,
+        HashableDimensionKey({FieldValue(Field(util::WAKELOCK_STATE_CHANGED,
                                                (int32_t)0x02010101),
                                          Value((int32_t)111))}),
         DEFAULT_DIMENSION_KEY);
 
 MetricDimensionKey dimensionKey2(
-    HashableDimensionKey({FieldValue(Field(android::util::WAKELOCK_STATE_CHANGED,
+    HashableDimensionKey({FieldValue(Field(util::WAKELOCK_STATE_CHANGED,
                                            (int32_t)0x02010101), Value((int32_t)222))}),
     DEFAULT_DIMENSION_KEY);
 
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
index 9e743f7..52229e2 100644
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
@@ -48,7 +48,7 @@
     countMetric->set_what(wakelockAcquireMatcher.id());
     *countMetric->mutable_dimensions_in_what() =
         CreateAttributionUidAndTagDimensions(
-            android::util::WAKELOCK_STATE_CHANGED, {position});
+            util::WAKELOCK_STATE_CHANGED, {position});
     countMetric->set_bucket(FIVE_MINUTES);
     return config;
 }
@@ -164,7 +164,7 @@
 
     auto data = countMetrics.data(0);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
+                                          util::WAKELOCK_STATE_CHANGED, 111, "App1");
     EXPECT_EQ(data.bucket_info_size(), 2);
     EXPECT_EQ(data.bucket_info(0).count(), 2);
     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
@@ -176,7 +176,7 @@
 
     data = countMetrics.data(1);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          android::util::WAKELOCK_STATE_CHANGED, 222,
+                                          util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
     EXPECT_EQ(data.bucket_info_size(), 2);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
@@ -188,7 +188,7 @@
 
     data = countMetrics.data(2);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          android::util::WAKELOCK_STATE_CHANGED, 222,
+                                          util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule3");
     EXPECT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
@@ -198,7 +198,7 @@
 
     data = countMetrics.data(3);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          android::util::WAKELOCK_STATE_CHANGED, 444,
+                                          util::WAKELOCK_STATE_CHANGED, 444,
                                           "GMSCoreModule2");
     EXPECT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
@@ -277,7 +277,7 @@
 
     auto data = countMetrics.data(0);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          android::util::WAKELOCK_STATE_CHANGED, 222,
+                                          util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
     EXPECT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
@@ -289,26 +289,26 @@
     EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
-    ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 222);
+    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 222);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          android::util::WAKELOCK_STATE_CHANGED, 222,
+                                          util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
-    ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 333);
+    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 333);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
+                                          util::WAKELOCK_STATE_CHANGED, 333, "App3");
     EXPECT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
     EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
 
     data = countMetrics.data(2);
-    ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 444);
+    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 444);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          android::util::WAKELOCK_STATE_CHANGED, 444,
+                                          util::WAKELOCK_STATE_CHANGED, 444,
                                           "GMSCoreModule2");
-    ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 222);
+    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 222);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          android::util::WAKELOCK_STATE_CHANGED, 222,
+                                          util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
     EXPECT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
@@ -317,31 +317,31 @@
     EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(3);
-    ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111);
+    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
-    ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 222);
+                                          util::WAKELOCK_STATE_CHANGED, 111, "App1");
+    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 222);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          android::util::WAKELOCK_STATE_CHANGED, 222,
+                                          util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
-    ValidateUidDimension(data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 333);
+    ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
-                                          android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
+                                          util::WAKELOCK_STATE_CHANGED, 333, "App3");
     EXPECT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(4);
-    ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111);
+    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
-    ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 333);
+                                          util::WAKELOCK_STATE_CHANGED, 111, "App1");
+    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 333);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
-    ValidateUidDimension(data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 222);
+                                          util::WAKELOCK_STATE_CHANGED, 333, "App3");
+    ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 222);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
-                                          android::util::WAKELOCK_STATE_CHANGED, 222,
+                                          util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
     EXPECT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
@@ -349,16 +349,16 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(5);
-    ValidateUidDimension(data.dimensions_in_what(), 0, android::util::WAKELOCK_STATE_CHANGED, 111);
+    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          android::util::WAKELOCK_STATE_CHANGED, 111, "App1");
-    ValidateUidDimension(data.dimensions_in_what(), 1, android::util::WAKELOCK_STATE_CHANGED, 444);
+                                          util::WAKELOCK_STATE_CHANGED, 111, "App1");
+    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 444);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          android::util::WAKELOCK_STATE_CHANGED, 444,
+                                          util::WAKELOCK_STATE_CHANGED, 444,
                                           "GMSCoreModule2");
-    ValidateUidDimension(data.dimensions_in_what(), 2, android::util::WAKELOCK_STATE_CHANGED, 333);
+    ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
-                                          android::util::WAKELOCK_STATE_CHANGED, 333, "App3");
+                                          util::WAKELOCK_STATE_CHANGED, 333, "App3");
     EXPECT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
diff --git a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp b/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
index 102bb1e..16adbdd 100644
--- a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
@@ -39,7 +39,7 @@
     countMetric->set_id(123456);
     countMetric->set_what(wakelockAcquireMatcher.id());
     *countMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
-            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
     countMetric->set_bucket(FIVE_MINUTES);
 
     auto alert = config.add_alert();
@@ -74,12 +74,12 @@
     std::vector<int> attributionUids1 = {111};
     std::vector<string> attributionTags1 = {"App1"};
 
-    FieldValue fieldValue1(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
+    FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
                            Value((int32_t)111));
     HashableDimensionKey whatKey1({fieldValue1});
     MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
 
-    FieldValue fieldValue2(Field(android::util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
+    FieldValue fieldValue2(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
                            Value((int32_t)222));
     HashableDimensionKey whatKey2({fieldValue2});
     MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
diff --git a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
index 2cd7854..69326cb 100644
--- a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
@@ -365,7 +365,7 @@
     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
 
     auto appCrashMatcher =
-            CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", android::util::APP_CRASH_OCCURRED);
+            CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
     *config.add_atom_matcher() = appCrashMatcher;
 
     auto state = CreateUidProcessState();
@@ -381,7 +381,7 @@
     MetricStateLink* stateLink = countMetric->add_state_link();
     stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
     auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(android::util::APP_CRASH_OCCURRED, {1 /*uid*/});
+    *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
     auto fieldsInState = stateLink->mutable_fields_in_state();
     *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
 
@@ -551,7 +551,7 @@
     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
 
     auto appCrashMatcher =
-            CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", android::util::APP_CRASH_OCCURRED);
+            CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
     *config.add_atom_matcher() = appCrashMatcher;
 
     auto state1 = CreateScreenStateWithOnOffMap();
@@ -571,7 +571,7 @@
     MetricStateLink* stateLink = countMetric->add_state_link();
     stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
     auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(android::util::APP_CRASH_OCCURRED, {1 /*uid*/});
+    *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
     auto fieldsInState = stateLink->mutable_fields_in_state();
     *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
 
diff --git a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
index b586b06..ae2a0f5 100644
--- a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
@@ -456,14 +456,14 @@
 
     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
     // The predicate is dimensioning by first attribution node by uid.
-    FieldMatcher dimensions = CreateAttributionUidDimensions(android::util::WAKELOCK_STATE_CHANGED,
+    FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
                                                              {Position::FIRST});
     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
     *config.add_predicate() = holdingWakelockPredicate;
 
     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
-            CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
+            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
     *config.add_predicate() = isInBackgroundPredicate;
 
     auto durationMetric = config.add_duration_metric();
@@ -473,17 +473,17 @@
     durationMetric->set_aggregation_type(DurationMetric::SUM);
     // The metric is dimensioning by first attribution node and only by uid.
     *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
-            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
     durationMetric->set_bucket(FIVE_MINUTES);
 
     // Links between wakelock state atom and condition of app is in background.
     auto links = durationMetric->add_links();
     links->set_condition(isInBackgroundPredicate.id());
     auto dimensionWhat = links->mutable_fields_in_what();
-    dimensionWhat->set_field(android::util::WAKELOCK_STATE_CHANGED);
+    dimensionWhat->set_field(util::WAKELOCK_STATE_CHANGED);
     dimensionWhat->add_child()->set_field(1);  // uid field.
     *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
-            android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
+            util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
 
     ConfigKey cfgKey;
     uint64_t bucketStartTimeNs = 10000000000;
@@ -536,7 +536,7 @@
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    android::util::WAKELOCK_STATE_CHANGED, appUid);
+                                    util::WAKELOCK_STATE_CHANGED, appUid);
     // Validate bucket info.
     EXPECT_EQ(1, data.bucket_info_size());
 
@@ -558,14 +558,14 @@
 
     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
     // The predicate is dimensioning by first attribution node by uid.
-    FieldMatcher dimensions = CreateAttributionUidDimensions(android::util::WAKELOCK_STATE_CHANGED,
+    FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
                                                              {Position::FIRST});
     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
     *config.add_predicate() = holdingWakelockPredicate;
 
     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
-            CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
+            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
     *config.add_predicate() = isInBackgroundPredicate;
 
     auto durationMetric = config.add_duration_metric();
@@ -575,17 +575,17 @@
     durationMetric->set_aggregation_type(DurationMetric::SUM);
     // The metric is dimensioning by first attribution node and only by uid.
     *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
-            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
     durationMetric->set_bucket(FIVE_MINUTES);
 
     // Links between wakelock state atom and condition of app is in background.
     auto links = durationMetric->add_links();
     links->set_condition(isInBackgroundPredicate.id());
     auto dimensionWhat = links->mutable_fields_in_what();
-    dimensionWhat->set_field(android::util::WAKELOCK_STATE_CHANGED);
+    dimensionWhat->set_field(util::WAKELOCK_STATE_CHANGED);
     dimensionWhat->add_child()->set_field(1);  // uid field.
     *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
-            android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
+            util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
 
     auto metric_activation1 = config.add_metric_activation();
     metric_activation1->set_metric_id(durationMetric->id());
@@ -694,7 +694,7 @@
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    android::util::WAKELOCK_STATE_CHANGED, appUid);
+                                    util::WAKELOCK_STATE_CHANGED, appUid);
     // Validate bucket info.
     EXPECT_EQ(2, data.bucket_info_size());
 
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index 594c1e6..ca4de6d 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -32,7 +32,7 @@
 namespace {
 
 const int64_t metricId = 123456;
-const int32_t ATOM_TAG = android::util::SUBSYSTEM_SLEEP_STATE;
+const int32_t ATOM_TAG = util::SUBSYSTEM_SLEEP_STATE;
 
 StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,
                                 bool useCondition = true) {
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
index 6e3d93a..81e1c05 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
@@ -35,12 +35,12 @@
     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
 
-    auto atomMatcher = CreateSimpleAtomMatcher("", android::util::APP_START_OCCURRED);
+    auto atomMatcher = CreateSimpleAtomMatcher("", util::APP_START_OCCURRED);
     *config.add_atom_matcher() = atomMatcher;
 
     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
-        CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
+        CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
     *config.add_predicate() = isInBackgroundPredicate;
 
     auto gaugeMetric = config.add_gauge_metric();
@@ -50,21 +50,21 @@
     gaugeMetric->mutable_gauge_fields_filter()->set_include_all(false);
     gaugeMetric->set_sampling_type(sampling_type);
     auto fieldMatcher = gaugeMetric->mutable_gauge_fields_filter()->mutable_fields();
-    fieldMatcher->set_field(android::util::APP_START_OCCURRED);
+    fieldMatcher->set_field(util::APP_START_OCCURRED);
     fieldMatcher->add_child()->set_field(3);  // type (enum)
     fieldMatcher->add_child()->set_field(4);  // activity_name(str)
     fieldMatcher->add_child()->set_field(7);  // activity_start_msec(int64)
     *gaugeMetric->mutable_dimensions_in_what() =
-        CreateDimensions(android::util::APP_START_OCCURRED, {1 /* uid field */ });
+        CreateDimensions(util::APP_START_OCCURRED, {1 /* uid field */ });
     gaugeMetric->set_bucket(FIVE_MINUTES);
 
     auto links = gaugeMetric->add_links();
     links->set_condition(isInBackgroundPredicate.id());
     auto dimensionWhat = links->mutable_fields_in_what();
-    dimensionWhat->set_field(android::util::APP_START_OCCURRED);
+    dimensionWhat->set_field(util::APP_START_OCCURRED);
     dimensionWhat->add_child()->set_field(1);  // uid field.
     auto dimensionCondition = links->mutable_fields_in_condition();
-    dimensionCondition->set_field(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
+    dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
     dimensionCondition->add_child()->set_field(1);  // uid field.
     return config;
 }
@@ -74,7 +74,7 @@
         AppStartOccurred::TransitionType type, const string& activity_name,
         const string& calling_pkg_name, const bool is_instant_app, int64_t activity_start_msec) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::APP_START_OCCURRED);
+    AStatsEvent_setAtomId(statsEvent, util::APP_START_OCCURRED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, uid);
@@ -173,7 +173,7 @@
         EXPECT_EQ(2, gaugeMetrics.data_size());
 
         auto data = gaugeMetrics.data(0);
-        EXPECT_EQ(android::util::APP_START_OCCURRED, data.dimensions_in_what().field());
+        EXPECT_EQ(util::APP_START_OCCURRED, data.dimensions_in_what().field());
         EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
         EXPECT_EQ(1 /* uid field */,
                   data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -272,7 +272,7 @@
 
         data = gaugeMetrics.data(1);
 
-        EXPECT_EQ(data.dimensions_in_what().field(), android::util::APP_START_OCCURRED);
+        EXPECT_EQ(data.dimensions_in_what().field(), util::APP_START_OCCURRED);
         EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
         EXPECT_EQ(1 /* uid field */,
                   data.dimensions_in_what().value_tuple().dimensions_value(0).field());
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
index 1dd90e2..f1e2744 100644
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
@@ -45,7 +45,7 @@
     countMetric->set_what(crashMatcher.id());
     countMetric->set_bucket(FIVE_MINUTES);
     countMetric->mutable_dimensions_in_what()->set_field(
-        android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
 
     auto metric_activation1 = config.add_metric_activation();
@@ -79,7 +79,7 @@
     countMetric->set_what(crashMatcher.id());
     countMetric->set_bucket(FIVE_MINUTES);
     countMetric->mutable_dimensions_in_what()->set_field(
-        android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
 
     auto metric_activation1 = config.add_metric_activation();
@@ -117,7 +117,7 @@
     countMetric->set_what(crashMatcher.id());
     countMetric->set_bucket(FIVE_MINUTES);
     countMetric->mutable_dimensions_in_what()->set_field(
-        android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
 
     auto metric_activation1 = config.add_metric_activation();
@@ -153,7 +153,7 @@
     countMetric->set_what(crashMatcher.id());
     countMetric->set_bucket(FIVE_MINUTES);
     countMetric->mutable_dimensions_in_what()->set_field(
-        android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
 
     auto metric_activation1 = config.add_metric_activation();
@@ -194,7 +194,7 @@
     countMetric->set_what(crashMatcher.id());
     countMetric->set_bucket(FIVE_MINUTES);
     countMetric->mutable_dimensions_in_what()->set_field(
-        android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
 
     int64_t metricId2 = 234567;
@@ -203,7 +203,7 @@
     countMetric->set_what(foregroundMatcher.id());
     countMetric->set_bucket(FIVE_MINUTES);
     countMetric->mutable_dimensions_in_what()->set_field(
-        android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
+        util::ACTIVITY_FOREGROUND_STATE_CHANGED);
     countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
 
     auto metric_activation1 = config.add_metric_activation();
@@ -398,7 +398,7 @@
     EXPECT_EQ(4, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -409,7 +409,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -420,7 +420,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -433,7 +433,7 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(3);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -706,7 +706,7 @@
     EXPECT_EQ(5, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -717,7 +717,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -728,7 +728,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -741,7 +741,7 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(3);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -754,7 +754,7 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(4);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1040,7 +1040,7 @@
     EXPECT_EQ(5, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1051,7 +1051,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1062,7 +1062,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1075,7 +1075,7 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(3);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1088,7 +1088,7 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(4);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1264,7 +1264,7 @@
     EXPECT_EQ(3, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1275,7 +1275,7 @@
     EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1286,7 +1286,7 @@
     EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1704,7 +1704,7 @@
     EXPECT_EQ(5, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1715,7 +1715,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1726,7 +1726,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1739,7 +1739,7 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(3);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1752,7 +1752,7 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(4);
-    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1769,7 +1769,7 @@
     EXPECT_EQ(5, countMetrics.data_size());
 
     data = countMetrics.data(0);
-    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1780,7 +1780,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1791,7 +1791,7 @@
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1804,7 +1804,7 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(3);
-    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -1817,7 +1817,7 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(4);
-    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index e8fb523..f0df2c6 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -48,12 +48,12 @@
     auto isSyncingPredicate = CreateIsSyncingPredicate();
     auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
     *syncDimension = CreateAttributionUidDimensions(
-        android::util::SYNC_STATE_CHANGED, {Position::FIRST});
+        util::SYNC_STATE_CHANGED, {Position::FIRST});
     syncDimension->add_child()->set_field(2 /* name field*/);
 
     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
-        CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
+        CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
 
     *config.add_predicate() = screenIsOffPredicate;
     *config.add_predicate() = isSyncingPredicate;
@@ -72,26 +72,26 @@
     countMetric->set_condition(combinationPredicate->id());
     // The metric is dimensioning by uid only.
     *countMetric->mutable_dimensions_in_what() =
-        CreateDimensions(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1});
+        CreateDimensions(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1});
     countMetric->set_bucket(FIVE_MINUTES);
 
     // Links between crash atom and condition of app is in syncing.
     auto links = countMetric->add_links();
     links->set_condition(isSyncingPredicate.id());
     auto dimensionWhat = links->mutable_fields_in_what();
-    dimensionWhat->set_field(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    dimensionWhat->set_field(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     dimensionWhat->add_child()->set_field(1);  // uid field.
     *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
-            android::util::SYNC_STATE_CHANGED, {Position::FIRST});
+            util::SYNC_STATE_CHANGED, {Position::FIRST});
 
     // Links between crash atom and condition of app is in background.
     links = countMetric->add_links();
     links->set_condition(isInBackgroundPredicate.id());
     dimensionWhat = links->mutable_fields_in_what();
-    dimensionWhat->set_field(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    dimensionWhat->set_field(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     dimensionWhat->add_child()->set_field(1);  // uid field.
     auto dimensionCondition = links->mutable_fields_in_condition();
-    dimensionCondition->set_field(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
+    dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
     dimensionCondition->add_child()->set_field(1);  // uid field.
     return config;
 }
@@ -211,7 +211,7 @@
     EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
     auto data = reports.reports(0).metrics(0).count_metrics().data(0);
     // Validate dimension value.
-    EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
     // Uid field.
     EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
@@ -332,7 +332,7 @@
     EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(1).count(), 3);
     auto data = reports.reports(0).metrics(0).count_metrics().data(0);
     // Validate dimension value.
-    EXPECT_EQ(data.dimensions_in_what().field(), android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
     // Uid field.
     EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index b975907..371a346 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -73,7 +73,7 @@
     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
 
     auto pulledAtomMatcher =
-            CreateSimpleAtomMatcher("TestMatcher", android::util::SUBSYSTEM_SLEEP_STATE);
+            CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
     *config.add_atom_matcher() = pulledAtomMatcher;
     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
@@ -82,9 +82,9 @@
     valueMetric->set_id(123456);
     valueMetric->set_what(pulledAtomMatcher.id());
     *valueMetric->mutable_value_field() =
-            CreateDimensions(android::util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
     *valueMetric->mutable_dimensions_in_what() =
-            CreateDimensions(android::util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
+            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
     valueMetric->set_bucket(FIVE_MINUTES);
     valueMetric->set_min_bucket_size_nanos(minTime);
     valueMetric->set_use_absolute_value_on_reset(true);
@@ -96,7 +96,7 @@
     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
 
     auto pulledAtomMatcher =
-                CreateSimpleAtomMatcher("TestMatcher", android::util::SUBSYSTEM_SLEEP_STATE);
+                CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
     *config.add_atom_matcher() = pulledAtomMatcher;
     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
@@ -106,7 +106,7 @@
     gaugeMetric->set_what(pulledAtomMatcher.id());
     gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
     *gaugeMetric->mutable_dimensions_in_what() =
-            CreateDimensions(android::util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
+            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
     gaugeMetric->set_bucket(FIVE_MINUTES);
     gaugeMetric->set_min_bucket_size_nanos(minTime);
     return config;
@@ -218,7 +218,7 @@
 TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
     shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     service->mPullerManager->RegisterPullAtomCallback(
-            /*uid=*/0, android::util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
+            /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
             SharedRefBase::make<FakeSubsystemSleepCallback>());
     // Partial buckets don't occur when app is first installed.
     service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
@@ -239,7 +239,7 @@
 TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) {
     shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     service->mPullerManager->RegisterPullAtomCallback(
-            /*uid=*/0, android::util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
+            /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
             SharedRefBase::make<FakeSubsystemSleepCallback>());
     // Partial buckets don't occur when app is first installed.
     service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index a87bb71..a5ef733 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -37,7 +37,7 @@
     StatsdConfig config;
     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
     auto pulledAtomMatcher =
-            CreateSimpleAtomMatcher("TestMatcher", android::util::SUBSYSTEM_SLEEP_STATE);
+            CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
     *config.add_atom_matcher() = pulledAtomMatcher;
     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
@@ -52,9 +52,9 @@
         valueMetric->set_condition(screenIsOffPredicate.id());
     }
     *valueMetric->mutable_value_field() =
-            CreateDimensions(android::util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
+            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
     *valueMetric->mutable_dimensions_in_what() =
-            CreateDimensions(android::util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
+            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
     valueMetric->set_bucket(FIVE_MINUTES);
     valueMetric->set_use_absolute_value_on_reset(true);
     valueMetric->set_skip_zero_diff_output(false);
@@ -73,7 +73,7 @@
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                              SharedRefBase::make<FakeSubsystemSleepCallback>(),
-                                             android::util::SUBSYSTEM_SLEEP_STATE);
+                                             util::SUBSYSTEM_SLEEP_STATE);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
@@ -142,7 +142,7 @@
     EXPECT_GT((int)valueMetrics.data_size(), 1);
 
     auto data = valueMetrics.data(0);
-    EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
+    EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -177,7 +177,7 @@
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                              SharedRefBase::make<FakeSubsystemSleepCallback>(),
-                                             android::util::SUBSYSTEM_SLEEP_STATE);
+                                             util::SUBSYSTEM_SLEEP_STATE);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
@@ -250,7 +250,7 @@
     EXPECT_GT((int)valueMetrics.data_size(), 1);
 
     auto data = valueMetrics.data(0);
-    EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
+    EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -289,7 +289,7 @@
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                              SharedRefBase::make<FakeSubsystemSleepCallback>(),
-                                             android::util::SUBSYSTEM_SLEEP_STATE);
+                                             util::SUBSYSTEM_SLEEP_STATE);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
@@ -353,7 +353,7 @@
     EXPECT_GT((int)valueMetrics.data_size(), 0);
 
     auto data = valueMetrics.data(0);
-    EXPECT_EQ(android::util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
+    EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
     EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
@@ -383,7 +383,7 @@
     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
 
     auto pulledAtomMatcher =
-            CreateSimpleAtomMatcher("TestMatcher", android::util::SUBSYSTEM_SLEEP_STATE);
+            CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
     *config.add_atom_matcher() = pulledAtomMatcher;
 
     auto screenState = CreateScreenState();
@@ -396,7 +396,7 @@
     valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
     valueMetric->set_what(pulledAtomMatcher.id());
     *valueMetric->mutable_value_field() =
-            CreateDimensions(android::util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
+            CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
     valueMetric->add_slice_by_state(screenState.id());
     valueMetric->set_max_pull_delay_sec(INT_MAX);
 
@@ -437,7 +437,7 @@
     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
 
     auto cpuTimePerUidMatcher =
-            CreateSimpleAtomMatcher("CpuTimePerUidMatcher", android::util::CPU_TIME_PER_UID);
+            CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
     *config.add_atom_matcher() = cpuTimePerUidMatcher;
 
     auto uidProcessState = CreateUidProcessState();
@@ -450,14 +450,14 @@
     valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
     valueMetric->set_what(cpuTimePerUidMatcher.id());
     *valueMetric->mutable_value_field() =
-            CreateDimensions(android::util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
+            CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
     *valueMetric->mutable_dimensions_in_what() =
-            CreateDimensions(android::util::CPU_TIME_PER_UID, {1 /* uid */});
+            CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
     valueMetric->add_slice_by_state(uidProcessState.id());
     MetricStateLink* stateLink = valueMetric->add_state_link();
     stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
     auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(android::util::CPU_TIME_PER_UID, {1 /* uid */});
+    *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
     auto fieldsInState = stateLink->mutable_fields_in_state();
     *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
     valueMetric->set_max_pull_delay_sec(INT_MAX);
@@ -497,7 +497,7 @@
     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
 
     auto cpuTimePerUidMatcher =
-            CreateSimpleAtomMatcher("CpuTimePerUidMatcher", android::util::CPU_TIME_PER_UID);
+            CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
     *config.add_atom_matcher() = cpuTimePerUidMatcher;
 
     auto uidProcessState = CreateUidProcessState();
@@ -510,12 +510,12 @@
     valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
     valueMetric->set_what(cpuTimePerUidMatcher.id());
     *valueMetric->mutable_value_field() =
-            CreateDimensions(android::util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
+            CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
     valueMetric->add_slice_by_state(uidProcessState.id());
     MetricStateLink* stateLink = valueMetric->add_state_link();
     stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
     auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(android::util::CPU_TIME_PER_UID, {1 /* uid */});
+    *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
     auto fieldsInState = stateLink->mutable_fields_in_state();
     *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
     valueMetric->set_max_pull_delay_sec(INT_MAX);
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
index ddd8f95..80f3c28 100644
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
@@ -42,7 +42,7 @@
     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
     // The predicate is dimensioning by any attribution node and both by uid and tag.
     FieldMatcher dimensions = CreateAttributionUidAndTagDimensions(
-            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST, Position::LAST});
+            util::WAKELOCK_STATE_CHANGED, {Position::FIRST, Position::LAST});
     // Also slice by the wakelock tag
     dimensions.add_child()->set_field(3);  // The wakelock tag is set in field 3 of the wakelock.
     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
@@ -56,7 +56,7 @@
     // The metric is dimensioning by first attribution node and only by uid.
     *durationMetric->mutable_dimensions_in_what() =
         CreateAttributionUidDimensions(
-            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
     durationMetric->set_bucket(FIVE_MINUTES);
     return config;
 }
@@ -142,7 +142,7 @@
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    android::util::WAKELOCK_STATE_CHANGED, 111);
+                                    util::WAKELOCK_STATE_CHANGED, 111);
     // Validate bucket info.
     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
     data = reports.reports(0).metrics(0).duration_metrics().data(0);
@@ -178,7 +178,7 @@
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    android::util::WAKELOCK_STATE_CHANGED, 111);
+                                    util::WAKELOCK_STATE_CHANGED, 111);
     // Two output buckets.
     // The wakelock holding interval in the 1st bucket starts from the screen off event and to
     // the end of the 1st bucket.
@@ -228,7 +228,7 @@
     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    android::util::WAKELOCK_STATE_CHANGED, 111);
+                                    util::WAKELOCK_STATE_CHANGED, 111);
     // The last wakelock holding spans 4 buckets.
     EXPECT_EQ((unsigned long long)data.bucket_info(2).duration_nanos(), bucketSizeNs - 100);
     EXPECT_EQ((unsigned long long)data.bucket_info(3).duration_nanos(), bucketSizeNs);
@@ -293,7 +293,7 @@
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    android::util::WAKELOCK_STATE_CHANGED, 111);
+                                    util::WAKELOCK_STATE_CHANGED, 111);
     // The max is acquire event for wl1 to screen off start.
     EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
 }
@@ -337,7 +337,7 @@
     EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    android::util::WAKELOCK_STATE_CHANGED, 111);
+                                    util::WAKELOCK_STATE_CHANGED, 111);
     // The last wakelock holding spans 4 buckets.
     EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 3 * bucketSizeNs);
     EXPECT_EQ((unsigned long long)data.bucket_info(1).start_bucket_elapsed_nanos(),
diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp
index f21954f2..15425d8 100644
--- a/cmds/statsd/tests/external/puller_util_test.cpp
+++ b/cmds/statsd/tests/external/puller_util_test.cpp
@@ -22,7 +22,7 @@
 
 #include "../metrics/metrics_test_helper.h"
 #include "stats_event.h"
-#include "statslog.h"
+#include "statslog_statsdtest.h"
 
 #ifdef __ANDROID__
 
@@ -39,9 +39,9 @@
  * Test merge isolated and host uid
  */
 namespace {
-int uidAtomTagId = android::util::CPU_CLUSTER_TIME;
+int uidAtomTagId = util::CPU_CLUSTER_TIME;
 const vector<int> uidAdditiveFields = {3};
-int nonUidAtomTagId = android::util::SYSTEM_UPTIME;
+int nonUidAtomTagId = util::SYSTEM_UPTIME;
 int timestamp = 1234;
 int isolatedUid = 30;
 int isolatedAdditiveData = 31;
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
index 2a43d9b..00e8397 100644
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 #include "src/guardrail/StatsdStats.h"
-#include "statslog.h"
+#include "statslog_statsdtest.h"
 #include "tests/statsd_test_util.h"
 
 #include <gtest/gtest.h>
@@ -222,11 +222,11 @@
     StatsdStats stats;
     time_t now = time(nullptr);
     // old event, we get it from the stats buffer. should be ignored.
-    stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, 1000);
+    stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, 1000);
 
-    stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, now + 1);
-    stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, now + 2);
-    stats.noteAtomLogged(android::util::APP_CRASH_OCCURRED, now + 3);
+    stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 1);
+    stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 2);
+    stats.noteAtomLogged(util::APP_CRASH_OCCURRED, now + 3);
 
     vector<uint8_t> output;
     stats.dumpStats(&output, false);
@@ -239,10 +239,10 @@
     bool dropboxAtomGood = false;
 
     for (const auto& atomStats : report.atom_stats()) {
-        if (atomStats.tag() == android::util::SENSOR_STATE_CHANGED && atomStats.count() == 3) {
+        if (atomStats.tag() == util::SENSOR_STATE_CHANGED && atomStats.count() == 3) {
             sensorAtomGood = true;
         }
-        if (atomStats.tag() == android::util::APP_CRASH_OCCURRED && atomStats.count() == 1) {
+        if (atomStats.tag() == util::APP_CRASH_OCCURRED && atomStats.count() == 1) {
             dropboxAtomGood = true;
         }
     }
@@ -287,21 +287,21 @@
 TEST(StatsdStatsTest, TestPullAtomStats) {
     StatsdStats stats;
 
-    stats.updateMinPullIntervalSec(android::util::DISK_SPACE, 3333L);
-    stats.updateMinPullIntervalSec(android::util::DISK_SPACE, 2222L);
-    stats.updateMinPullIntervalSec(android::util::DISK_SPACE, 4444L);
+    stats.updateMinPullIntervalSec(util::DISK_SPACE, 3333L);
+    stats.updateMinPullIntervalSec(util::DISK_SPACE, 2222L);
+    stats.updateMinPullIntervalSec(util::DISK_SPACE, 4444L);
 
-    stats.notePull(android::util::DISK_SPACE);
-    stats.notePullTime(android::util::DISK_SPACE, 1111L);
-    stats.notePullDelay(android::util::DISK_SPACE, 1111L);
-    stats.notePull(android::util::DISK_SPACE);
-    stats.notePullTime(android::util::DISK_SPACE, 3333L);
-    stats.notePullDelay(android::util::DISK_SPACE, 3335L);
-    stats.notePull(android::util::DISK_SPACE);
-    stats.notePullFromCache(android::util::DISK_SPACE);
-    stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
-    stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, false);
-    stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
+    stats.notePull(util::DISK_SPACE);
+    stats.notePullTime(util::DISK_SPACE, 1111L);
+    stats.notePullDelay(util::DISK_SPACE, 1111L);
+    stats.notePull(util::DISK_SPACE);
+    stats.notePullTime(util::DISK_SPACE, 3333L);
+    stats.notePullDelay(util::DISK_SPACE, 3335L);
+    stats.notePull(util::DISK_SPACE);
+    stats.notePullFromCache(util::DISK_SPACE);
+    stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
+    stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, false);
+    stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
 
 
     vector<uint8_t> output;
@@ -312,7 +312,7 @@
 
     EXPECT_EQ(1, report.pulled_atom_stats_size());
 
-    EXPECT_EQ(android::util::DISK_SPACE, report.pulled_atom_stats(0).atom_id());
+    EXPECT_EQ(util::DISK_SPACE, report.pulled_atom_stats(0).atom_id());
     EXPECT_EQ(3, report.pulled_atom_stats(0).total_pull());
     EXPECT_EQ(1, report.pulled_atom_stats(0).total_pull_from_cache());
     EXPECT_EQ(2222L, report.pulled_atom_stats(0).min_pull_interval_sec());
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index e48f378..0868aaa 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -79,153 +79,695 @@
     }
 }
 
-// TODO(b/149590301): Update these tests to use new socket schema.
-//class ValueMetricProducerTestHelper {
-//
-// public:
-//    static shared_ptr<LogEvent> createEvent(int64_t eventTimeNs, int64_t value) {
-//        shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, eventTimeNs);
-//        event->write(tagId);
-//        event->write(value);
-//        event->write(value);
-//        event->init();
-//        return event;
-//    }
-//
-//    static sp<ValueMetricProducer> createValueProducerNoConditions(
-//            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
-//        UidMap uidMap;
-//        SimpleAtomMatcher atomMatcher;
-//        atomMatcher.set_atom_id(tagId);
-//        sp<EventMatcherWizard> eventMatcherWizard =
-//                new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                        atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//
-//        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-//                kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-//                logEventMatcherIndex, eventMatcherWizard, tagId,
-//                bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-//        return valueProducer;
-//    }
-//
-//    static sp<ValueMetricProducer> createValueProducerWithCondition(
-//            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
-//        UidMap uidMap;
-//        SimpleAtomMatcher atomMatcher;
-//        atomMatcher.set_atom_id(tagId);
-//        sp<EventMatcherWizard> eventMatcherWizard =
-//                new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                        atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//
-//        sp<ValueMetricProducer> valueProducer =
-//                new ValueMetricProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
-//                                        eventMatcherWizard, tagId, bucketStartTimeNs,
-//                                        bucketStartTimeNs, pullerManager);
-//        valueProducer->mCondition = ConditionState::kFalse;
-//        return valueProducer;
-//    }
-//
-//    static sp<ValueMetricProducer> createValueProducerWithNoInitialCondition(
-//            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
-//        UidMap uidMap;
-//        SimpleAtomMatcher atomMatcher;
-//        atomMatcher.set_atom_id(tagId);
-//        sp<EventMatcherWizard> eventMatcherWizard =
-//                new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                        atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//
-//        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-//                kConfigKey, metric, 1, wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
-//                bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-//        return valueProducer;
-//    }
-//
-//    static sp<ValueMetricProducer> createValueProducerWithState(
-//            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
-//            vector<int32_t> slicedStateAtoms,
-//            unordered_map<int, unordered_map<int, int64_t>> stateGroupMap) {
-//        UidMap uidMap;
-//        SimpleAtomMatcher atomMatcher;
-//        atomMatcher.set_atom_id(tagId);
-//        sp<EventMatcherWizard> eventMatcherWizard =
-//                new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                        atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-//                kConfigKey, metric, -1 /* no condition */, wizard, logEventMatcherIndex,
-//                eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager, {},
-//                {}, slicedStateAtoms, stateGroupMap);
-//        return valueProducer;
-//    }
-//
-//    static ValueMetric createMetric() {
-//        ValueMetric metric;
-//        metric.set_id(metricId);
-//        metric.set_bucket(ONE_MINUTE);
-//        metric.mutable_value_field()->set_field(tagId);
-//        metric.mutable_value_field()->add_child()->set_field(2);
-//        metric.set_max_pull_delay_sec(INT_MAX);
-//        return metric;
-//    }
-//
-//    static ValueMetric createMetricWithCondition() {
-//        ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//        metric.set_condition(StringToId("SCREEN_ON"));
-//        return metric;
-//    }
-//
-//    static ValueMetric createMetricWithState(string state) {
-//        ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//        metric.add_slice_by_state(StringToId(state));
-//        return metric;
-//    }
-//};
-//
-///*
-// * Tests that the first bucket works correctly
-// */
-//TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    int64_t startTimeBase = 11;
-//    UidMap uidMap;
-//    SimpleAtomMatcher atomMatcher;
-//    atomMatcher.set_atom_id(tagId);
-//    sp<EventMatcherWizard> eventMatcherWizard =
-//            new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-//    // statsd started long ago.
-//    // The metric starts in the middle of the bucket
-//    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-//                                      logEventMatcherIndex, eventMatcherWizard, -1, startTimeBase,
-//                                      22, pullerManager);
-//
-//    EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
-//    EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
-//    EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
-//              valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
-//    EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
-//              valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
-//}
-//
-///*
-// * Tests that the first bucket works correctly
-// */
-//TEST(ValueMetricProducerTest, TestFirstBucket) {
+class ValueMetricProducerTestHelper {
+public:
+    static sp<ValueMetricProducer> createValueProducerNoConditions(
+            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
+        UidMap uidMap;
+        SimpleAtomMatcher atomMatcher;
+        atomMatcher.set_atom_id(tagId);
+        sp<EventMatcherWizard> eventMatcherWizard =
+                new EventMatcherWizard({new SimpleLogMatchingTracker(
+                        atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+                kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex,
+                eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+        return valueProducer;
+    }
+
+    static sp<ValueMetricProducer> createValueProducerWithCondition(
+            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
+        UidMap uidMap;
+        SimpleAtomMatcher atomMatcher;
+        atomMatcher.set_atom_id(tagId);
+        sp<EventMatcherWizard> eventMatcherWizard =
+                new EventMatcherWizard({new SimpleLogMatchingTracker(
+                        atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+                kConfigKey, metric, 1, wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+                bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+        valueProducer->mCondition = ConditionState::kFalse;
+        return valueProducer;
+    }
+
+    static sp<ValueMetricProducer> createValueProducerWithNoInitialCondition(
+            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
+        UidMap uidMap;
+        SimpleAtomMatcher atomMatcher;
+        atomMatcher.set_atom_id(tagId);
+        sp<EventMatcherWizard> eventMatcherWizard =
+                new EventMatcherWizard({new SimpleLogMatchingTracker(
+                        atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+                kConfigKey, metric, 1, wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+                bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+        return valueProducer;
+    }
+
+    static sp<ValueMetricProducer> createValueProducerWithState(
+            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
+            vector<int32_t> slicedStateAtoms,
+            unordered_map<int, unordered_map<int, int64_t>> stateGroupMap) {
+        UidMap uidMap;
+        SimpleAtomMatcher atomMatcher;
+        atomMatcher.set_atom_id(tagId);
+        sp<EventMatcherWizard> eventMatcherWizard =
+                new EventMatcherWizard({new SimpleLogMatchingTracker(
+                        atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+                kConfigKey, metric, -1 /* no condition */, wizard, logEventMatcherIndex,
+                eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager, {},
+                {}, slicedStateAtoms, stateGroupMap);
+        return valueProducer;
+    }
+
+    static ValueMetric createMetric() {
+        ValueMetric metric;
+        metric.set_id(metricId);
+        metric.set_bucket(ONE_MINUTE);
+        metric.mutable_value_field()->set_field(tagId);
+        metric.mutable_value_field()->add_child()->set_field(2);
+        metric.set_max_pull_delay_sec(INT_MAX);
+        return metric;
+    }
+
+    static ValueMetric createMetricWithCondition() {
+        ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+        metric.set_condition(StringToId("SCREEN_ON"));
+        return metric;
+    }
+
+    static ValueMetric createMetricWithState(string state) {
+        ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+        metric.add_slice_by_state(StringToId(state));
+        return metric;
+    }
+};
+
+/*
+ * Tests that the first bucket works correctly
+ */
+TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    int64_t startTimeBase = 11;
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+    // statsd started long ago.
+    // The metric starts in the middle of the bucket
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard, -1, startTimeBase,
+                                      22, pullerManager);
+
+    EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
+    EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
+    EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
+              valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
+    EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
+              valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
+}
+
+/*
+ * Tests that the first bucket works correctly
+ */
+TEST(ValueMetricProducerTest, TestFirstBucket) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+    // statsd started long ago.
+    // The metric starts in the middle of the bucket
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard, -1, 5,
+                                      600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
+
+    EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
+    EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
+    EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
+}
+
+/*
+ * Tests pulled atoms with no conditions
+ */
+TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
+
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval =
+            valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(11, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(8, curInterval.value.long_value);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(23, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(12, curInterval.value.long_value);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
+    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+    EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(36, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(13, curInterval.value.long_value);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    EXPECT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
+    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+    EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
+    EXPECT_EQ(13, valueProducer->mPastBuckets.begin()->second[2].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[2].mConditionTrueNs);
+}
+
+TEST(ValueMetricProducerTest, TestPartialBucketCreated) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Initialize bucket.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
+                return true;
+            }))
+            // Partial bucket.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+    // First bucket ends.
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 2));
+    valueProducer->onDataPulled(allData, /** success */ true, bucket2StartTimeNs);
+
+    // Partial buckets created in 2nd bucket.
+    valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1);
+
+    // One full bucket and one partial bucket.
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    vector<ValueBucket> buckets = valueProducer->mPastBuckets.begin()->second;
+    EXPECT_EQ(2UL, buckets.size());
+    // Full bucket (2 - 1)
+    EXPECT_EQ(1, buckets[0].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, buckets[0].mConditionTrueNs);
+    // Full bucket (5 - 3)
+    EXPECT_EQ(3, buckets[1].values[0].long_value);
+    // partial bucket [bucket2StartTimeNs, bucket2StartTimeNs + 2]
+    EXPECT_EQ(2, buckets[1].mConditionTrueNs);
+}
+
+/*
+ * Tests pulled atoms with filtering
+ */
+TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    auto keyValue = atomMatcher.add_field_value_matcher();
+    keyValue->set_field(1);
+    keyValue->set_eq_int(3);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 3, 3));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+            kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex,
+            eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 3, 11));
+
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval =
+            valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(11, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(8, curInterval.value.long_value);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+
+    allData.clear();
+    allData.push_back(CreateTwoValueLogEvent(tagId, bucket3StartTimeNs + 1, 4, 23));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
+    // No new data seen, so data has been cleared.
+    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
+
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(11, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(8, curInterval.value.long_value);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+
+    allData.clear();
+    allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 3, 36));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+    // the base was reset
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(36, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
+    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
+}
+
+/*
+ * Tests pulled atoms with no conditions and take absolute value after reset
+ */
+TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+    metric.set_use_absolute_value_on_reset(true);
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
+
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval =
+            valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(11, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(10, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(10, curInterval.value.long_value);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(36, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(26, curInterval.value.long_value);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
+    EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+    EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
+}
+
+/*
+ * Tests pulled atoms with no conditions and take zero value after reset
+ */
+TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
+
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval =
+            valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(11, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(10, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(36, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(26, curInterval.value.long_value);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+}
+
+/*
+ * Test pulled event with non sliced condition.
+ */
+TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 130));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 180));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval =
+            valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    // startUpdated:false sum:0 start:100
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(100, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 110));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8});
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(110, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(10, curInterval.value.long_value);
+
+    valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8});
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(20, curInterval.value.long_value);
+    EXPECT_EQ(false, curBaseInfo.hasBase);
+
+    valueProducer->onConditionChanged(true, bucket3StartTimeNs + 1);
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10, 20}, {bucketSizeNs - 8, 1});
+}
+
+TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+                                      pullerManager);
+
+    LogEvent event1(/*uid=*/0, /*pid=*/0);
+    CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
+    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+
+    valueProducer.notifyAppUpgrade(bucketStartTimeNs + 150, "ANY.APP", 1, 1);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
+
+    LogEvent event2(/*uid=*/0, /*pid=*/0);
+    CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 1, 10);
+    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
+
+    // Next value should create a new bucket.
+    LogEvent event3(/*uid=*/0, /*pid=*/0);
+    CreateTwoValueLogEvent(&event3, tagId, bucketStartTimeNs + 65 * NS_PER_SEC, 1, 10);
+    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs);
+}
+
+TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            .WillOnce(Return(true))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 149, 120));
+                return true;
+            }));
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+                                      eventMatcherWizard, tagId, bucketStartTimeNs,
+                                      bucketStartTimeNs, pullerManager);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
+
+    valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+
+    valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
+    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {150});
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 150));
+    valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
+    EXPECT_EQ(20L,
+              valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
+    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20, 30},
+                                    {150, bucketSizeNs - 150});
+}
+
+TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+    metric.set_split_bucket_for_app_upgrade(false);
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+                                      eventMatcherWizard, tagId, bucketStartTimeNs,
+                                      bucketStartTimeNs, pullerManager);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
+
+    valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+
+    valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
+    EXPECT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
+}
+
+TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 120));
+                return true;
+            }));
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
+
+    valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100);
+    EXPECT_FALSE(valueProducer->mCondition);
+
+    valueProducer->notifyAppUpgrade(bucket2StartTimeNs - 50, "ANY.APP", 1, 1);
+    // Expect one full buckets already done and starting a partial bucket.
+    EXPECT_EQ(bucket2StartTimeNs - 50, valueProducer->mCurrentBucketStartTimeNs);
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    EXPECT_EQ(bucketStartTimeNs,
+              valueProducer->mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20},
+                                    {(bucket2StartTimeNs - 100) - (bucketStartTimeNs + 1)});
+    EXPECT_FALSE(valueProducer->mCondition);
+}
+
+// TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //
 //    UidMap uidMap;
@@ -237,676 +779,10 @@
 //    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //
-//    // statsd started long ago.
-//    // The metric starts in the middle of the bucket
-//    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-//                                      logEventMatcherIndex, eventMatcherWizard, -1, 5,
-//                                      600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
-//
-//    EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
-//    EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
-//    EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
-//}
-//
-///*
-// * Tests pulled atoms with no conditions
-// */
-//TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(tagId);
-//                event->write(3);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(11);
-//    event->init();
-//    allData.push_back(event);
-//
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    ValueMetricProducer::Interval curInterval =
-//            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(11, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(8, curInterval.value.long_value);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(23);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(23, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(12, curInterval.value.long_value);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
-//    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//    EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(36);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(36, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(13, curInterval.value.long_value);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    EXPECT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
-//    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//    EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
-//    EXPECT_EQ(13, valueProducer->mPastBuckets.begin()->second[2].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[2].mConditionTrueNs);
-//}
-//
-//TEST(ValueMetricProducerTest, TestPartialBucketCreated) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Initialize bucket.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
-//                event->write(tagId);
-//                event->write(1);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            // Partial bucket.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
-//                event->write(tagId);
-//                event->write(5);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-//    // First bucket ends.
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
-//    event->write(tagId);
-//    event->write(2);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** success */ true, bucket2StartTimeNs);
-//
-//    // Partial buckets created in 2nd bucket.
-//    valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1);
-//
-//    // One full bucket and one partial bucket.
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    vector<ValueBucket> buckets = valueProducer->mPastBuckets.begin()->second;
-//    EXPECT_EQ(2UL, buckets.size());
-//    // Full bucket (2 - 1)
-//    EXPECT_EQ(1, buckets[0].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, buckets[0].mConditionTrueNs);
-//    // Full bucket (5 - 3)
-//    EXPECT_EQ(3, buckets[1].values[0].long_value);
-//    // partial bucket [bucket2StartTimeNs, bucket2StartTimeNs + 2]
-//    EXPECT_EQ(2, buckets[1].mConditionTrueNs);
-//}
-//
-///*
-// * Tests pulled atoms with filtering
-// */
-//TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    UidMap uidMap;
-//    SimpleAtomMatcher atomMatcher;
-//    atomMatcher.set_atom_id(tagId);
-//    auto keyValue = atomMatcher.add_field_value_matcher();
-//    keyValue->set_field(1);
-//    keyValue->set_eq_int(3);
-//    sp<EventMatcherWizard> eventMatcherWizard =
-//            new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(3);
-//                event->write(3);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-//            kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex,
-//            eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//    event->write(3);
-//    event->write(11);
-//    event->init();
-//    allData.push_back(event);
-//
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    ValueMetricProducer::Interval curInterval =
-//            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(11, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(8, curInterval.value.long_value);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
-//    event->write(4);
-//    event->write(23);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-//    // No new data seen, so data has been cleared.
-//    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-//
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(11, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(8, curInterval.value.long_value);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
-//    event->write(3);
-//    event->write(36);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-//    // the base was reset
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(36, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
-//    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-//}
-//
-///*
-// * Tests pulled atoms with no conditions and take absolute value after reset
-// */
-//TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//    metric.set_use_absolute_value_on_reset(true);
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(11);
-//    event->init();
-//    allData.push_back(event);
-//
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(11, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(10);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(10, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(10, curInterval.value.long_value);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(36);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(36, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(26, curInterval.value.long_value);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
-//    EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//    EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
-//}
-//
-///*
-// * Tests pulled atoms with no conditions and take zero value after reset
-// */
-//TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(11);
-//    event->init();
-//    allData.push_back(event);
-//
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(11, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(10);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(10, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(36);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(36, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(26, curInterval.value.long_value);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-//    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//}
-//
-///*
-// * Test pulled event with non sliced condition.
-// */
-//TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
-//                event->write(tagId);
-//                event->write(100);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//                event->write(tagId);
-//                event->write(130);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
-//                event->write(tagId);
-//                event->write(180);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-//
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    // startUpdated:false sum:0 start:100
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(100, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//    event->write(1);
-//    event->write(110);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8});
-//
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(110, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(10, curInterval.value.long_value);
-//
-//    valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8});
-//
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curInterval.hasValue);
-//    EXPECT_EQ(20, curInterval.value.long_value);
-//    EXPECT_EQ(false, curBaseInfo.hasBase);
-//
-//    valueProducer->onConditionChanged(true, bucket3StartTimeNs + 1);
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10, 20}, {bucketSizeNs - 8, 1});
-//}
-//
-//TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    UidMap uidMap;
-//    SimpleAtomMatcher atomMatcher;
-//    atomMatcher.set_atom_id(tagId);
-//    sp<EventMatcherWizard> eventMatcherWizard =
-//            new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-//                                      pullerManager);
-//
-//    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-//    event1->write(1);
-//    event1->write(10);
-//    event1->init();
-//    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
-//    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-//
-//    valueProducer.notifyAppUpgrade(bucketStartTimeNs + 150, "ANY.APP", 1, 1);
-//    EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-//    EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
-//
-//    shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 59 * NS_PER_SEC);
-//    event2->write(1);
-//    event2->write(10);
-//    event2->init();
-//    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
-//    EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-//    EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
-//
-//    // Next value should create a new bucket.
-//    shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 65 * NS_PER_SEC);
-//    event3->write(1);
-//    event3->write(10);
-//    event3->init();
-//    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
-//    EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-//    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs);
-//}
-//
-//TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    UidMap uidMap;
-//    SimpleAtomMatcher atomMatcher;
-//    atomMatcher.set_atom_id(tagId);
-//    sp<EventMatcherWizard> eventMatcherWizard =
-//            new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            .WillOnce(Return(true))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 149);
-//                event->write(tagId);
-//                event->write(120);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, tagId, bucketStartTimeNs,
+//                                      eventMatcherWizard, -1, bucketStartTimeNs,
 //                                      bucketStartTimeNs, pullerManager);
 //
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(100);
-//    event->init();
-//    allData.push_back(event);
-//
-//    valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-//
-//    valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
-//    EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-//    EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
-//    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {150});
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(150);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-//    EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-//    EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
-//    EXPECT_EQ(20L,
-//              valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
-//    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20, 30},
-//                                    {150, bucketSizeNs - 150});
-//}
-//
-//TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//    metric.set_split_bucket_for_app_upgrade(false);
-//
-//    UidMap uidMap;
-//    SimpleAtomMatcher atomMatcher;
-//    atomMatcher.set_atom_id(tagId);
-//    sp<EventMatcherWizard> eventMatcherWizard =
-//            new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
-//    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, tagId, bucketStartTimeNs,
-//                                      bucketStartTimeNs, pullerManager);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(100);
-//    event->init();
-//    allData.push_back(event);
-//
-//    valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-//
-//    valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
-//    EXPECT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-//    EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
-//}
-//
-//TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
-//                event->write(tagId);
-//                event->write(100);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs - 100);
-//                event->write(tagId);
-//                event->write(120);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
-//
-//    valueProducer->onConditionChanged(false, bucket2StartTimeNs-100);
-//    EXPECT_FALSE(valueProducer->mCondition);
-//
-//    valueProducer->notifyAppUpgrade(bucket2StartTimeNs-50, "ANY.APP", 1, 1);
-//    // Expect one full buckets already done and starting a partial bucket.
-//    EXPECT_EQ(bucket2StartTimeNs-50, valueProducer->mCurrentBucketStartTimeNs);
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-//    EXPECT_EQ(bucketStartTimeNs,
-//              valueProducer->mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20},
-//                                    {(bucket2StartTimeNs - 100) - (bucketStartTimeNs + 1)});
-//    EXPECT_FALSE(valueProducer->mCondition);
-//}
-//
-//TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    UidMap uidMap;
-//    SimpleAtomMatcher atomMatcher;
-//    atomMatcher.set_atom_id(tagId);
-//    sp<EventMatcherWizard> eventMatcherWizard =
-//            new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-//    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-//                                      pullerManager);
-//
 //    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
 //    event1->write(1);
 //    event1->write(10);
@@ -918,10 +794,10 @@
 //    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
 //    // has one slice
 //    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-//    ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(10, curInterval.value.long_value);
-//    EXPECT_EQ(true, curInterval.hasValue);
+//    ValueMetricProducer::Interval curInterval =
+//    valueProducer.mCurrentSlicedBucket.begin()->second[0]; ValueMetricProducer::BaseInfo
+//    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(10,
+//    curInterval.value.long_value); EXPECT_EQ(true, curInterval.hasValue);
 //
 //    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
 //
@@ -934,7 +810,7 @@
 //    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs});
 //}
 //
-//TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
+// TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //
 //    UidMap uidMap;
@@ -947,8 +823,8 @@
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //
 //    ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-//                                      pullerManager);
+//                                      eventMatcherWizard, -1, bucketStartTimeNs,
+//                                      bucketStartTimeNs, pullerManager);
 //    valueProducer.mCondition = ConditionState::kFalse;
 //
 //    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
@@ -1000,7 +876,7 @@
 //    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20});
 //}
 //
-//TEST(ValueMetricProducerTest, TestAnomalyDetection) {
+// TEST(ValueMetricProducerTest, TestAnomalyDetection) {
 //    sp<AlarmMonitor> alarmMonitor;
 //    Alert alert;
 //    alert.set_id(101);
@@ -1053,7 +929,8 @@
 //    event5->write(150); // value of interest
 //    event5->init();
 //    shared_ptr<LogEvent> event6
-//            = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10 * NS_PER_SEC);
+//            = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10 *
+//            NS_PER_SEC);
 //    event6->write(25);
 //    event6->write(160); // value of interest
 //    event6->init();
@@ -1086,7 +963,7 @@
 //}
 //
 //// Test value metric no condition, the pull on bucket boundary come in time and too late
-//TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
+// TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //    EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
@@ -1107,7 +984,8 @@
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+//    ValueMetricProducer::BaseInfo curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0];
 //
 //    // startUpdated:true sum:0 start:11
 //    EXPECT_EQ(true, curBaseInfo.hasBase);
@@ -1158,7 +1036,7 @@
 // * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
 // * was delivered late.
 // */
-//TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
+// TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1184,7 +1062,8 @@
 //                return true;
 //            }));
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 //
@@ -1192,8 +1071,8 @@
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
+//    ValueMetricProducer::BaseInfo curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
 //    EXPECT_EQ(100, curBaseInfo.base.long_value);
 //    EXPECT_EQ(false, curInterval.hasValue);
 //    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
@@ -1219,10 +1098,11 @@
 //}
 //
 ///*
-// * Test pulled event with non sliced condition. The pull on boundary come late, after the condition
+// * Test pulled event with non sliced condition. The pull on boundary come late, after the
+// condition
 // * change to false, and then true again. This is due to alarm delivered late.
 // */
-//TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
+// TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1250,16 +1130,15 @@
 //            // condition becomes true again
 //            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
 //                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 25);
-//                event->write(tagId);
-//                event->write(130);
-//                event->init();
+//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+//                25); event->write(tagId); event->write(130); event->init();
 //                data->push_back(event);
 //                return true;
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 //
@@ -1267,7 +1146,8 @@
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+//    ValueMetricProducer::BaseInfo curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0];
 //    // startUpdated:false sum:0 start:100
 //    EXPECT_EQ(true, curBaseInfo.hasBase);
 //    EXPECT_EQ(100, curBaseInfo.base.long_value);
@@ -1313,7 +1193,7 @@
 //                                    {bucketSizeNs - 8, bucketSizeNs - 24});
 //}
 //
-//TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
+// TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.set_aggregation_type(ValueMetric::MIN);
 //
@@ -1327,8 +1207,8 @@
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //
 //    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-//                                      pullerManager);
+//                                      eventMatcherWizard, -1, bucketStartTimeNs,
+//                                      bucketStartTimeNs, pullerManager);
 //
 //    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
 //    event1->write(1);
@@ -1357,7 +1237,7 @@
 //    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs});
 //}
 //
-//TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
+// TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.set_aggregation_type(ValueMetric::MAX);
 //
@@ -1371,8 +1251,8 @@
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //
 //    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-//                                      pullerManager);
+//                                      eventMatcherWizard, -1, bucketStartTimeNs,
+//                                      bucketStartTimeNs, pullerManager);
 //
 //    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
 //    event1->write(1);
@@ -1403,7 +1283,7 @@
 //    /* EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value); */
 //}
 //
-//TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
+// TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.set_aggregation_type(ValueMetric::AVG);
 //
@@ -1417,8 +1297,8 @@
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //
 //    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-//                                      pullerManager);
+//                                      eventMatcherWizard, -1, bucketStartTimeNs,
+//                                      bucketStartTimeNs, pullerManager);
 //
 //    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
 //    event1->write(1);
@@ -1449,11 +1329,12 @@
 //    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
 //    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
 //
-//    EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value -
+//    EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value
+//    -
 //                         12.5) < epsilon);
 //}
 //
-//TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
+// TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.set_aggregation_type(ValueMetric::SUM);
 //
@@ -1467,8 +1348,8 @@
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //
 //    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-//                                      pullerManager);
+//                                      eventMatcherWizard, -1, bucketStartTimeNs,
+//                                      bucketStartTimeNs, pullerManager);
 //
 //    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
 //    event1->write(1);
@@ -1497,7 +1378,7 @@
 //    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs});
 //}
 //
-//TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
+// TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.set_aggregation_type(ValueMetric::MIN);
 //    metric.set_use_diff(true);
@@ -1512,8 +1393,8 @@
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //
 //    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-//                                      pullerManager);
+//                                      eventMatcherWizard, -1, bucketStartTimeNs,
+//                                      bucketStartTimeNs, pullerManager);
 //
 //    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
 //    event1->write(1);
@@ -1572,7 +1453,7 @@
 //    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs});
 //}
 //
-//TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
+// TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.mutable_value_field()->add_child()->set_field(3);
 //    metric.set_aggregation_type(ValueMetric::MIN);
@@ -1588,8 +1469,8 @@
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //
 //    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-//                                      pullerManager);
+//                                      eventMatcherWizard, -1, bucketStartTimeNs,
+//                                      bucketStartTimeNs, pullerManager);
 //
 //    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
 //    event1->write(1);
@@ -1687,7 +1568,7 @@
 ///*
 // * Tests zero default base.
 // */
-//TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
+// TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.mutable_dimensions_in_what()->set_field(tagId);
 //    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
@@ -1774,7 +1655,7 @@
 ///*
 // * Tests using zero default base with failed pull.
 // */
-//TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
+// TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.mutable_dimensions_in_what()->set_field(tagId);
 //    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
@@ -1885,8 +1766,9 @@
 //    it2 = std::next(valueProducer->mCurrentSlicedBucket.begin());
 //    interval1 = it->second[0];
 //    interval2 = it2->second[0];
-//    baseInfo1 = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat())->second[0];
-//    baseInfo2 = valueProducer->mCurrentBaseInfo.find(it2->first.getDimensionKeyInWhat())->second[0];
+//    baseInfo1 =
+//    valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat())->second[0]; baseInfo2
+//    = valueProducer->mCurrentBaseInfo.find(it2->first.getDimensionKeyInWhat())->second[0];
 //
 //    EXPECT_EQ(true, baseInfo1.hasBase);
 //    EXPECT_EQ(5, baseInfo1.base.long_value);
@@ -1905,7 +1787,7 @@
 ///*
 // * Tests trim unused dimension key if no new data is seen in an entire bucket.
 // */
-//TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
+// TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.mutable_dimensions_in_what()->set_field(tagId);
 //    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
@@ -2023,7 +1905,7 @@
 //    EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
 //}
 //
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2040,15 +1922,16 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 //    // has one slice
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval& curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
+//    ValueMetricProducer::BaseInfo& curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
 //    EXPECT_EQ(100, curBaseInfo.base.long_value);
 //    EXPECT_EQ(false, curInterval.hasValue);
 //
@@ -2060,7 +1943,7 @@
 //    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
 //}
 //
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2077,7 +1960,8 @@
 //            .WillOnce(Return(false));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 //
@@ -2085,8 +1969,8 @@
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval& curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
+//    ValueMetricProducer::BaseInfo& curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
 //    EXPECT_EQ(100, curBaseInfo.base.long_value);
 //    EXPECT_EQ(false, curInterval.hasValue);
 //    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
@@ -2100,7 +1984,7 @@
 //    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
 //}
 //
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2125,7 +2009,8 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    // Don't directly set mCondition; the real code never does that. Go through regular code path
 //    // to avoid unexpected behaviors.
@@ -2138,13 +2023,13 @@
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval& curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(false, curBaseInfo.hasBase);
+//    ValueMetricProducer::BaseInfo curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(false, curBaseInfo.hasBase);
 //    EXPECT_EQ(false, curInterval.hasValue);
 //    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
 //}
 //
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.set_condition(StringToId("SCREEN_ON"));
 //    metric.set_max_pull_delay_sec(0);
@@ -2162,7 +2047,8 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    valueProducer->mCondition = ConditionState::kFalse;
 //
@@ -2171,7 +2057,7 @@
 //    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
 //}
 //
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    UidMap uidMap;
@@ -2196,7 +2082,7 @@
 //    EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
 //}
 //
-//TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
+// TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2212,7 +2098,8 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    valueProducer->mCondition = ConditionState::kFalse;
 //    valueProducer->mHasGlobalBase = false;
@@ -2222,8 +2109,8 @@
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval& curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
+//    ValueMetricProducer::BaseInfo curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
 //    EXPECT_EQ(100, curBaseInfo.base.long_value);
 //    EXPECT_EQ(false, curInterval.hasValue);
 //    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
@@ -2232,7 +2119,7 @@
 ///*
 // * Tests that a bucket is marked invalid when a condition change pull fails.
 // */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2251,7 +2138,8 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    valueProducer->mCondition = ConditionState::kTrue;
 //
@@ -2286,8 +2174,8 @@
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval& curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
+//    ValueMetricProducer::BaseInfo curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
 //    EXPECT_EQ(140, curBaseInfo.base.long_value);
 //    EXPECT_EQ(false, curInterval.hasValue);
 //    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
@@ -2317,7 +2205,7 @@
 ///*
 // * Tests that a bucket is marked invalid when the guardrail is hit.
 // */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    metric.mutable_dimensions_in_what()->set_field(tagId);
 //    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
@@ -2339,7 +2227,8 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //    valueProducer->mCondition = ConditionState::kFalse;
 //
 //    valueProducer->onConditionChanged(true, bucketStartTimeNs + 2);
@@ -2385,7 +2274,7 @@
 ///*
 // * Tests that a bucket is marked invalid when the bucket's initial pull fails.
 // */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2412,7 +2301,8 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    valueProducer->mCondition = ConditionState::kTrue;
 //
@@ -2445,8 +2335,8 @@
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval& curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
+//    ValueMetricProducer::BaseInfo curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
 //    EXPECT_EQ(140, curBaseInfo.base.long_value);
 //    EXPECT_EQ(false, curInterval.hasValue);
 //    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
@@ -2477,7 +2367,7 @@
 // * Tests that a bucket is marked invalid when the bucket's final pull fails
 // * (i.e. failed pull on bucket boundary).
 // */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2504,7 +2394,8 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    valueProducer->mCondition = ConditionState::kTrue;
 //
@@ -2537,8 +2428,8 @@
 //    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 //    ValueMetricProducer::Interval& curInterval =
 //            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(false, curBaseInfo.hasBase);
+//    ValueMetricProducer::BaseInfo curBaseInfo =
+//    valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(false, curBaseInfo.hasBase);
 //    EXPECT_EQ(false, curInterval.hasValue);
 //    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
 //
@@ -2564,7 +2455,7 @@
 //    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), dropEvent.drop_time_millis());
 //}
 //
-//TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
+// TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //    EXPECT_CALL(*pullerManager, Pull(tagId, _))
@@ -2604,999 +2495,903 @@
 //    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
 //    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
 //}
-//
-//TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // First onConditionChanged
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(tagId);
-//                event->write(3);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    ValueMetricProducer::Interval& curInterval =
-//            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-//
-//    // Empty pull.
-//    valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(false, curBaseInfo.hasBase);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-//}
-//
-//TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // First onConditionChanged
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(tagId);
-//                event->write(1);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(tagId);
-//                event->write(2);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(tagId);
-//                event->write(5);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-//    valueProducer->onConditionChanged(false, bucketStartTimeNs + 11);
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 12);
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    ValueMetricProducer::Interval& curInterval =
-//            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(true, curInterval.hasValue);
-//    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-//
-//    // End of bucket
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    // Data is empty, base should be reset.
-//    EXPECT_EQ(false, curBaseInfo.hasBase);
-//    EXPECT_EQ(5, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-//
-//    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1});
-//}
-//
-//TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//    metric.mutable_dimensions_in_what()->set_field(tagId);
-//    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-//    metric.set_condition(StringToId("SCREEN_ON"));
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // First onConditionChanged
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(tagId);
-//                event->write(1);
-//                event->write(1);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//
-//    // End of bucket
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//    event->write(2);
-//    event->write(2);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-//    // Key 1 should be reset since in not present in the most pull.
-//    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-//    auto iterator = valueProducer->mCurrentSlicedBucket.begin();
-//    auto baseInfoIter = valueProducer->mCurrentBaseInfo.begin();
-//    EXPECT_EQ(true, baseInfoIter->second[0].hasBase);
-//    EXPECT_EQ(2, baseInfoIter->second[0].base.long_value);
-//    EXPECT_EQ(false, iterator->second[0].hasValue);
-//    iterator++;
-//    baseInfoIter++;
-//    EXPECT_EQ(false, baseInfoIter->second[0].hasBase);
-//    EXPECT_EQ(1, baseInfoIter->second[0].base.long_value);
-//    EXPECT_EQ(false, iterator->second[0].hasValue);
-//
-//    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-//}
-//
-//TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Initialization.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
-//                return true;
-//            }))
-//            // notifyAppUpgrade.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(ValueMetricProducerTestHelper::createEvent(
-//                        bucketStartTimeNs + bucketSizeNs / 2, 10));
-//                return true;
-//            }));
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//    ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
-//
-//    valueProducer->notifyAppUpgrade(bucketStartTimeNs + bucketSizeNs / 2, "com.foo", 10000, 1);
-//    ASSERT_EQ(1UL, valueProducer->mCurrentFullBucket.size());
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs + 1, 4));
-//    valueProducer->onDataPulled(allData, /** fails */ false, bucket3StartTimeNs + 1);
-//    ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
-//}
-//
-//TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Second onConditionChanged.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(
-//                        ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 10, 5));
-//                return true;
-//            }))
-//            // Third onConditionChanged.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(
-//                        ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs + 10, 7));
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//    valueProducer->mCondition = ConditionState::kUnknown;
-//
-//    valueProducer->onConditionChanged(false, bucketStartTimeNs);
-//    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-//
-//    // End of first bucket
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 1, 4));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
-//    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-//
-//    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-//    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curBaseInfo.hasBase);
-//    EXPECT_EQ(5, curBaseInfo.base.long_value);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//
-//    valueProducer->onConditionChanged(false, bucket3StartTimeNs + 10);
-//
-//    // Bucket should have been completed.
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10});
-//}
-//
-//TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//    metric.set_use_diff(false);
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
-//
-//    allData.clear();
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 20));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-//    // Bucket should have been completed.
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs});
-//}
-//
-//TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Initialization.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
-//
-//    allData.clear();
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 20));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-//    // Bucket should have been completed.
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs});
-//}
-//
-//TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Initialization.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
-//                return true;
-//            }))
-//            // notifyAppUpgrade.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(
-//                        ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 2, 10));
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-//    valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1);
-//
-//    // Bucket should have been completed.
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs});
-//}
-//
-//TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // First on condition changed.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
-//                return true;
-//            }))
-//            // Second on condition changed.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 3));
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-//    valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
-//    valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
-//
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(true, curInterval.hasValue);
-//    EXPECT_EQ(2, curInterval.value.long_value);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 1, 10));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
-//
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2});
-//}
-//
-//// TODO: b/145705635 fix or delete this test
-//TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // First condition change.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
-//                return true;
-//            }))
-//            // 2nd condition change.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 1));
-//                return true;
-//            }))
-//            // 3rd condition change.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 1));
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 3, 10));
-//    valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs + 3);
-//
-//    allData.clear();
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 20));
-//    valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
-//
-//    valueProducer->onConditionChanged(false, bucket2StartTimeNs + 8);
-//    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-//
-//    allData.clear();
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs, 30));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-//    // There was not global base available so all buckets are invalid.
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
-//}
-//
-//TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    UidMap uidMap;
-//    SimpleAtomMatcher atomMatcher;
-//    atomMatcher.set_atom_id(tagId);
-//    sp<EventMatcherWizard> eventMatcherWizard =
-//            new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Initial pull.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(tagId);
-//                event->write(1);
-//                event->write(1);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, tagId, bucketStartTimeNs,
-//                                      bucketStartTimeNs, pullerManager);
-//
-//    ProtoOutputStream output;
-//    std::set<string> strSet;
-//    valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
-//                               FAST, &strSet, &output);
-//
-//    StatsLogReport report = outputStreamToProto(&output);
-//    // Bucket is invalid since we did not pull when dump report was called.
-//    EXPECT_EQ(0, report.value_metrics().data_size());
-//}
-//
-//TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    UidMap uidMap;
-//    SimpleAtomMatcher atomMatcher;
-//    atomMatcher.set_atom_id(tagId);
-//    sp<EventMatcherWizard> eventMatcherWizard =
-//            new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Initial pull.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(tagId);
-//                event->write(1);
-//                event->write(1);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, tagId, bucketStartTimeNs,
-//                                      bucketStartTimeNs, pullerManager);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.clear();
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-//    event->write(tagId);
-//    event->write(2);
-//    event->write(2);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-//    ProtoOutputStream output;
-//    std::set<string> strSet;
-//    valueProducer.onDumpReport(bucket4StartTimeNs, false /* include recent buckets */, true, FAST,
-//                               &strSet, &output);
-//
-//    StatsLogReport report = outputStreamToProto(&output);
-//    // Previous bucket is part of the report.
-//    EXPECT_EQ(1, report.value_metrics().data_size());
-//    EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num());
-//}
-//
-//TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-//    UidMap uidMap;
-//    SimpleAtomMatcher atomMatcher;
-//    atomMatcher.set_atom_id(tagId);
-//    sp<EventMatcherWizard> eventMatcherWizard =
-//            new EventMatcherWizard({new SimpleLogMatchingTracker(
-//                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-//    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-//    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Initial pull.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-//                event->write(tagId);
-//                event->write(1);
-//                event->write(1);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
-//                event->write(tagId);
-//                event->write(3);
-//                event->write(3);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-//                                      eventMatcherWizard, tagId, bucketStartTimeNs,
-//                                      bucketStartTimeNs, pullerManager);
-//
-//    ProtoOutputStream output;
-//    std::set<string> strSet;
-//    valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
-//                               NO_TIME_CONSTRAINTS, &strSet, &output);
-//
-//    StatsLogReport report = outputStreamToProto(&output);
-//    EXPECT_EQ(1, report.value_metrics().data_size());
-//    EXPECT_EQ(1, report.value_metrics().data(0).bucket_info_size());
-//    EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
-//}
-//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//    metric.set_use_diff(false);
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 10));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 30);
-//
-//    // Bucket should have been completed.
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs});
-//}
-//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//    metric.set_use_diff(false);
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // condition becomes true
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(
-//                        ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10));
-//                return true;
-//            }))
-//            // condition becomes false
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(
-//                        ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 50, 20));
-//                return true;
-//            }));
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//    valueProducer->mCondition = ConditionState::kFalse;
-//
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-//    valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
-//    // has one slice
-//    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-//    ValueMetricProducer::Interval curInterval =
-//            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(false, curBaseInfo.hasBase);
-//    EXPECT_EQ(true, curInterval.hasValue);
-//    EXPECT_EQ(20, curInterval.value.long_value);
-//
-//    // Now the alarm is delivered. Condition is off though.
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 110));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8});
-//    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(false, curBaseInfo.hasBase);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//}
-//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//    metric.set_use_diff(false);
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // condition becomes true
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(
-//                        ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10));
-//                return true;
-//            }));
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//    valueProducer->mCondition = ConditionState::kFalse;
-//
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-//
-//    // Now the alarm is delivered. Condition is off though.
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 30));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8});
-//    ValueMetricProducer::Interval curInterval =
-//            valueProducer->mCurrentSlicedBucket.begin()->second[0];
-//    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//    EXPECT_EQ(false, curBaseInfo.hasBase);
-//    EXPECT_EQ(false, curInterval.hasValue);
-//}
-//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//    metric.set_use_diff(false);
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//    valueProducer->mCondition = ConditionState::kFalse;
-//
-//    // Now the alarm is delivered. Condition is off though.
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 30));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-//    // Condition was always false.
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
-//}
-//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//    metric.set_use_diff(false);
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // condition becomes true
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                data->push_back(
-//                        ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10));
-//                return true;
-//            }))
-//            .WillOnce(Return(false));
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//    valueProducer->mCondition = ConditionState::kFalse;
-//
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-//    valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
-//
-//    // Now the alarm is delivered. Condition is off though.
-//    vector<shared_ptr<LogEvent>> allData;
-//    allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 30));
-//    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-//
-//    // No buckets, we had a failure.
-//    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
-//}
-//
-///*
-// * Test that DUMP_REPORT_REQUESTED dump reason is logged.
-// *
-// * For the bucket to be marked invalid during a dump report requested,
-// * three things must be true:
-// * - we want to include the current partial bucket
-// * - we need a pull (metric is pulled and condition is true)
-// * - the dump latency must be FAST
-// */
-//
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequested) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Condition change to true.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
-//                event->write("field1");
-//                event->write(10);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    // Condition change event.
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 20);
-//
-//    // Check dump report.
-//    ProtoOutputStream output;
-//    std::set<string> strSet;
-//    valueProducer->onDumpReport(bucketStartTimeNs + 40, true /* include recent buckets */, true,
-//                                FAST /* dumpLatency */, &strSet, &output);
-//
-//    StatsLogReport report = outputStreamToProto(&output);
-//    EXPECT_TRUE(report.has_value_metrics());
-//    EXPECT_EQ(0, report.value_metrics().data_size());
-//    EXPECT_EQ(1, report.value_metrics().skipped_size());
-//
-//    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-//              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-//    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40),
-//              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-//    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-//
-//    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-//    EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason());
-//    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), dropEvent.drop_time_millis());
-//}
-//
-///*
-// * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late condition
-// * change event (i.e. the condition change occurs in the wrong bucket).
-// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWrongBucket) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Condition change to true.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 50);
-//                event->write("field1");
-//                event->write(10);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    // Condition change event.
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-//
-//    // Bucket boundary pull.
-//    vector<shared_ptr<LogEvent>> allData;
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs);
-//    event->write("field1");
-//    event->write(15);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-//
-//    // Late condition change event.
-//    valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100);
-//
-//    // Check dump report.
-//    ProtoOutputStream output;
-//    std::set<string> strSet;
-//    valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
-//                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-//
-//    StatsLogReport report = outputStreamToProto(&output);
-//    EXPECT_TRUE(report.has_value_metrics());
-//    EXPECT_EQ(1, report.value_metrics().data_size());
-//    EXPECT_EQ(1, report.value_metrics().skipped_size());
-//
-//    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-//              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-//    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
-//              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-//    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-//
-//    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-//    EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
-//    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
-//}
-//
-///*
-// * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late accumulate
-// * event (i.e. the accumulate events call occurs in the wrong bucket).
-// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Condition change to true.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 50);
-//                event->write("field1");
-//                event->write(10);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            // Dump report requested.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 100);
-//                event->write("field1");
-//                event->write(15);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    // Condition change event.
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-//
-//    // Bucket boundary pull.
-//    vector<shared_ptr<LogEvent>> allData;
-//    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs);
-//    event->write("field1");
-//    event->write(15);
-//    event->init();
-//    allData.push_back(event);
-//    valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-//
-//    allData.clear();
-//    event = make_shared<LogEvent>(tagId, bucket2StartTimeNs - 100);
-//    event->write("field1");
-//    event->write(20);
-//    event->init();
-//    allData.push_back(event);
-//
-//    // Late accumulateEvents event.
-//    valueProducer->accumulateEvents(allData, bucket2StartTimeNs - 100, bucket2StartTimeNs - 100);
-//
-//    // Check dump report.
-//    ProtoOutputStream output;
-//    std::set<string> strSet;
-//    valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
-//                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-//
-//    StatsLogReport report = outputStreamToProto(&output);
-//    EXPECT_TRUE(report.has_value_metrics());
-//    EXPECT_EQ(1, report.value_metrics().data_size());
-//    EXPECT_EQ(1, report.value_metrics().skipped_size());
-//
-//    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-//              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-//    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
-//              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-//    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-//
-//    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-//    EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
-//    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
-//}
-//
-///*
-// * Test that CONDITION_UNKNOWN dump reason is logged due to an unknown condition
-// * when a metric is initialized.
-// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Condition change to true.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 50);
-//                event->write("field1");
-//                event->write(10);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            // Dump report requested.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 100);
-//                event->write("field1");
-//                event->write(15);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithNoInitialCondition(pullerManager,
-//                                                                                     metric);
-//
-//    // Condition change event.
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-//
-//    // Check dump report.
-//    ProtoOutputStream output;
-//    std::set<string> strSet;
-//    int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
-//    valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
-//                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-//
-//    StatsLogReport report = outputStreamToProto(&output);
-//    EXPECT_TRUE(report.has_value_metrics());
-//    EXPECT_EQ(0, report.value_metrics().data_size());
-//    EXPECT_EQ(1, report.value_metrics().skipped_size());
-//
-//    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-//              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-//    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
-//              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-//    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-//
-//    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-//    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
-//    EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-//}
-//
-///*
-// * Test that PULL_FAILED dump reason is logged due to a pull failure in
-// * #pullAndMatchEventsLocked.
-// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) {
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-//
-//    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//    EXPECT_CALL(*pullerManager, Pull(tagId, _))
-//            // Condition change to true.
-//            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-//                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 50);
-//                event->write("field1");
-//                event->write(10);
-//                event->init();
-//                data->push_back(event);
-//                return true;
-//            }))
-//            // Dump report requested, pull fails.
-//            .WillOnce(Return(false));
-//
-//    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
-//
-//    // Condition change event.
-//    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-//
-//    // Check dump report.
-//    ProtoOutputStream output;
-//    std::set<string> strSet;
-//    int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
-//    valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
-//                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-//
-//    StatsLogReport report = outputStreamToProto(&output);
-//    EXPECT_TRUE(report.has_value_metrics());
-//    EXPECT_EQ(0, report.value_metrics().data_size());
-//    EXPECT_EQ(1, report.value_metrics().skipped_size());
-//
-//    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-//              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-//    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
-//              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-//    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-//
-//    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-//    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-//    EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-//}
-//
+
+TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // First onConditionChanged
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval& curInterval =
+            valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
+
+    // Empty pull.
+    valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(false, curBaseInfo.hasBase);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
+}
+
+TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // First onConditionChanged
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 2));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 5));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
+    valueProducer->onConditionChanged(false, bucketStartTimeNs + 11);
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 12);
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval& curInterval =
+            valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
+
+    // End of bucket
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    // Data is empty, base should be reset.
+    EXPECT_EQ(false, curBaseInfo.hasBase);
+    EXPECT_EQ(5, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
+
+    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1});
+}
+
+TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+    metric.mutable_dimensions_in_what()->set_field(tagId);
+    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
+    metric.set_condition(StringToId("SCREEN_ON"));
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // First onConditionChanged
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+
+    // End of bucket
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 2));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+    // Key 1 should be reset since in not present in the most pull.
+    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    auto iterator = valueProducer->mCurrentSlicedBucket.begin();
+    auto baseInfoIter = valueProducer->mCurrentBaseInfo.begin();
+    EXPECT_EQ(true, baseInfoIter->second[0].hasBase);
+    EXPECT_EQ(2, baseInfoIter->second[0].base.long_value);
+    EXPECT_EQ(false, iterator->second[0].hasValue);
+    iterator++;
+    baseInfoIter++;
+    EXPECT_EQ(false, baseInfoIter->second[0].hasBase);
+    EXPECT_EQ(1, baseInfoIter->second[0].base.long_value);
+    EXPECT_EQ(false, iterator->second[0].hasValue);
+
+    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
+}
+
+TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Initialization.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
+            // notifyAppUpgrade.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(
+                        tagId, bucketStartTimeNs + bucketSizeNs / 2, 10));
+                return true;
+            }));
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+    ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
+
+    valueProducer->notifyAppUpgrade(bucketStartTimeNs + bucketSizeNs / 2, "com.foo", 10000, 1);
+    ASSERT_EQ(1UL, valueProducer->mCurrentFullBucket.size());
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 4));
+    valueProducer->onDataPulled(allData, /** fails */ false, bucket3StartTimeNs + 1);
+    ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
+}
+
+TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Second onConditionChanged.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5));
+                return true;
+            }))
+            // Third onConditionChanged.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 10, 7));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+    valueProducer->mCondition = ConditionState::kUnknown;
+
+    valueProducer->onConditionChanged(false, bucketStartTimeNs);
+    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
+
+    // End of first bucket
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 4));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
+    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
+
+    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curBaseInfo.hasBase);
+    EXPECT_EQ(5, curBaseInfo.base.long_value);
+    EXPECT_EQ(false, curInterval.hasValue);
+
+    valueProducer->onConditionChanged(false, bucket3StartTimeNs + 10);
+
+    // Bucket should have been completed.
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10});
+}
+
+TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+    metric.set_use_diff(false);
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+    // Bucket should have been completed.
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs});
+}
+
+TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Initialization.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+    // Bucket should have been completed.
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs});
+}
+
+TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Initialization.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
+            // notifyAppUpgrade.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 2, 10));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+    valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1);
+
+    // Bucket should have been completed.
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs});
+}
+
+TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // First on condition changed.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
+            // Second on condition changed.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
+    valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
+    valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
+
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(2, curInterval.value.long_value);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 10));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
+
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2});
+}
+
+// TODO: b/145705635 fix or delete this test
+TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // First condition change.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
+            // 2nd condition change.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
+                return true;
+            }))
+            // 3rd condition change.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 3, 10));
+    valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs + 3);
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
+    valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
+
+    valueProducer->onConditionChanged(false, bucket2StartTimeNs + 8);
+    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 30));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+    // There was not global base available so all buckets are invalid.
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
+}
+
+TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Initial pull.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
+                return true;
+            }));
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+                                      eventMatcherWizard, tagId, bucketStartTimeNs,
+                                      bucketStartTimeNs, pullerManager);
+
+    ProtoOutputStream output;
+    std::set<string> strSet;
+    valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
+                               FAST, &strSet, &output);
+
+    StatsLogReport report = outputStreamToProto(&output);
+    // Bucket is invalid since we did not pull when dump report was called.
+    EXPECT_EQ(0, report.value_metrics().data_size());
+}
+
+TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Initial pull.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
+                return true;
+            }));
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+                                      eventMatcherWizard, tagId, bucketStartTimeNs,
+                                      bucketStartTimeNs, pullerManager);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    allData.push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 1, tagId, 2, 2));
+    valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+    ProtoOutputStream output;
+    std::set<string> strSet;
+    valueProducer.onDumpReport(bucket4StartTimeNs, false /* include recent buckets */, true, FAST,
+                               &strSet, &output);
+
+    StatsLogReport report = outputStreamToProto(&output);
+    // Previous bucket is part of the report.
+    EXPECT_EQ(1, report.value_metrics().data_size());
+    EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num());
+}
+
+TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Initial pull.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(
+                        CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 10, tagId, 3, 3));
+                return true;
+            }));
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+                                      eventMatcherWizard, tagId, bucketStartTimeNs,
+                                      bucketStartTimeNs, pullerManager);
+
+    ProtoOutputStream output;
+    std::set<string> strSet;
+    valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
+                               NO_TIME_CONSTRAINTS, &strSet, &output);
+
+    StatsLogReport report = outputStreamToProto(&output);
+    EXPECT_EQ(1, report.value_metrics().data_size());
+    EXPECT_EQ(1, report.value_metrics().data(0).bucket_info_size());
+    EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
+}
+
+TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+    metric.set_use_diff(false);
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 10));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 30);
+
+    // Bucket should have been completed.
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs});
+}
+
+TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+    metric.set_use_diff(false);
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // condition becomes true
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
+                return true;
+            }))
+            // condition becomes false
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 20));
+                return true;
+            }));
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+    valueProducer->mCondition = ConditionState::kFalse;
+
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
+    valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval =
+            valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(false, curBaseInfo.hasBase);
+    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(20, curInterval.value.long_value);
+
+    // Now the alarm is delivered. Condition is off though.
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8});
+    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(false, curBaseInfo.hasBase);
+    EXPECT_EQ(false, curInterval.hasValue);
+}
+
+TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+    metric.set_use_diff(false);
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // condition becomes true
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
+                return true;
+            }));
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+    valueProducer->mCondition = ConditionState::kFalse;
+
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
+
+    // Now the alarm is delivered. Condition is off though.
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8});
+    ValueMetricProducer::Interval curInterval =
+            valueProducer->mCurrentSlicedBucket.begin()->second[0];
+    ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+    EXPECT_EQ(false, curBaseInfo.hasBase);
+    EXPECT_EQ(false, curInterval.hasValue);
+}
+
+TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+    metric.set_use_diff(false);
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+    valueProducer->mCondition = ConditionState::kFalse;
+
+    // Now the alarm is delivered. Condition is off though.
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+    // Condition was always false.
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
+}
+
+TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+    metric.set_use_diff(false);
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // condition becomes true
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
+                return true;
+            }))
+            .WillOnce(Return(false));
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+    valueProducer->mCondition = ConditionState::kFalse;
+
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
+    valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
+
+    // Now the alarm is delivered. Condition is off though.
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
+    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+
+    // No buckets, we had a failure.
+    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
+}
+
+/*
+ * Test that DUMP_REPORT_REQUESTED dump reason is logged.
+ *
+ * For the bucket to be marked invalid during a dump report requested,
+ * three things must be true:
+ * - we want to include the current partial bucket
+ * - we need a pull (metric is pulled and condition is true)
+ * - the dump latency must be FAST
+ */
+
+TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequested) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Condition change to true.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20, 10));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    // Condition change event.
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 20);
+
+    // Check dump report.
+    ProtoOutputStream output;
+    std::set<string> strSet;
+    valueProducer->onDumpReport(bucketStartTimeNs + 40, true /* include recent buckets */, true,
+                                FAST /* dumpLatency */, &strSet, &output);
+
+    StatsLogReport report = outputStreamToProto(&output);
+    EXPECT_TRUE(report.has_value_metrics());
+    EXPECT_EQ(0, report.value_metrics().data_size());
+    EXPECT_EQ(1, report.value_metrics().skipped_size());
+
+    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
+              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
+    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40),
+              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
+    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+
+    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
+    EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason());
+    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), dropEvent.drop_time_millis());
+}
+
+/*
+ * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late condition
+ * change event (i.e. the condition change occurs in the wrong bucket).
+ */
+TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWrongBucket) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Condition change to true.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    // Condition change event.
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
+
+    // Bucket boundary pull.
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15));
+    valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
+
+    // Late condition change event.
+    valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100);
+
+    // Check dump report.
+    ProtoOutputStream output;
+    std::set<string> strSet;
+    valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
+                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
+
+    StatsLogReport report = outputStreamToProto(&output);
+    EXPECT_TRUE(report.has_value_metrics());
+    EXPECT_EQ(1, report.value_metrics().data_size());
+    EXPECT_EQ(1, report.value_metrics().skipped_size());
+
+    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
+              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
+    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
+              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
+    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+
+    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
+    EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
+    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
+}
+
+/*
+ * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late accumulate
+ * event (i.e. the accumulate events call occurs in the wrong bucket).
+ */
+TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Condition change to true.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
+                return true;
+            }))
+            // Dump report requested.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 100, 15));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    // Condition change event.
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
+
+    // Bucket boundary pull.
+    vector<shared_ptr<LogEvent>> allData;
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15));
+    valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
+
+    allData.clear();
+    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 20));
+
+    // Late accumulateEvents event.
+    valueProducer->accumulateEvents(allData, bucket2StartTimeNs - 100, bucket2StartTimeNs - 100);
+
+    // Check dump report.
+    ProtoOutputStream output;
+    std::set<string> strSet;
+    valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
+                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
+
+    StatsLogReport report = outputStreamToProto(&output);
+    EXPECT_TRUE(report.has_value_metrics());
+    EXPECT_EQ(1, report.value_metrics().data_size());
+    EXPECT_EQ(1, report.value_metrics().skipped_size());
+
+    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
+              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
+    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
+              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
+    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+
+    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
+    EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
+    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
+}
+
+/*
+ * Test that CONDITION_UNKNOWN dump reason is logged due to an unknown condition
+ * when a metric is initialized.
+ */
+TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Condition change to true.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
+                return true;
+            }))
+            // Dump report requested.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 100, 15));
+                return true;
+            }));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithNoInitialCondition(pullerManager,
+                                                                                     metric);
+
+    // Condition change event.
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
+
+    // Check dump report.
+    ProtoOutputStream output;
+    std::set<string> strSet;
+    int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
+    valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
+                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
+
+    StatsLogReport report = outputStreamToProto(&output);
+    EXPECT_TRUE(report.has_value_metrics());
+    EXPECT_EQ(0, report.value_metrics().data_size());
+    EXPECT_EQ(1, report.value_metrics().skipped_size());
+
+    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
+              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
+    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
+              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
+    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+
+    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
+    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
+    EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
+}
+
+/*
+ * Test that PULL_FAILED dump reason is logged due to a pull failure in
+ * #pullAndMatchEventsLocked.
+ */
+TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) {
+    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Condition change to true.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
+                return true;
+            }))
+            // Dump report requested, pull fails.
+            .WillOnce(Return(false));
+
+    sp<ValueMetricProducer> valueProducer =
+            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+
+    // Condition change event.
+    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
+
+    // Check dump report.
+    ProtoOutputStream output;
+    std::set<string> strSet;
+    int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
+    valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
+                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
+
+    StatsLogReport report = outputStreamToProto(&output);
+    EXPECT_TRUE(report.has_value_metrics());
+    EXPECT_EQ(0, report.value_metrics().data_size());
+    EXPECT_EQ(1, report.value_metrics().skipped_size());
+
+    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
+              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
+    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
+              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
+    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+
+    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
+    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
+    EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
+}
+
 ///*
 // * Test that MULTIPLE_BUCKETS_SKIPPED dump reason is logged when a log event
 // * skips over more than one bucket.
 // */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenMultipleBucketsSkipped) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenMultipleBucketsSkipped) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3624,7 +3419,8 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    // Condition change event.
 //    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
@@ -3635,7 +3431,8 @@
 //    // Check dump report.
 //    ProtoOutputStream output;
 //    std::set<string> strSet;
-//    valueProducer->onDumpReport(bucket4StartTimeNs + 1000, true /* include recent buckets */, true,
+//    valueProducer->onDumpReport(bucket4StartTimeNs + 1000, true /* include recent buckets */,
+//    true,
 //                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
 //
 //    StatsLogReport report = outputStreamToProto(&output);
@@ -3658,7 +3455,7 @@
 // * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
 // * is smaller than the "min_bucket_size_nanos" specified in the metric config.
 // */
-//TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //    metric.set_min_bucket_size_nanos(10000000000);  // 10 seconds
 //
@@ -3687,7 +3484,8 @@
 //            }));
 //
 //    sp<ValueMetricProducer> valueProducer =
-//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+//            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+//            metric);
 //
 //    // Condition change event.
 //    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
@@ -3718,7 +3516,7 @@
 ///*
 // * Test multiple bucket drop events in the same bucket.
 // */
-//TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3772,7 +3570,7 @@
 // * Test that the number of logged bucket drop events is capped at the maximum.
 // * The maximum is currently 10 and is set in MetricProducer::maxDropEventsReached().
 // */
-//TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) {
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 //
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3800,10 +3598,8 @@
 //            .WillOnce(Return(false))
 //            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
 //                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 220);
-//                event->write("field1");
-//                event->write(10);
-//                event->init();
+//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs +
+//                220); event->write("field1"); event->write(10); event->init();
 //                data->push_back(event);
 //                return true;
 //            }));
@@ -3896,7 +3692,7 @@
 // * - Using diff
 // * - Second field is value field
 // */
-//TEST(ValueMetricProducerTest, TestSlicedState) {
+// TEST(ValueMetricProducerTest, TestSlicedState) {
 //    // Set up ValueMetricProducer.
 //    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE");
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3954,7 +3750,7 @@
 //
 //    sp<ValueMetricProducer> valueProducer =
 //            ValueMetricProducerTestHelper::createValueProducerWithState(
-//                    pullerManager, metric, {android::util::SCREEN_STATE_CHANGED}, {});
+//                    pullerManager, metric, {util::SCREEN_STATE_CHANGED}, {});
 //
 //    // Set up StateManager and check that StateTrackers are initialized.
 //    StateManager::getInstance().clear();
@@ -3987,7 +3783,8 @@
 //    EXPECT_EQ(2, it->second[0].value.long_value);
 //
 //    // Bucket status after screen state change ON->OFF.
-//    screenEvent = CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
+//    screenEvent =
+//    CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
 //                                                bucketStartTimeNs + 10);
 //    StateManager::getInstance().onLogEvent(*screenEvent);
 //    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
@@ -4067,9 +3864,10 @@
 // * - Using diff
 // * - Second field is value field
 // */
-//TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
+// TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
 //    // Set up ValueMetricProducer.
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE_ONOFF");
+//    ValueMetric metric =
+//    ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE_ONOFF");
 //    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 //    EXPECT_CALL(*pullerManager, Pull(tagId, _))
 //            // ValueMetricProducer initialized.
@@ -4136,7 +3934,7 @@
 //
 //    sp<ValueMetricProducer> valueProducer =
 //            ValueMetricProducerTestHelper::createValueProducerWithState(
-//                    pullerManager, metric, {android::util::SCREEN_STATE_CHANGED}, stateGroupMap);
+//                    pullerManager, metric, {util::SCREEN_STATE_CHANGED}, stateGroupMap);
 //
 //    // Set up StateManager and check that StateTrackers are initialized.
 //    StateManager::getInstance().clear();
@@ -4189,7 +3987,8 @@
 //    EXPECT_EQ(2, it->second[0].value.long_value);
 //
 //    // Bucket status after screen state change VR->OFF.
-//    screenEvent = CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
+//    screenEvent =
+//    CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
 //                                                bucketStartTimeNs + 15);
 //    StateManager::getInstance().onLogEvent(*screenEvent);
 //    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
@@ -4243,9 +4042,10 @@
 // * - Using diff
 // * - Second field is value field
 // */
-//TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
+// TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
 //    // Set up ValueMetricProducer.
-//    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("UID_PROCESS_STATE");
+//    ValueMetric metric =
+//    ValueMetricProducerTestHelper::createMetricWithState("UID_PROCESS_STATE");
 //    metric.mutable_dimensions_in_what()->set_field(tagId);
 //    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
 //
@@ -4311,10 +4111,8 @@
 //            // Uid 1 process state change from Foreground -> Background
 //            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
 //                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 20);
-//                event->write(1 /* uid */);
-//                event->write(13);
-//                event->init();
+//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+//                20); event->write(1 /* uid */); event->write(13); event->init();
 //                data->push_back(event);
 //
 //                // This event should be skipped.
@@ -4328,10 +4126,8 @@
 //            // Uid 1 process state change from Background -> Foreground
 //            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
 //                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 40);
-//                event->write(1 /* uid */);
-//                event->write(17);
-//                event->init();
+//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+//                40); event->write(1 /* uid */); event->write(17); event->init();
 //                data->push_back(event);
 //
 //                // This event should be skipped.
@@ -4345,10 +4141,8 @@
 //            // Dump report pull.
 //            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
 //                data->clear();
-//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 50);
-//                event->write(2 /* uid */);
-//                event->write(20);
-//                event->init();
+//                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+//                50); event->write(2 /* uid */); event->write(20); event->init();
 //                data->push_back(event);
 //
 //                event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 50);
@@ -4393,7 +4187,8 @@
 //
 //    // Bucket status after uid 1 process state change kStateUnknown -> Foreground.
 //    auto uidProcessEvent = CreateUidProcessStateChangedEvent(
-//            1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, bucketStartTimeNs + 20);
+//            1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, bucketStartTimeNs +
+//            20);
 //    StateManager::getInstance().onLogEvent(*uidProcessEvent);
 //    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
 //    // Base for dimension key {uid 1}.
@@ -4420,7 +4215,8 @@
 //
 //    // Bucket status after uid 2 process state change kStateUnknown -> Background.
 //    uidProcessEvent = CreateUidProcessStateChangedEvent(
-//            2 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, bucketStartTimeNs + 40);
+//            2 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, bucketStartTimeNs +
+//            40);
 //    StateManager::getInstance().onLogEvent(*uidProcessEvent);
 //    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
 //    // Base for dimension key {uid 1}.
@@ -4499,7 +4295,8 @@
 //
 //    // Bucket status after uid 1 process state change from Foreground -> Background.
 //    uidProcessEvent = CreateUidProcessStateChangedEvent(
-//            1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, bucket2StartTimeNs + 20);
+//            1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, bucket2StartTimeNs +
+//            20);
 //    StateManager::getInstance().onLogEvent(*uidProcessEvent);
 //
 //    EXPECT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
@@ -4533,7 +4330,8 @@
 //
 //    // Bucket status after uid 1 process state change Background->Foreground.
 //    uidProcessEvent = CreateUidProcessStateChangedEvent(
-//            1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, bucket2StartTimeNs + 40);
+//            1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, bucket2StartTimeNs +
+//            40);
 //    StateManager::getInstance().onLogEvent(*uidProcessEvent);
 //
 //    EXPECT_EQ(5UL, valueProducer->mCurrentSlicedBucket.size());
diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp
index 36c0f32..b1633c6 100644
--- a/cmds/statsd/tests/state/StateTracker_test.cpp
+++ b/cmds/statsd/tests/state/StateTracker_test.cpp
@@ -61,7 +61,7 @@
 //// State with no primary fields - ScreenStateChanged
 //std::shared_ptr<LogEvent> buildScreenEvent(int state) {
 //    std::shared_ptr<LogEvent> event =
-//            std::make_shared<LogEvent>(android::util::SCREEN_STATE_CHANGED, 1000 /*timestamp*/);
+//            std::make_shared<LogEvent>(util::SCREEN_STATE_CHANGED, 1000 /*timestamp*/);
 //    event->write((int32_t)state);
 //    event->init();
 //    return event;
@@ -70,7 +70,7 @@
 //// State with one primary field - UidProcessStateChanged
 //std::shared_ptr<LogEvent> buildUidProcessEvent(int uid, int state) {
 //    std::shared_ptr<LogEvent> event =
-//            std::make_shared<LogEvent>(android::util::UID_PROCESS_STATE_CHANGED, 1000 /*timestamp*/);
+//            std::make_shared<LogEvent>(util::UID_PROCESS_STATE_CHANGED, 1000 /*timestamp*/);
 //    event->write((int32_t)uid);
 //    event->write((int32_t)state);
 //    event->init();
@@ -85,7 +85,7 @@
 //    attr.set_uid(uid);
 //
 //    std::shared_ptr<LogEvent> event =
-//            std::make_shared<LogEvent>(android::util::WAKELOCK_STATE_CHANGED, 1000 /* timestamp */);
+//            std::make_shared<LogEvent>(util::WAKELOCK_STATE_CHANGED, 1000 /* timestamp */);
 //    event->write(chain);
 //    event->write((int32_t)1);  // PARTIAL_WAKE_LOCK
 //    event->write(tag);
@@ -97,7 +97,7 @@
 //// State with multiple primary fields - OverlayStateChanged
 //std::shared_ptr<LogEvent> buildOverlayEvent(int uid, const std::string& packageName, int state) {
 //    std::shared_ptr<LogEvent> event =
-//            std::make_shared<LogEvent>(android::util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
+//            std::make_shared<LogEvent>(util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
 //    event->write((int32_t)uid);
 //    event->write(packageName);
 //    event->write(true);  // using_alert_window
@@ -109,7 +109,7 @@
 //// Incorrect event - missing fields
 //std::shared_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName, int state) {
 //    std::shared_ptr<LogEvent> event =
-//            std::make_shared<LogEvent>(android::util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
+//            std::make_shared<LogEvent>(util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
 //    event->write((int32_t)uid);
 //    event->write(packageName);
 //    event->write((int32_t)state);
@@ -120,7 +120,7 @@
 //// Incorrect event - exclusive state has wrong type
 //std::shared_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) {
 //    std::shared_ptr<LogEvent> event =
-//            std::make_shared<LogEvent>(android::util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
+//            std::make_shared<LogEvent>(util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/);
 //    event->write((int32_t)uid);
 //    event->write(packageName);
 //    event->write(true);
@@ -136,7 +136,7 @@
 //    attr.set_uid(uid);
 //
 //    std::shared_ptr<LogEvent> event =
-//            std::make_shared<LogEvent>(android::util::BLE_SCAN_STATE_CHANGED, 1000);
+//            std::make_shared<LogEvent>(util::BLE_SCAN_STATE_CHANGED, 1000);
 //    event->write(chain);
 //    event->write(reset ? 2 : acquire ? 1 : 0);  // PARTIAL_WAKE_LOCK
 //    event->write(0);                            // filtered
@@ -216,7 +216,7 @@
     StateManager& mgr = StateManager::getInstance();
     mgr.clear();
 
-    mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener1);
+    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
     EXPECT_EQ(1, mgr.getStateTrackersCount());
     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
 }
@@ -236,22 +236,22 @@
 
     // Register listener to non-existing StateTracker
     EXPECT_EQ(0, mgr.getStateTrackersCount());
-    EXPECT_TRUE(mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener1));
+    EXPECT_TRUE(mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1));
     EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, mgr.getListenersCount(android::util::SCREEN_STATE_CHANGED));
+    EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
 
     // Register listener to existing StateTracker
-    EXPECT_TRUE(mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener2));
+    EXPECT_TRUE(mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2));
     EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(2, mgr.getListenersCount(android::util::SCREEN_STATE_CHANGED));
+    EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
 
     // Register already registered listener to existing StateTracker
-    EXPECT_TRUE(mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener2));
+    EXPECT_TRUE(mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2));
     EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(2, mgr.getListenersCount(android::util::SCREEN_STATE_CHANGED));
+    EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
 
     // Register listener to non-state atom
-    EXPECT_FALSE(mgr.registerListener(android::util::BATTERY_LEVEL_CHANGED, listener2));
+    EXPECT_FALSE(mgr.registerListener(util::BATTERY_LEVEL_CHANGED, listener2));
     EXPECT_EQ(1, mgr.getStateTrackersCount());
 }
 
@@ -270,28 +270,28 @@
 
     // Unregister listener from non-existing StateTracker
     EXPECT_EQ(0, mgr.getStateTrackersCount());
-    mgr.unregisterListener(android::util::SCREEN_STATE_CHANGED, listener1);
+    mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener1);
     EXPECT_EQ(0, mgr.getStateTrackersCount());
-    EXPECT_EQ(-1, mgr.getListenersCount(android::util::SCREEN_STATE_CHANGED));
+    EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
 
     // Unregister non-registered listener from existing StateTracker
-    mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener1);
+    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
     EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, mgr.getListenersCount(android::util::SCREEN_STATE_CHANGED));
-    mgr.unregisterListener(android::util::SCREEN_STATE_CHANGED, listener2);
+    EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
+    mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener2);
     EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, mgr.getListenersCount(android::util::SCREEN_STATE_CHANGED));
+    EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
 
     // Unregister second-to-last listener from StateTracker
-    mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener2);
-    mgr.unregisterListener(android::util::SCREEN_STATE_CHANGED, listener1);
+    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
+    mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener1);
     EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, mgr.getListenersCount(android::util::SCREEN_STATE_CHANGED));
+    EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
 
     // Unregister last listener from StateTracker
-    mgr.unregisterListener(android::util::SCREEN_STATE_CHANGED, listener2);
+    mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener2);
     EXPECT_EQ(0, mgr.getStateTrackersCount());
-    EXPECT_EQ(-1, mgr.getListenersCount(android::util::SCREEN_STATE_CHANGED));
+    EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
 }
 // TODO(b/149590301): Update these tests to use new socket schema.
 ///**
@@ -305,7 +305,7 @@
 //TEST(StateTrackerTest, TestStateChangeNested) {
 //    sp<TestStateListener> listener = new TestStateListener();
 //    StateManager mgr;
-//    mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener);
+//    mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener);
 //
 //    std::shared_ptr<LogEvent> event1 =
 //            buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/);
@@ -342,7 +342,7 @@
 //TEST(StateTrackerTest, TestStateChangeReset) {
 //    sp<TestStateListener> listener = new TestStateListener();
 //    StateManager mgr;
-//    mgr.registerListener(android::util::BLE_SCAN_STATE_CHANGED, listener);
+//    mgr.registerListener(util::BLE_SCAN_STATE_CHANGED, listener);
 //
 //    std::shared_ptr<LogEvent> event1 =
 //            buildBleScanEvent(1000 /* uid */, true /*acquire*/, false /*reset*/);
@@ -375,7 +375,7 @@
 //TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) {
 //    sp<TestStateListener> listener1 = new TestStateListener();
 //    StateManager mgr;
-//    mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener1);
+//    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
 //
 //    // log event
 //    std::shared_ptr<LogEvent> event =
@@ -390,7 +390,7 @@
 //    // check StateTracker was updated by querying for state
 //    HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
 //    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-//              getStateInt(mgr, android::util::SCREEN_STATE_CHANGED, queryKey));
+//              getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
 //}
 //
 ///**
@@ -400,7 +400,7 @@
 //TEST(StateTrackerTest, TestStateChangeOnePrimaryField) {
 //    sp<TestStateListener> listener1 = new TestStateListener();
 //    StateManager mgr;
-//    mgr.registerListener(android::util::UID_PROCESS_STATE_CHANGED, listener1);
+//    mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener1);
 //
 //    // log event
 //    std::shared_ptr<LogEvent> event =
@@ -416,13 +416,13 @@
 //    HashableDimensionKey queryKey;
 //    getUidProcessKey(1000 /* uid */, &queryKey);
 //    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
-//              getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED, queryKey));
+//              getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey));
 //}
 //
 //TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) {
 //    sp<TestStateListener> listener1 = new TestStateListener();
 //    StateManager mgr;
-//    mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener1);
+//    mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener1);
 //
 //    // Log event.
 //    std::shared_ptr<LogEvent> event =
@@ -430,7 +430,7 @@
 //    mgr.onLogEvent(*event);
 //
 //    EXPECT_EQ(1, mgr.getStateTrackersCount());
-//    EXPECT_EQ(1, mgr.getListenersCount(android::util::WAKELOCK_STATE_CHANGED));
+//    EXPECT_EQ(1, mgr.getListenersCount(util::WAKELOCK_STATE_CHANGED));
 //
 //    // Check listener was updated.
 //    EXPECT_EQ(1, listener1->updates.size());
@@ -444,19 +444,19 @@
 //    HashableDimensionKey queryKey;
 //    getPartialWakelockKey(1001 /* uid */, "tag1", &queryKey);
 //    EXPECT_EQ(WakelockStateChanged::ACQUIRE,
-//              getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey));
+//              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey));
 //
 //    // No state stored for this query key.
 //    HashableDimensionKey queryKey2;
 //    getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2);
 //    EXPECT_EQ(WakelockStateChanged::RELEASE,
-//              getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey2));
+//              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey2));
 //
 //    // Partial query fails.
 //    HashableDimensionKey queryKey3;
 //    getPartialWakelockKey(1001 /* uid */, &queryKey3);
 //    EXPECT_EQ(WakelockStateChanged::RELEASE,
-//              getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey3));
+//              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey3));
 //}
 //
 ///**
@@ -466,7 +466,7 @@
 //TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) {
 //    sp<TestStateListener> listener1 = new TestStateListener();
 //    StateManager mgr;
-//    mgr.registerListener(android::util::OVERLAY_STATE_CHANGED, listener1);
+//    mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
 //
 //    // log event
 //    std::shared_ptr<LogEvent> event =
@@ -482,7 +482,7 @@
 //    HashableDimensionKey queryKey;
 //    getOverlayKey(1000 /* uid */, "package1", &queryKey);
 //    EXPECT_EQ(OverlayStateChanged::ENTERED,
-//              getStateInt(mgr, android::util::OVERLAY_STATE_CHANGED, queryKey));
+//              getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey));
 //}
 //
 ///**
@@ -493,7 +493,7 @@
 //TEST(StateTrackerTest, TestStateChangeEventError) {
 //    sp<TestStateListener> listener1 = new TestStateListener();
 //    StateManager mgr;
-//    mgr.registerListener(android::util::OVERLAY_STATE_CHANGED, listener1);
+//    mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
 //
 //    // log event
 //    std::shared_ptr<LogEvent> event1 =
@@ -513,10 +513,10 @@
 //    sp<TestStateListener> listener3 = new TestStateListener();
 //    sp<TestStateListener> listener4 = new TestStateListener();
 //    StateManager mgr;
-//    mgr.registerListener(android::util::SCREEN_STATE_CHANGED, listener1);
-//    mgr.registerListener(android::util::UID_PROCESS_STATE_CHANGED, listener2);
-//    mgr.registerListener(android::util::OVERLAY_STATE_CHANGED, listener3);
-//    mgr.registerListener(android::util::WAKELOCK_STATE_CHANGED, listener4);
+//    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
+//    mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener2);
+//    mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener3);
+//    mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener4);
 //
 //    std::shared_ptr<LogEvent> event1 = buildUidProcessEvent(
 //            1000,
@@ -554,40 +554,40 @@
 //    HashableDimensionKey queryKey1;
 //    getUidProcessKey(1001, &queryKey1);
 //    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
-//              getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED, queryKey1));
+//              getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
 //
 //    // Query for UidProcessState of uid 1004 - not in state map
 //    HashableDimensionKey queryKey2;
 //    getUidProcessKey(1004, &queryKey2);
-//    EXPECT_EQ(-1, getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED,
+//    EXPECT_EQ(-1, getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED,
 //                              queryKey2));  // default state
 //
 //    // Query for UidProcessState of uid 1001 - after change in state
 //    mgr.onLogEvent(*event4);
 //    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
-//              getStateInt(mgr, android::util::UID_PROCESS_STATE_CHANGED, queryKey1));
+//              getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
 //
 //    // Query for ScreenState
 //    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-//              getStateInt(mgr, android::util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY));
+//              getStateInt(mgr, util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY));
 //
 //    // Query for OverlayState of uid 1000, package name "package2"
 //    HashableDimensionKey queryKey3;
 //    getOverlayKey(1000, "package2", &queryKey3);
 //    EXPECT_EQ(OverlayStateChanged::EXITED,
-//              getStateInt(mgr, android::util::OVERLAY_STATE_CHANGED, queryKey3));
+//              getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey3));
 //
 //    // Query for WakelockState of uid 1005, tag 2
 //    HashableDimensionKey queryKey4;
 //    getPartialWakelockKey(1005, "tag2", &queryKey4);
 //    EXPECT_EQ(WakelockStateChanged::RELEASE,
-//              getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey4));
+//              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey4));
 //
 //    // Query for WakelockState of uid 1005, tag 1
 //    HashableDimensionKey queryKey5;
 //    getPartialWakelockKey(1005, "tag1", &queryKey5);
 //    EXPECT_EQ(WakelockStateChanged::ACQUIRE,
-//              getStateInt(mgr, android::util::WAKELOCK_STATE_CHANGED, queryKey5));
+//              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey5));
 //}
 
 }  // namespace statsd
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index e2eee03..050dbf8 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -51,7 +51,7 @@
 }
 
 AtomMatcher CreateTemperatureAtomMatcher() {
-    return CreateSimpleAtomMatcher("TemperatureMatcher", android::util::TEMPERATURE);
+    return CreateSimpleAtomMatcher("TemperatureMatcher", util::TEMPERATURE);
 }
 
 AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
@@ -59,7 +59,7 @@
     AtomMatcher atom_matcher;
     atom_matcher.set_id(StringToId(name));
     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::SCHEDULED_JOB_STATE_CHANGED);
+    simple_atom_matcher->set_atom_id(util::SCHEDULED_JOB_STATE_CHANGED);
     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     field_value_matcher->set_field(3);  // State field.
     field_value_matcher->set_eq_int(state);
@@ -80,7 +80,7 @@
     AtomMatcher atom_matcher;
     atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::SCREEN_BRIGHTNESS_CHANGED);
+    simple_atom_matcher->set_atom_id(util::SCREEN_BRIGHTNESS_CHANGED);
     return atom_matcher;
 }
 
@@ -88,7 +88,7 @@
     AtomMatcher atom_matcher;
     atom_matcher.set_id(StringToId("UidProcessStateChanged"));
     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::UID_PROCESS_STATE_CHANGED);
+    simple_atom_matcher->set_atom_id(util::UID_PROCESS_STATE_CHANGED);
     return atom_matcher;
 }
 
@@ -97,7 +97,7 @@
     AtomMatcher atom_matcher;
     atom_matcher.set_id(StringToId(name));
     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::WAKELOCK_STATE_CHANGED);
+    simple_atom_matcher->set_atom_id(util::WAKELOCK_STATE_CHANGED);
     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     field_value_matcher->set_field(4);  // State field.
     field_value_matcher->set_eq_int(state);
@@ -117,7 +117,7 @@
     AtomMatcher atom_matcher;
     atom_matcher.set_id(StringToId(name));
     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::BATTERY_SAVER_MODE_STATE_CHANGED);
+    simple_atom_matcher->set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);
     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     field_value_matcher->set_field(1);  // State field.
     field_value_matcher->set_eq_int(state);
@@ -141,7 +141,7 @@
     AtomMatcher atom_matcher;
     atom_matcher.set_id(StringToId(name));
     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::SCREEN_STATE_CHANGED);
+    simple_atom_matcher->set_atom_id(util::SCREEN_STATE_CHANGED);
     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     field_value_matcher->set_field(1);  // State field.
     field_value_matcher->set_eq_int(state);
@@ -164,7 +164,7 @@
     AtomMatcher atom_matcher;
     atom_matcher.set_id(StringToId(name));
     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::SYNC_STATE_CHANGED);
+    simple_atom_matcher->set_atom_id(util::SYNC_STATE_CHANGED);
     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     field_value_matcher->set_field(3);  // State field.
     field_value_matcher->set_eq_int(state);
@@ -184,7 +184,7 @@
     AtomMatcher atom_matcher;
     atom_matcher.set_id(StringToId(name));
     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
+    simple_atom_matcher->set_atom_id(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     field_value_matcher->set_field(4);  // Activity field.
     field_value_matcher->set_eq_int(state);
@@ -206,7 +206,7 @@
     AtomMatcher atom_matcher;
     atom_matcher.set_id(StringToId(name));
     auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    simple_atom_matcher->set_atom_id(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
     field_value_matcher->set_field(3);  // Process state field.
     field_value_matcher->set_eq_int(state);
@@ -277,28 +277,28 @@
 State CreateScreenState() {
     State state;
     state.set_id(StringToId("ScreenState"));
-    state.set_atom_id(android::util::SCREEN_STATE_CHANGED);
+    state.set_atom_id(util::SCREEN_STATE_CHANGED);
     return state;
 }
 
 State CreateUidProcessState() {
     State state;
     state.set_id(StringToId("UidProcessState"));
-    state.set_atom_id(android::util::UID_PROCESS_STATE_CHANGED);
+    state.set_atom_id(util::UID_PROCESS_STATE_CHANGED);
     return state;
 }
 
 State CreateOverlayState() {
     State state;
     state.set_id(StringToId("OverlayState"));
-    state.set_atom_id(android::util::OVERLAY_STATE_CHANGED);
+    state.set_atom_id(util::OVERLAY_STATE_CHANGED);
     return state;
 }
 
 State CreateScreenStateWithOnOffMap() {
     State state;
     state.set_id(StringToId("ScreenStateOnOff"));
-    state.set_atom_id(android::util::SCREEN_STATE_CHANGED);
+    state.set_atom_id(util::SCREEN_STATE_CHANGED);
 
     auto map = CreateScreenStateOnOffMap();
     *state.mutable_map() = map;
@@ -309,7 +309,7 @@
 State CreateScreenStateWithInDozeMap() {
     State state;
     state.set_id(StringToId("ScreenStateInDoze"));
-    state.set_atom_id(android::util::SCREEN_STATE_CHANGED);
+    state.set_atom_id(util::SCREEN_STATE_CHANGED);
 
     auto map = CreateScreenStateInDozeMap();
     *state.mutable_map() = map;
@@ -410,10 +410,131 @@
     return dimensions;
 }
 
+shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
+                                            int32_t value2) {
+    AStatsEvent* statsEvent = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(statsEvent, atomId);
+    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+    AStatsEvent_writeInt32(statsEvent, value1);
+    AStatsEvent_writeInt32(statsEvent, value2);
+    AStatsEvent_build(statsEvent);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
+    logEvent->parseBuffer(buf, size);
+    AStatsEvent_release(statsEvent);
+
+    return logEvent;
+}
+//
+void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
+                            int32_t value2) {
+    AStatsEvent* statsEvent = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(statsEvent, atomId);
+    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+    AStatsEvent_writeInt32(statsEvent, value1);
+    AStatsEvent_writeInt32(statsEvent, value2);
+    AStatsEvent_build(statsEvent);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+    logEvent->parseBuffer(buf, size);
+    AStatsEvent_release(statsEvent);
+}
+
+shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
+                                              int32_t value2, int32_t value3) {
+    AStatsEvent* statsEvent = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(statsEvent, atomId);
+    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+    AStatsEvent_writeInt32(statsEvent, value1);
+    AStatsEvent_writeInt32(statsEvent, value2);
+    AStatsEvent_writeInt32(statsEvent, value3);
+    AStatsEvent_build(statsEvent);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
+    logEvent->parseBuffer(buf, size);
+    AStatsEvent_release(statsEvent);
+
+    return logEvent;
+}
+
+void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
+                              int32_t value2, int32_t value3) {
+    AStatsEvent* statsEvent = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(statsEvent, atomId);
+    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+    AStatsEvent_writeInt32(statsEvent, value1);
+    AStatsEvent_writeInt32(statsEvent, value2);
+    AStatsEvent_writeInt32(statsEvent, value3);
+    AStatsEvent_build(statsEvent);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+    logEvent->parseBuffer(buf, size);
+    AStatsEvent_release(statsEvent);
+}
+
+shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) {
+    AStatsEvent* statsEvent = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(statsEvent, atomId);
+    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+    AStatsEvent_writeInt32(statsEvent, value);
+    AStatsEvent_writeInt32(statsEvent, value);
+    AStatsEvent_build(statsEvent);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
+    logEvent->parseBuffer(buf, size);
+    AStatsEvent_release(statsEvent);
+
+    return logEvent;
+}
+
+void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
+                                 int32_t value) {
+    AStatsEvent* statsEvent = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(statsEvent, atomId);
+    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+    AStatsEvent_writeInt32(statsEvent, value);
+    AStatsEvent_writeInt32(statsEvent, value);
+    AStatsEvent_build(statsEvent);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+    logEvent->parseBuffer(buf, size);
+    AStatsEvent_release(statsEvent);
+}
+
+shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) {
+    AStatsEvent* statsEvent = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(statsEvent, atomId);
+    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+    AStatsEvent_build(statsEvent);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
+    logEvent->parseBuffer(buf, size);
+    AStatsEvent_release(statsEvent);
+
+    return logEvent;
+}
+
 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
         uint64_t timestampNs, const android::view::DisplayStateEnum state) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::SCREEN_STATE_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, state);
@@ -430,7 +551,7 @@
 
 std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::BATTERY_SAVER_MODE_STATE_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON);
@@ -447,7 +568,7 @@
 
 std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::BATTERY_SAVER_MODE_STATE_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF);
@@ -464,7 +585,7 @@
 
 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::SCREEN_BRIGHTNESS_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::SCREEN_BRIGHTNESS_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, level);
@@ -482,7 +603,7 @@
 //std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
 //        const std::vector<AttributionNodeInternal>& attributions, const string& jobName,
 //        const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
-//    auto event = std::make_unique<LogEvent>(android::util::SCHEDULED_JOB_STATE_CHANGED, timestampNs);
+//    auto event = std::make_unique<LogEvent>(util::SCHEDULED_JOB_STATE_CHANGED, timestampNs);
 //    event->write(attributions);
 //    event->write(jobName);
 //    event->write(state);
@@ -511,7 +632,7 @@
                                                           const string& wakelockName,
                                                           const WakelockStateChanged::State state) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::WAKELOCK_STATE_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::WAKELOCK_STATE_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     vector<const char*> cTags(attributionTags.size());
@@ -555,7 +676,7 @@
 std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
         uint64_t timestampNs, const int uid, const ActivityForegroundStateChanged::State state) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::ACTIVITY_FOREGROUND_STATE_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, uid);
@@ -589,7 +710,7 @@
                                                       const string& name,
                                                       const SyncStateChanged::State state) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::SYNC_STATE_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     vector<const char*> cTags(attributionTags.size());
@@ -632,7 +753,7 @@
 std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
         uint64_t timestampNs, const int uid, const ProcessLifeCycleStateChanged::State state) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, uid);
@@ -656,7 +777,7 @@
 
 std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::APP_CRASH_OCCURRED);
+    AStatsEvent_setAtomId(statsEvent, util::APP_CRASH_OCCURRED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, uid);
@@ -676,7 +797,7 @@
 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
                                                         int isolatedUid, bool is_create) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::ISOLATED_UID_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::ISOLATED_UID_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, hostUid);
@@ -696,7 +817,7 @@
 std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
         uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, android::util::UID_PROCESS_STATE_CHANGED);
+    AStatsEvent_setAtomId(statsEvent, util::UID_PROCESS_STATE_CHANGED);
     AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
 
     AStatsEvent_writeInt32(statsEvent, uid);
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index 4371015..ead041c 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -25,7 +25,7 @@
 #include "src/hash.h"
 #include "src/logd/LogEvent.h"
 #include "src/stats_log_util.h"
-#include "statslog.h"
+#include "statslog_statsdtest.h"
 
 namespace android {
 namespace os {
@@ -38,8 +38,8 @@
 using google::protobuf::RepeatedPtrField;
 using Status = ::ndk::ScopedAStatus;
 
-const int SCREEN_STATE_ATOM_ID = android::util::SCREEN_STATE_CHANGED;
-const int UID_PROCESS_STATE_ATOM_ID = android::util::UID_PROCESS_STATE_CHANGED;
+const int SCREEN_STATE_ATOM_ID = util::SCREEN_STATE_CHANGED;
+const int UID_PROCESS_STATE_ATOM_ID = util::UID_PROCESS_STATE_CHANGED;
 
 // Converts a ProtoOutputStream to a StatsLogReport proto.
 StatsLogReport outputStreamToProto(ProtoOutputStream* proto);
@@ -164,6 +164,29 @@
 FieldMatcher CreateAttributionUidDimensions(const int atomId,
                                             const std::vector<Position>& positions);
 
+shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
+                                            int32_t value2);
+
+void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
+                            int32_t value2);
+
+shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
+                                              int32_t value2, int32_t value3);
+
+void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
+                              int32_t value2, int32_t value3);
+
+// The repeated value log event helpers create a log event with two int fields, both
+// set to the same value. This is useful for testing metrics that are only interested
+// in the value of the second field but still need the first field to be populated.
+std::shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs,
+                                                      int32_t value);
+
+void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
+                                 int32_t value);
+
+std::shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs);
+
 // Create log event for screen state changed.
 std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
         uint64_t timestampNs, const android::view::DisplayStateEnum state);
diff --git a/config/hiddenapi-greylist-max-q.txt b/config/hiddenapi-greylist-max-q.txt
index a895a44..4832dd1 100644
--- a/config/hiddenapi-greylist-max-q.txt
+++ b/config/hiddenapi-greylist-max-q.txt
@@ -406,7 +406,6 @@
 Lcom/android/internal/R$string;->enable_explore_by_touch_warning_title:I
 Lcom/android/internal/R$string;->gigabyteShort:I
 Lcom/android/internal/R$string;->kilobyteShort:I
-Lcom/android/internal/R$string;->map:I
 Lcom/android/internal/R$string;->megabyteShort:I
 Lcom/android/internal/R$string;->notification_title:I
 Lcom/android/internal/R$string;->no_matches:I
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 1a92b75..b3a0be1 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1315,7 +1315,8 @@
 
         /**
          * @return The in-memory or loaded icon that represents the current state of this task.
-         * @deprecated This call is no longer supported.
+         * @deprecated This call is no longer supported. The caller should keep track of any icons
+         *             it sets for the task descriptions internally.
          */
         @Deprecated
         public Bitmap getIcon() {
@@ -3627,11 +3628,40 @@
         }
     }
 
+    /**
+     * Set custom state data for this process. It will be included in the record of
+     * {@link ApplicationExitInfo} on the death of the current calling process; the new process
+     * of the app can retrieve this state data by calling
+     * {@link ApplicationExitInfo#getProcessStateSummary} on the record returned by
+     * {@link #getHistoricalProcessExitReasons}.
+     *
+     * <p> This would be useful for the calling app to save its stateful data: if it's
+     * killed later for any reason, the new process of the app can know what the
+     * previous process of the app was doing. For instance, you could use this to encode
+     * the current level in a game, or a set of features/experiments that were enabled. Later you
+     * could analyze under what circumstances the app tends to crash or use too much memory.
+     * However, it's not suggested to rely on this to restore the applications previous UI state
+     * or so, it's only meant for analyzing application healthy status.</p>
+     *
+     * <p> System might decide to throttle the calls to this API; so call this API in a reasonable
+     * manner, excessive calls to this API could result a {@link java.lang.RuntimeException}.
+     * </p>
+     *
+     * @param state The state data
+     */
+    public void setProcessStateSummary(@Nullable byte[] state) {
+        try {
+            getService().setProcessStateSummary(state);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     /*
      * @return Whether or not the low memory kill will be reported in
      * {@link #getHistoricalProcessExitReasons}.
      *
-     * @see {@link ApplicationExitInfo#REASON_LOW_MEMORY}
+     * @see ApplicationExitInfo#REASON_LOW_MEMORY
      */
     public static boolean isLowMemoryKillReportSupported() {
         return SystemProperties.getBoolean("persist.sys.lmk.reportkills", false);
@@ -4242,8 +4272,6 @@
      *         {@code false} otherwise.
      * @hide
      */
-    @SystemApi
-    @TestApi
     @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION)
     public boolean updateMccMncConfiguration(@NonNull String mcc, @NonNull String mnc) {
         if (mcc == null || mnc == null) {
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 489a0de..f926075 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -248,7 +248,8 @@
 
     /**
      * Returns whether the given user requires credential entry at this time. This is used to
-     * intercept activity launches for work apps when the Work Challenge is present.
+     * intercept activity launches for locked work apps due to work challenge being triggered or
+     * when the profile user is yet to be unlocked.
      */
     public abstract boolean shouldConfirmCredentials(@UserIdInt int userId);
 
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index fa4aa19..9c1a861 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1386,6 +1386,7 @@
             "android:auto_revoke_permissions_if_unused";
 
     /** @hide Auto-revoke app permissions if app is unused for an extended period */
+    @SystemApi
     public static final String OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER =
             "android:auto_revoke_managed_by_installer";
 
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index 5df3257..61be01f 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -23,7 +23,9 @@
 import android.app.ActivityManager.RunningAppProcessInfo.Importance;
 import android.icu.text.SimpleDateFormat;
 import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.DebugUtils;
@@ -31,12 +33,17 @@
 import android.util.proto.ProtoOutputStream;
 import android.util.proto.WireTypeMismatchException;
 
+import com.android.internal.util.ArrayUtils;
+
+import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Date;
 import java.util.Objects;
+import java.util.zip.GZIPInputStream;
 
 /**
  * Describes the information of an application process's death.
@@ -321,85 +328,105 @@
     // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.
 
     /**
-     * @see {@link #getPid}
+     * @see #getPid
      */
     private int mPid;
 
     /**
-     * @see {@link #getRealUid}
+     * @see #getRealUid
      */
     private int mRealUid;
 
     /**
-     * @see {@link #getPackageUid}
+     * @see #getPackageUid
      */
     private int mPackageUid;
 
     /**
-     * @see {@link #getDefiningUid}
+     * @see #getDefiningUid
      */
     private int mDefiningUid;
 
     /**
-     * @see {@link #getProcessName}
+     * @see #getProcessName
      */
     private String mProcessName;
 
     /**
-     * @see {@link #getReason}
+     * @see #getReason
      */
     private @Reason int mReason;
 
     /**
-     * @see {@link #getStatus}
+     * @see #getStatus
      */
     private int mStatus;
 
     /**
-     * @see {@link #getImportance}
+     * @see #getImportance
      */
     private @Importance int mImportance;
 
     /**
-     * @see {@link #getPss}
+     * @see #getPss
      */
     private long mPss;
 
     /**
-     * @see {@link #getRss}
+     * @see #getRss
      */
     private long mRss;
 
     /**
-     * @see {@link #getTimestamp}
+     * @see #getTimestamp
      */
     private @CurrentTimeMillisLong long mTimestamp;
 
     /**
-     * @see {@link #getDescription}
+     * @see #getDescription
      */
     private @Nullable String mDescription;
 
     /**
-     * @see {@link #getSubReason}
+     * @see #getSubReason
      */
     private @SubReason int mSubReason;
 
     /**
-     * @see {@link #getConnectionGroup}
+     * @see #getConnectionGroup
      */
     private int mConnectionGroup;
 
     /**
-     * @see {@link #getPackageName}
+     * @see #getPackageName
      */
     private String mPackageName;
 
     /**
-     * @see {@link #getPackageList}
+     * @see #getPackageList
      */
     private String[] mPackageList;
 
+    /**
+     * @see #getProcessStateSummary
+     */
+    private byte[] mState;
+
+    /**
+     * The file to the trace file in the storage;
+     *
+     * for system internal use only, will not retain across processes.
+     *
+     * @see #getTraceInputStream
+     */
+    private File mTraceFile;
+
+    /**
+     * The Binder interface to retrieve the file descriptor to
+     * the trace file from the system.
+     */
+    private IAppTraceRetriever mAppTraceRetriever;
+
     /** @hide */
     @IntDef(prefix = { "REASON_" }, value = {
         REASON_UNKNOWN,
@@ -557,6 +584,54 @@
     }
 
     /**
+     * Return the state data set by calling {@link ActivityManager#setProcessStateSummary}
+     * from the process before its death.
+     *
+     * @return The process-customized data
+     * @see ActivityManager#setProcessStateSummary(byte[])
+     */
+    public @Nullable byte[] getProcessStateSummary() {
+        return mState;
+    }
+
+    /**
+     * Return the InputStream to the traces that was taken by the system
+     * prior to the death of the process; typically it'll be available when
+     * the reason is {@link #REASON_ANR}, though if the process gets an ANR
+     * but recovers, and dies for another reason later, this trace will be included
+     * in the record of {@link ApplicationExitInfo} still.
+     *
+     * @return The input stream to the traces that was taken by the system
+     *         prior to the death of the process.
+     */
+    public @Nullable InputStream getTraceInputStream() throws IOException {
+        if (mAppTraceRetriever == null) {
+            return null;
+        }
+        try {
+            final ParcelFileDescriptor fd = mAppTraceRetriever.getTraceFileDescriptor(
+                    mPackageName, mPackageUid, mPid);
+            if (fd == null) {
+                return null;
+            }
+            return new GZIPInputStream(new ParcelFileDescriptor.AutoCloseInputStream(fd));
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Similar to {@link #getTraceInputStream} but return the File object.
+     *
+     * For internal use only.
+     *
+     * @hide
+     */
+    public @Nullable File getTraceFile() {
+        return mTraceFile;
+    }
+
+    /**
      * A subtype reason in conjunction with {@link #mReason}.
      *
      * For internal use only.
@@ -569,7 +644,7 @@
 
     /**
      * The connection group this process belongs to, if there is any.
-     * @see {@link android.content.Context#updateServiceGroup}.
+     * @see android.content.Context#updateServiceGroup
      *
      * For internal use only.
      *
@@ -582,8 +657,6 @@
     /**
      * Name of first package running in this process;
      *
-     * For system internal use only, will not retain across processes.
-     *
      * @hide
      */
     public String getPackageName() {
@@ -602,7 +675,7 @@
     }
 
     /**
-     * @see {@link #getPid}
+     * @see #getPid
      *
      * @hide
      */
@@ -611,7 +684,7 @@
     }
 
     /**
-     * @see {@link #getRealUid}
+     * @see #getRealUid
      *
      * @hide
      */
@@ -620,7 +693,7 @@
     }
 
     /**
-     * @see {@link #getPackageUid}
+     * @see #getPackageUid
      *
      * @hide
      */
@@ -629,7 +702,7 @@
     }
 
     /**
-     * @see {@link #getDefiningUid}
+     * @see #getDefiningUid
      *
      * @hide
      */
@@ -638,7 +711,7 @@
     }
 
     /**
-     * @see {@link #getProcessName}
+     * @see #getProcessName
      *
      * @hide
      */
@@ -647,7 +720,7 @@
     }
 
     /**
-     * @see {@link #getReason}
+     * @see #getReason
      *
      * @hide
      */
@@ -656,7 +729,7 @@
     }
 
     /**
-     * @see {@link #getStatus}
+     * @see #getStatus
      *
      * @hide
      */
@@ -665,7 +738,7 @@
     }
 
     /**
-     * @see {@link #getImportance}
+     * @see #getImportance
      *
      * @hide
      */
@@ -674,7 +747,7 @@
     }
 
     /**
-     * @see {@link #getPss}
+     * @see #getPss
      *
      * @hide
      */
@@ -683,7 +756,7 @@
     }
 
     /**
-     * @see {@link #getRss}
+     * @see #getRss
      *
      * @hide
      */
@@ -692,7 +765,7 @@
     }
 
     /**
-     * @see {@link #getTimestamp}
+     * @see #getTimestamp
      *
      * @hide
      */
@@ -701,7 +774,7 @@
     }
 
     /**
-     * @see {@link #getDescription}
+     * @see #getDescription
      *
      * @hide
      */
@@ -710,7 +783,7 @@
     }
 
     /**
-     * @see {@link #getSubReason}
+     * @see #getSubReason
      *
      * @hide
      */
@@ -719,7 +792,7 @@
     }
 
     /**
-     * @see {@link #getConnectionGroup}
+     * @see #getConnectionGroup
      *
      * @hide
      */
@@ -728,7 +801,7 @@
     }
 
     /**
-     * @see {@link #getPackageName}
+     * @see #getPackageName
      *
      * @hide
      */
@@ -737,7 +810,7 @@
     }
 
     /**
-     * @see {@link #getPackageList}
+     * @see #getPackageList
      *
      * @hide
      */
@@ -745,6 +818,33 @@
         mPackageList = packageList;
     }
 
+    /**
+     * @see #getProcessStateSummary
+     *
+     * @hide
+     */
+    public void setProcessStateSummary(final byte[] state) {
+        mState = state;
+    }
+
+    /**
+     * @see #getTraceFile
+     *
+     * @hide
+     */
+    public void setTraceFile(final File traceFile) {
+        mTraceFile = traceFile;
+    }
+
+    /**
+     * @see #mAppTraceRetriever
+     *
+     * @hide
+     */
+    public void setAppTraceRetriever(final IAppTraceRetriever retriever) {
+        mAppTraceRetriever = retriever;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -757,6 +857,7 @@
         dest.writeInt(mPackageUid);
         dest.writeInt(mDefiningUid);
         dest.writeString(mProcessName);
+        dest.writeString(mPackageName);
         dest.writeInt(mConnectionGroup);
         dest.writeInt(mReason);
         dest.writeInt(mSubReason);
@@ -766,6 +867,13 @@
         dest.writeLong(mRss);
         dest.writeLong(mTimestamp);
         dest.writeString(mDescription);
+        dest.writeByteArray(mState);
+        if (mAppTraceRetriever != null) {
+            dest.writeInt(1);
+            dest.writeStrongBinder(mAppTraceRetriever.asBinder());
+        } else {
+            dest.writeInt(0);
+        }
     }
 
     /** @hide */
@@ -779,6 +887,7 @@
         mPackageUid = other.mPackageUid;
         mDefiningUid = other.mDefiningUid;
         mProcessName = other.mProcessName;
+        mPackageName = other.mPackageName;
         mConnectionGroup = other.mConnectionGroup;
         mReason = other.mReason;
         mStatus = other.mStatus;
@@ -790,6 +899,9 @@
         mDescription = other.mDescription;
         mPackageName = other.mPackageName;
         mPackageList = other.mPackageList;
+        mState = other.mState;
+        mTraceFile = other.mTraceFile;
+        mAppTraceRetriever = other.mAppTraceRetriever;
     }
 
     private ApplicationExitInfo(@NonNull Parcel in) {
@@ -798,6 +910,7 @@
         mPackageUid = in.readInt();
         mDefiningUid = in.readInt();
         mProcessName = in.readString();
+        mPackageName = in.readString();
         mConnectionGroup = in.readInt();
         mReason = in.readInt();
         mSubReason = in.readInt();
@@ -807,6 +920,10 @@
         mRss = in.readLong();
         mTimestamp = in.readLong();
         mDescription = in.readString();
+        mState = in.createByteArray();
+        if (in.readInt() == 1) {
+            mAppTraceRetriever = IAppTraceRetriever.Stub.asInterface(in.readStrongBinder());
+        }
     }
 
     public @NonNull static final Creator<ApplicationExitInfo> CREATOR =
@@ -839,6 +956,9 @@
         pw.print(prefix + "  pss="); DebugUtils.printSizeValue(pw, mPss << 10); pw.println();
         pw.print(prefix + "  rss="); DebugUtils.printSizeValue(pw, mRss << 10); pw.println();
         pw.println(prefix + "  description=" + mDescription);
+        pw.println(prefix + "  state=" + (ArrayUtils.isEmpty(mState)
+                ? "empty" : Integer.toString(mState.length) + " bytes"));
+        pw.println(prefix + "  trace=" + mTraceFile);
     }
 
     @Override
@@ -859,6 +979,9 @@
         sb.append(" pss="); DebugUtils.sizeValueToString(mPss << 10, sb);
         sb.append(" rss="); DebugUtils.sizeValueToString(mRss << 10, sb);
         sb.append(" description=").append(mDescription);
+        sb.append(" state=").append(ArrayUtils.isEmpty(mState)
+                ? "empty" : Integer.toString(mState.length) + " bytes");
+        sb.append(" trace=").append(mTraceFile);
         return sb.toString();
     }
 
@@ -961,6 +1084,9 @@
         proto.write(ApplicationExitInfoProto.RSS, mRss);
         proto.write(ApplicationExitInfoProto.TIMESTAMP, mTimestamp);
         proto.write(ApplicationExitInfoProto.DESCRIPTION, mDescription);
+        proto.write(ApplicationExitInfoProto.STATE, mState);
+        proto.write(ApplicationExitInfoProto.TRACE_FILE,
+                mTraceFile == null ? null : mTraceFile.getAbsolutePath());
         proto.end(token);
     }
 
@@ -1019,6 +1145,15 @@
                 case (int) ApplicationExitInfoProto.DESCRIPTION:
                     mDescription = proto.readString(ApplicationExitInfoProto.DESCRIPTION);
                     break;
+                case (int) ApplicationExitInfoProto.STATE:
+                    mState = proto.readBytes(ApplicationExitInfoProto.STATE);
+                    break;
+                case (int) ApplicationExitInfoProto.TRACE_FILE:
+                    final String path = proto.readString(ApplicationExitInfoProto.TRACE_FILE);
+                    if (!TextUtils.isEmpty(path)) {
+                        mTraceFile = new File(path);
+                    }
+                    break;
             }
         }
         proto.end(token);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 18df401..0b0a803 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3297,15 +3297,6 @@
     }
 
     @Override
-    public String[] getTelephonyPackageNames() {
-        try {
-            return mPM.getTelephonyPackageNames();
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-    }
-
-    @Override
     public String getSystemCaptionsServicePackageName() {
         try {
             return mPM.getSystemCaptionsServicePackageName();
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 6f0611e..b8221b4 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -652,4 +652,27 @@
      */
     void setActivityLocusContext(in ComponentName activity, in LocusId locusId,
             in IBinder appToken);
+
+    /**
+     * Set custom state data for this process. It will be included in the record of
+     * {@link ApplicationExitInfo} on the death of the current calling process; the new process
+     * of the app can retrieve this state data by calling
+     * {@link ApplicationExitInfo#getProcessStateSummary} on the record returned by
+     * {@link #getHistoricalProcessExitReasons}.
+     *
+     * <p> This would be useful for the calling app to save its stateful data: if it's
+     * killed later for any reason, the new process of the app can know what the
+     * previous process of the app was doing. For instance, you could use this to encode
+     * the current level in a game, or a set of features/experiments that were enabled. Later you
+     * could analyze under what circumstances the app tends to crash or use too much memory.
+     * However, it's not suggested to rely on this to restore the applications previous UI state
+     * or so, it's only meant for analyzing application healthy status.</p>
+     *
+     * <p> System might decide to throttle the calls to this API; so call this API in a reasonable
+     * manner, excessive calls to this API could result a {@link java.lang.RuntimeException}.
+     * </p>
+     *
+     * @param state The customized state data
+     */
+    void setProcessStateSummary(in byte[] state);
 }
diff --git a/core/java/android/app/IAppTraceRetriever.aidl b/core/java/android/app/IAppTraceRetriever.aidl
new file mode 100644
index 0000000..1463da7
--- /dev/null
+++ b/core/java/android/app/IAppTraceRetriever.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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 android.app;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * An interface that's to be used by {@link ApplicationExitInfo#getTraceFile()}
+ * to retrieve the actual file descriptor to its trace file.
+ *
+ * @hide
+ */
+interface IAppTraceRetriever {
+    /**
+     * Retrieve the trace file with given packageName/uid/pid.
+     *
+     * @param packagename The target package name of the trace
+     * @param uid The target UID of the trace
+     * @param pid The target PID of the trace
+     * @return The file descriptor to the trace file, or null if it's not found.
+     */
+    ParcelFileDescriptor getTraceFileDescriptor(in String packageName,
+            int uid, int pid);
+}
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index cbbdf63..811b9c0 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1015,14 +1015,15 @@
     }
 
     /**
+     * Returns the currently applied notification policy.
+     *
      * <p>
-     *  Gets the currently applied notification policy. If {@link #getCurrentInterruptionFilter}
-     * is equal to {@link #INTERRUPTION_FILTER_ALL}, then the consolidated notification policy
-     * will match the default notification policy returned by {@link #getNotificationPolicy}.
+     * If {@link #getCurrentInterruptionFilter} is equal to {@link #INTERRUPTION_FILTER_ALL},
+     * then the consolidated notification policy will match the default notification policy
+     * returned by {@link #getNotificationPolicy}.
      * </p>
      */
-    @Nullable
-    public NotificationManager.Policy getConsolidatedNotificationPolicy() {
+    public @NonNull NotificationManager.Policy getConsolidatedNotificationPolicy() {
         INotificationManager service = getService();
         try {
             return service.getConsolidatedNotificationPolicy();
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 81671c3..9f5dee9 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -250,28 +250,6 @@
         return dm;
     }
 
-    private static void applyNonDefaultDisplayMetricsToConfiguration(
-            @NonNull DisplayMetrics dm, @NonNull Configuration config) {
-        config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
-        config.densityDpi = dm.densityDpi;
-        config.screenWidthDp = (int) (dm.widthPixels / dm.density);
-        config.screenHeightDp = (int) (dm.heightPixels / dm.density);
-        int sl = Configuration.resetScreenLayout(config.screenLayout);
-        if (dm.widthPixels > dm.heightPixels) {
-            config.orientation = Configuration.ORIENTATION_LANDSCAPE;
-            config.screenLayout = Configuration.reduceScreenLayout(sl,
-                    config.screenWidthDp, config.screenHeightDp);
-        } else {
-            config.orientation = Configuration.ORIENTATION_PORTRAIT;
-            config.screenLayout = Configuration.reduceScreenLayout(sl,
-                    config.screenHeightDp, config.screenWidthDp);
-        }
-        config.smallestScreenWidthDp = Math.min(config.screenWidthDp, config.screenHeightDp);
-        config.compatScreenWidthDp = config.screenWidthDp;
-        config.compatScreenHeightDp = config.screenHeightDp;
-        config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
-    }
-
     public boolean applyCompatConfigurationLocked(int displayDensity,
             @NonNull Configuration compatConfiguration) {
         if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
@@ -519,17 +497,11 @@
 
     private Configuration generateConfig(@NonNull ResourcesKey key, @NonNull DisplayMetrics dm) {
         Configuration config;
-        final boolean isDefaultDisplay = (key.mDisplayId == Display.DEFAULT_DISPLAY);
         final boolean hasOverrideConfig = key.hasOverrideConfiguration();
-        if (!isDefaultDisplay || hasOverrideConfig) {
+        if (hasOverrideConfig) {
             config = new Configuration(getConfiguration());
-            if (!isDefaultDisplay) {
-                applyNonDefaultDisplayMetricsToConfiguration(dm, config);
-            }
-            if (hasOverrideConfig) {
-                config.updateFrom(key.mOverrideConfiguration);
-                if (DEBUG) Slog.v(TAG, "Applied overrideConfig=" + key.mOverrideConfiguration);
-            }
+            config.updateFrom(key.mOverrideConfiguration);
+            if (DEBUG) Slog.v(TAG, "Applied overrideConfig=" + key.mOverrideConfiguration);
         } else {
             config = getConfiguration();
         }
@@ -1110,8 +1082,6 @@
                     + resourcesImpl + " config to: " + config);
         }
         int displayId = key.mDisplayId;
-        final boolean hasOverrideConfiguration = key.hasOverrideConfiguration();
-        tmpConfig.setTo(config);
 
         // Get new DisplayMetrics based on the DisplayAdjustments given to the ResourcesImpl. Update
         // a copy if the CompatibilityInfo changed, because the ResourcesImpl object will handle the
@@ -1121,15 +1091,12 @@
             daj = new DisplayAdjustments(daj);
             daj.setCompatibilityInfo(compat);
         }
-        daj.setConfiguration(config);
-        DisplayMetrics dm = getDisplayMetrics(displayId, daj);
-        if (displayId != Display.DEFAULT_DISPLAY) {
-            applyNonDefaultDisplayMetricsToConfiguration(dm, tmpConfig);
-        }
-
-        if (hasOverrideConfiguration) {
+        tmpConfig.setTo(config);
+        if (key.hasOverrideConfiguration()) {
             tmpConfig.updateFrom(key.mOverrideConfiguration);
         }
+        daj.setConfiguration(tmpConfig);
+        DisplayMetrics dm = getDisplayMetrics(displayId, daj);
         resourcesImpl.updateConfiguration(tmpConfig, dm, compat);
     }
 
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 81396fe..dc8269f 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -34,7 +34,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
-import android.view.contentcapture.ContentCaptureManager;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -307,8 +306,7 @@
  * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.java
  *      bind}
  */
-public abstract class Service extends ContextWrapper implements ComponentCallbacks2,
-        ContentCaptureManager.ContentCaptureClient {
+public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
     private static final String TAG = "Service";
 
     /**
@@ -819,16 +817,8 @@
         writer.println("nothing to dump");
     }
 
-    @Override
-    protected void attachBaseContext(Context newBase) {
-        super.attachBaseContext(newBase);
-        if (newBase != null) {
-            newBase.setContentCaptureOptions(getContentCaptureOptions());
-        }
-    }
-
     // ------------------ Internal API ------------------
-
+    
     /**
      * @hide
      */
@@ -845,7 +835,6 @@
         mActivityManager = (IActivityManager)activityManager;
         mStartCompatibility = getApplicationInfo().targetSdkVersion
                 < Build.VERSION_CODES.ECLAIR;
-        setContentCaptureOptions(application.getContentCaptureOptions());
     }
 
     /**
@@ -860,18 +849,6 @@
         return mClassName;
     }
 
-    /** @hide */
-    @Override
-    public final ContentCaptureManager.ContentCaptureClient getContentCaptureClient() {
-        return this;
-    }
-
-    /** @hide */
-    @Override
-    public final ComponentName contentCaptureClientGetComponentName() {
-        return new ComponentName(this, mClassName);
-    }
-
     // set by the thread after the constructor and before onCreate(Bundle icicle) is called.
     @UnsupportedAppUsage
     private ActivityThread mThread = null;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 5b8ee71..32e815e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -11919,13 +11919,17 @@
     }
 
     /**
-     * Called by device owner or profile owner of an organization-owned managed profile to return
-     * whether Common Criteria mode is currently enabled for the device.
+     * Returns whether Common Criteria mode is currently enabled. Device owner and profile owner of
+     * an organization-owned managed profile can query its own Common Criteria mode setting by
+     * calling this method with its admin {@link ComponentName}. Any caller can obtain the
+     * aggregated device-wide Common Criteria mode state by passing {@code null} as the
+     * {@code admin} argument.
      *
-     * @param admin which {@link DeviceAdminReceiver} this request is associated with.
+     * @param admin which {@link DeviceAdminReceiver} this request is associated with, or
+     *     {@code null} if the caller is not a device admin.
      * @return {@code true} if Common Criteria mode is enabled, {@code false} otherwise.
      */
-    public boolean isCommonCriteriaModeEnabled(@NonNull ComponentName admin) {
+    public boolean isCommonCriteriaModeEnabled(@Nullable ComponentName admin) {
         throwIfParentInstance("isCommonCriteriaModeEnabled");
         if (mService != null) {
             try {
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 5b98188..d6e7762 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -29,10 +29,10 @@
 import android.net.DataUsageRequest;
 import android.net.INetworkStatsService;
 import android.net.NetworkIdentity;
+import android.net.NetworkStack;
 import android.net.NetworkTemplate;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
-import android.net.netstats.provider.NetworkStatsProviderWrapper;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
@@ -527,32 +527,53 @@
 
     /**
      * Registers a custom provider of {@link android.net.NetworkStats} to provide network statistics
-     * to the system. To unregister, invoke {@link NetworkStatsProviderCallback#unregister()}.
+     * to the system. To unregister, invoke {@link #unregisterNetworkStatsProvider}.
      * Note that no de-duplication of statistics between providers is performed, so each provider
-     * must only report network traffic that is not being reported by any other provider.
+     * must only report network traffic that is not being reported by any other provider. Also note
+     * that the provider cannot be re-registered after unregistering.
      *
      * @param tag a human readable identifier of the custom network stats provider. This is only
      *            used for debugging.
-     * @param provider the subclass of {@link AbstractNetworkStatsProvider} that needs to be
+     * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
      *                 registered to the system.
-     * @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the
-     *         system or unregister the provider.
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
-    @NonNull public NetworkStatsProviderCallback registerNetworkStatsProvider(
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_STATS_PROVIDER,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
+    @NonNull public void registerNetworkStatsProvider(
             @NonNull String tag,
-            @NonNull AbstractNetworkStatsProvider provider) {
+            @NonNull NetworkStatsProvider provider) {
         try {
-            final NetworkStatsProviderWrapper wrapper = new NetworkStatsProviderWrapper(provider);
-            return new NetworkStatsProviderCallback(
-                    mService.registerNetworkStatsProvider(tag, wrapper));
+            if (provider.getProviderCallbackBinder() != null) {
+                throw new IllegalArgumentException("provider is already registered");
+            }
+            final INetworkStatsProviderCallback cbBinder =
+                    mService.registerNetworkStatsProvider(tag, provider.getProviderBinder());
+            provider.setProviderCallbackBinder(cbBinder);
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
-        // Unreachable code, but compiler doesn't know about it.
-        return null;
+    }
+
+    /**
+     * Unregisters an instance of {@link NetworkStatsProvider}.
+     *
+     * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
+     *                 unregistered to the system.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_STATS_PROVIDER,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
+    @NonNull public void unregisterNetworkStatsProvider(@NonNull NetworkStatsProvider provider) {
+        try {
+            provider.getProviderCallbackBinderOrThrow().unregister();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
     }
 
     private static NetworkTemplate createTemplate(int networkType, String subscriberId) {
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index d4b5b1a..4bd7b05 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -257,11 +257,22 @@
 
     /**
      * Check if a given package was {@link #associate associated} with a device with given
-     * mac address by given user.
+     * Wi-Fi MAC address for a given user.
      *
-     * @param packageName the package to check for
-     * @param macAddress the mac address or BSSID of the device to check for
-     * @param user the user to check for
+     * <p>This is a system API protected by the
+     * {@link andrioid.Manifest.permission#MANAGE_COMPANION_DEVICES} permission, that’s currently
+     * called by the Android Wi-Fi stack to determine whether user consent is required to connect
+     * to a Wi-Fi network. Devices that have been pre-registered as companion devices will not
+     * require user consent to connect.</p>
+     *
+     * <p>Note if the caller has the
+     * {@link android.Manifest.permission#COMPANION_APPROVE_WIFI_CONNECTIONS} permission, this
+     * method will return true by default.</p>
+     *
+     * @param packageName the name of the package that has the association with the companion device
+     * @param macAddress the Wi-Fi MAC address or BSSID of the companion device to check for
+     * @param user the user handle that currently hosts the package being queried for a companion
+     *             device association
      * @return whether a corresponding association record exists
      *
      * @hide
diff --git a/core/java/android/content/pm/IDataLoader.aidl b/core/java/android/content/pm/IDataLoader.aidl
index 6a2658d..5ec6341 100644
--- a/core/java/android/content/pm/IDataLoader.aidl
+++ b/core/java/android/content/pm/IDataLoader.aidl
@@ -29,9 +29,9 @@
    void create(int id, in DataLoaderParamsParcel params,
            in FileSystemControlParcel control,
            IDataLoaderStatusListener listener);
-   void start();
-   void stop();
-   void destroy();
+   void start(int id);
+   void stop(int id);
+   void destroy(int id);
 
-   void prepareImage(in InstallationFileParcel[] addedFiles, in @utf8InCpp String[] removedFiles);
+   void prepareImage(int id, in InstallationFileParcel[] addedFiles, in @utf8InCpp String[] removedFiles);
 }
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index 8a89840..27c9cfc 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -103,4 +103,7 @@
             in UserHandle user);
     void uncacheShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
             in UserHandle user);
+
+    String getShortcutIconUri(String callingPackage, String packageName, String shortcutId,
+            int userId);
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0311120..b52034f 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -680,8 +680,6 @@
 
     String getWellbeingPackageName();
 
-    String[] getTelephonyPackageNames();
-
     String getAppPredictionServicePackageName();
 
     String getSystemCaptionsServicePackageName();
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 4e4897f..e73fd03 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -51,6 +51,7 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
+import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
@@ -67,8 +68,10 @@
 import android.util.Log;
 import android.util.Pair;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.function.pooled.PooledLambda;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -460,10 +463,7 @@
         /**
          * If non-null, return only the specified shortcuts by locus ID.  When setting this field,
          * a package name must also be set with {@link #setPackage}.
-         *
-         * @hide
          */
-        @SystemApi
         @NonNull
         public ShortcutQuery setLocusIds(@Nullable List<LocusId> locusIds) {
             mLocusIds = locusIds;
@@ -1201,6 +1201,35 @@
     }
 
     /**
+     * @hide internal/unit tests only
+     */
+    @VisibleForTesting
+    public ParcelFileDescriptor getUriShortcutIconFd(@NonNull ShortcutInfo shortcut) {
+        return getUriShortcutIconFd(shortcut.getPackage(), shortcut.getId(), shortcut.getUserId());
+    }
+
+    private ParcelFileDescriptor getUriShortcutIconFd(@NonNull String packageName,
+            @NonNull String shortcutId, int userId) {
+        String uri = null;
+        try {
+            uri = mService.getShortcutIconUri(mContext.getPackageName(), packageName, shortcutId,
+                    userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+        if (uri == null) {
+            return null;
+        }
+        try {
+            return mContext.getContentResolver().openFileDescriptor(Uri.parse(uri), "r");
+        } catch (FileNotFoundException e) {
+            Log.e(TAG, "Icon file not found: " + uri);
+            return null;
+        }
+    }
+
+    /**
      * Returns the icon for this shortcut, without any badging for the profile.
      *
      * <p>The calling launcher application must be allowed to access the shortcut information,
@@ -1220,26 +1249,10 @@
     public Drawable getShortcutIconDrawable(@NonNull ShortcutInfo shortcut, int density) {
         if (shortcut.hasIconFile()) {
             final ParcelFileDescriptor pfd = getShortcutIconFd(shortcut);
-            if (pfd == null) {
-                return null;
-            }
-            try {
-                final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
-                if (bmp != null) {
-                    BitmapDrawable dr = new BitmapDrawable(mContext.getResources(), bmp);
-                    if (shortcut.hasAdaptiveBitmap()) {
-                        return new AdaptiveIconDrawable(null, dr);
-                    } else {
-                        return dr;
-                    }
-                }
-                return null;
-            } finally {
-                try {
-                    pfd.close();
-                } catch (IOException ignore) {
-                }
-            }
+            return loadDrawableFromFileDescriptor(pfd, shortcut.hasAdaptiveBitmap());
+        } else if (shortcut.hasIconUri()) {
+            final ParcelFileDescriptor pfd = getUriShortcutIconFd(shortcut);
+            return loadDrawableFromFileDescriptor(pfd, shortcut.hasAdaptiveBitmap());
         } else if (shortcut.hasIconResource()) {
             return loadDrawableResourceFromPackage(shortcut.getPackage(),
                     shortcut.getIconResourceId(), shortcut.getUserHandle(), density);
@@ -1263,6 +1276,29 @@
         }
     }
 
+    private Drawable loadDrawableFromFileDescriptor(ParcelFileDescriptor pfd, boolean adaptive) {
+        if (pfd == null) {
+            return null;
+        }
+        try {
+            final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
+            if (bmp != null) {
+                BitmapDrawable dr = new BitmapDrawable(mContext.getResources(), bmp);
+                if (adaptive) {
+                    return new AdaptiveIconDrawable(null, dr);
+                } else {
+                    return dr;
+                }
+            }
+            return null;
+        } finally {
+            try {
+                pfd.close();
+            } catch (IOException ignore) {
+            }
+        }
+    }
+
     private Drawable loadDrawableResourceFromPackage(String packageName, int resId,
             UserHandle user, int density) {
         try {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 05ff830..84eabdb 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -7796,18 +7796,6 @@
     }
 
     /**
-     * @return the system defined telephony package names, or null if there's none.
-     *
-     * @hide
-     */
-    @Nullable
-    @TestApi
-    public String[] getTelephonyPackageNames() {
-        throw new UnsupportedOperationException(
-                "getTelephonyPackageNames not implemented in subclass");
-    }
-
-    /**
      * @return the system defined content capture service package name, or null if there's none.
      *
      * @hide
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 3aa1a6d..c6c2882 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -239,17 +239,6 @@
 
     /**
      * Additional flag for {@link #protectionLevel}, corresponding
-     * to the <code>telephony</code> value of
-     * {@link android.R.attr#protectionLevel}.
-     *
-     * @hide
-     */
-    @SystemApi
-    @TestApi
-    public static final int PROTECTION_FLAG_TELEPHONY = 0x400000;
-
-    /**
-     * Additional flag for {@link #protectionLevel}, corresponding
      * to the <code>companion</code> value of
      * {@link android.R.attr#protectionLevel}.
      *
@@ -291,7 +280,6 @@
             PROTECTION_FLAG_CONFIGURATOR,
             PROTECTION_FLAG_INCIDENT_REPORT_APPROVER,
             PROTECTION_FLAG_APP_PREDICTOR,
-            PROTECTION_FLAG_TELEPHONY,
             PROTECTION_FLAG_COMPANION,
             PROTECTION_FLAG_RETAIL_DEMO,
     })
@@ -537,9 +525,6 @@
         if ((level & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0) {
             protLevel += "|appPredictor";
         }
-        if ((level & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0) {
-            protLevel += "|telephony";
-        }
         if ((level & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0) {
             protLevel += "|retailDemo";
         }
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index af87578..8d8776f 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -123,6 +123,9 @@
     public static final int FLAG_CACHED = 1 << 14;
 
     /** @hide */
+    public static final int FLAG_HAS_ICON_URI = 1 << 15;
+
+    /** @hide */
     @IntDef(flag = true, prefix = { "FLAG_" }, value = {
             FLAG_DYNAMIC,
             FLAG_PINNED,
@@ -139,6 +142,7 @@
             FLAG_SHADOW,
             FLAG_LONG_LIVED,
             FLAG_CACHED,
+            FLAG_HAS_ICON_URI,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ShortcutFlags {}
@@ -401,6 +405,9 @@
     private String mIconResName;
 
     // Internal use only.
+    private String mIconUri;
+
+    // Internal use only.
     @Nullable
     private String mBitmapPath;
 
@@ -554,6 +561,7 @@
             if ((cloneFlags & CLONE_REMOVE_ICON) == 0) {
                 mIcon = source.mIcon;
                 mBitmapPath = source.mBitmapPath;
+                mIconUri = source.mIconUri;
             }
 
             mTitle = source.mTitle;
@@ -856,6 +864,7 @@
             mIconResId = 0;
             mIconResName = null;
             mBitmapPath = null;
+            mIconUri = null;
         }
         if (source.mTitle != null) {
             mTitle = source.mTitle;
@@ -916,6 +925,8 @@
             case Icon.TYPE_RESOURCE:
             case Icon.TYPE_BITMAP:
             case Icon.TYPE_ADAPTIVE_BITMAP:
+            case Icon.TYPE_URI:
+            case Icon.TYPE_URI_ADAPTIVE_BITMAP:
                 break; // OK
             default:
                 throw getInvalidIconException();
@@ -1792,6 +1803,15 @@
         return hasFlags(FLAG_HAS_ICON_RES);
     }
 
+    /**
+     * Return whether a shortcut's icon is provided via a URI.
+     *
+     * @hide internal/unit tests only
+     */
+    public boolean hasIconUri() {
+        return hasFlags(FLAG_HAS_ICON_URI);
+    }
+
     /** @hide */
     public boolean hasStringResources() {
         return (mTitleResId != 0) || (mTextResId != 0) || (mDisabledMessageResId != 0);
@@ -1911,6 +1931,19 @@
         return mIconResId;
     }
 
+    /** @hide */
+    public void setIconUri(String iconUri) {
+        mIconUri = iconUri;
+    }
+
+    /**
+     * Get the Uri for the icon, valid only when {@link #hasIconUri()} } is true.
+     * @hide internal / tests only.
+     */
+    public String getIconUri() {
+        return mIconUri;
+    }
+
     /**
      * Bitmap path.  Note this will be null even if {@link #hasIconFile()} is set when the save
      * is pending.  Use {@link #isIconPendingSave()} to check it.
@@ -2062,6 +2095,7 @@
 
         mPersons = source.readParcelableArray(cl, Person.class);
         mLocusId = source.readParcelable(cl);
+        mIconUri = source.readString();
     }
 
     @Override
@@ -2112,6 +2146,7 @@
 
         dest.writeParcelableArray(mPersons, flags);
         dest.writeParcelable(mLocusId, flags);
+        dest.writeString(mIconUri);
     }
 
     public static final @android.annotation.NonNull Creator<ShortcutInfo> CREATOR =
@@ -2203,6 +2238,12 @@
         if (hasIconResource()) {
             sb.append("Ic-r");
         }
+        if (hasIconUri()) {
+            sb.append("Ic-u");
+        }
+        if (hasAdaptiveBitmap()) {
+            sb.append("Ic-a");
+        }
         if (hasKeyFieldsOnly()) {
             sb.append("Key");
         }
@@ -2325,6 +2366,9 @@
 
             sb.append(", bitmapPath=");
             sb.append(mBitmapPath);
+
+            sb.append(", iconUri=");
+            sb.append(mIconUri);
         }
 
         if (mLocusId != null) {
@@ -2343,8 +2387,8 @@
             CharSequence disabledMessage, int disabledMessageResId, String disabledMessageResName,
             Set<String> categories, Intent[] intentsWithExtras, int rank, PersistableBundle extras,
             long lastChangedTimestamp,
-            int flags, int iconResId, String iconResName, String bitmapPath, int disabledReason,
-            Person[] persons, LocusId locusId) {
+            int flags, int iconResId, String iconResName, String bitmapPath, String iconUri,
+            int disabledReason, Person[] persons, LocusId locusId) {
         mUserId = userId;
         mId = id;
         mPackageName = packageName;
@@ -2369,6 +2413,7 @@
         mIconResId = iconResId;
         mIconResName = iconResName;
         mBitmapPath = bitmapPath;
+        mIconUri = iconUri;
         mDisabledReason = disabledReason;
         mPersons = persons;
         mLocusId = locusId;
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index a50ce92..435c70a 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -103,4 +103,10 @@
      */
     public abstract List<ShortcutManager.ShareShortcutInfo> getShareTargets(
             @NonNull String callingPackage, @NonNull IntentFilter intentFilter, int userId);
+
+    /**
+     * Returns the icon Uri of the shortcut, and grants Uri read permission to the caller.
+     */
+    public abstract String getShortcutIconUri(int launcherUserId, @NonNull String launcherPackage,
+            @NonNull String packageName, @NonNull String shortcutId, int userId);
 }
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index e41ed85..6f8acb6 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -1820,8 +1820,8 @@
                 .setUseEmbeddedDex(bool(false, R.styleable.AndroidManifestApplication_useEmbeddedDex, sa))
                 .setUsesNonSdkApi(bool(false, R.styleable.AndroidManifestApplication_usesNonSdkApi, sa))
                 .setVmSafeMode(bool(false, R.styleable.AndroidManifestApplication_vmSafeMode, sa))
-                .setDontAutoRevokePermissions(bool(false, R.styleable.AndroidManifestApplication_requestDontAutoRevokePermissions, sa))
-                .setAllowDontAutoRevokePermissions(bool(false, R.styleable.AndroidManifestApplication_allowDontAutoRevokePermissions, sa))
+                .setDontAutoRevokePermissions(bool(false, R.styleable.AndroidManifestApplication_requestAutoRevokePermissionsExemption, sa))
+                .setAllowDontAutoRevokePermissions(bool(false, R.styleable.AndroidManifestApplication_allowAutoRevokePermissionsExemption, sa))
                 // targetSdkVersion gated
                 .setAllowAudioPlaybackCapture(bool(targetSdk >= Build.VERSION_CODES.Q, R.styleable.AndroidManifestApplication_allowAudioPlaybackCapture, sa))
                 .setBaseHardwareAccelerated(bool(targetSdk >= Build.VERSION_CODES.ICE_CREAM_SANDWICH, R.styleable.AndroidManifestApplication_hardwareAccelerated, sa))
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 5fbf0da..9906331 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -657,7 +657,9 @@
     public int accuracy;
 
     /**
-     * The time in nanosecond at which the event happened
+     * The time in nanoseconds at which the event happened. For a given sensor,
+     * each new sensor event should be monotonically increasing using the same
+     * time base as {@link android.os.SystemClock#elapsedRealtimeNanos()}.
      */
     public long timestamp;
 
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 8f3cb93..45d6fed 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1066,8 +1066,9 @@
      * <li>One Jpeg ImageReader, any resolution: the camera device is
      *    allowed to slow down JPEG output speed by 50% if there is any ongoing offline
      *    session.</li>
-     * <li>One ImageWriter surface of private format, any resolution if the device supports
-     *    PRIVATE_REPROCESSING capability</li>
+     * <li>If the device supports PRIVATE_REPROCESSING, one pair of ImageWriter/ImageReader
+     *    surfaces of private format, with the same resolution that is larger or equal to
+     *    the JPEG ImageReader resolution above.</li>
      * </ol>
      * </li>
      * <li>Alternatively, the active camera session above can be replaced by an legacy
diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java
index bd39c13..29da495 100644
--- a/core/java/android/net/NattKeepalivePacketData.java
+++ b/core/java/android/net/NattKeepalivePacketData.java
@@ -20,6 +20,7 @@
 import static android.net.InvalidPacketException.ERROR_INVALID_PORT;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.util.IpUtils;
 import android.os.Parcel;
@@ -30,6 +31,7 @@
 import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.util.Objects;
 
 /** @hide */
 @SystemApi
@@ -121,4 +123,19 @@
                     return new NattKeepalivePacketData[size];
                 }
             };
+
+    @Override
+    public boolean equals(@Nullable final Object o) {
+        if (!(o instanceof NattKeepalivePacketData)) return false;
+        final NattKeepalivePacketData other = (NattKeepalivePacketData) o;
+        return this.srcAddress.equals(other.srcAddress)
+            && this.dstAddress.equals(other.dstAddress)
+            && this.srcPort == other.srcPort
+            && this.dstPort == other.dstPort;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(srcAddress, dstAddress, srcPort, dstPort);
+    }
 }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 116e343..7d8df6a 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -37,9 +37,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.Arrays;
 import java.util.Objects;
 import java.util.Set;
 import java.util.StringJoiner;
@@ -96,7 +94,7 @@
         mTransportInfo = null;
         mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
         mUids = null;
-        mAdministratorUids.clear();
+        mAdministratorUids = new int[0];
         mOwnerUid = Process.INVALID_UID;
         mSSID = null;
         mPrivateDnsBroken = false;
@@ -884,10 +882,10 @@
      * empty unless the destination is 1) the System Server, or 2) Telephony. In either case, the
      * receiving entity must have the ACCESS_FINE_LOCATION permission and target R+.
      */
-    private final List<Integer> mAdministratorUids = new ArrayList<>();
+    private int[] mAdministratorUids = new int[0];
 
     /**
-     * Sets the list of UIDs that are administrators of this network.
+     * Sets the int[] of UIDs that are administrators of this network.
      *
      * <p>UIDs included in administratorUids gain administrator privileges over this Network.
      * Examples of UIDs that should be included in administratorUids are:
@@ -907,23 +905,21 @@
      */
     @NonNull
     @SystemApi
-    public NetworkCapabilities setAdministratorUids(
-            @NonNull final List<Integer> administratorUids) {
-        mAdministratorUids.clear();
-        mAdministratorUids.addAll(administratorUids);
+    public NetworkCapabilities setAdministratorUids(@NonNull final int[] administratorUids) {
+        mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
         return this;
     }
 
     /**
-     * Retrieves the list of UIDs that are administrators of this Network.
+     * Retrieves the UIDs that are administrators of this Network.
      *
-     * @return the List of UIDs that are administrators of this Network
+     * @return the int[] of UIDs that are administrators of this Network
      * @hide
      */
     @NonNull
     @SystemApi
-    public List<Integer> getAdministratorUids() {
-        return Collections.unmodifiableList(mAdministratorUids);
+    public int[] getAdministratorUids() {
+        return Arrays.copyOf(mAdministratorUids, mAdministratorUids.length);
     }
 
     /**
@@ -1584,7 +1580,7 @@
         dest.writeArraySet(mUids);
         dest.writeString(mSSID);
         dest.writeBoolean(mPrivateDnsBroken);
-        dest.writeList(mAdministratorUids);
+        dest.writeIntArray(mAdministratorUids);
         dest.writeInt(mOwnerUid);
         dest.writeInt(mRequestorUid);
         dest.writeString(mRequestorPackageName);
@@ -1608,7 +1604,7 @@
                         null /* ClassLoader, null for default */);
                 netCap.mSSID = in.readString();
                 netCap.mPrivateDnsBroken = in.readBoolean();
-                netCap.setAdministratorUids(in.readArrayList(null));
+                netCap.setAdministratorUids(in.createIntArray());
                 netCap.mOwnerUid = in.readInt();
                 netCap.mRequestorUid = in.readInt();
                 netCap.mRequestorPackageName = in.readString();
@@ -1665,8 +1661,8 @@
             sb.append(" OwnerUid: ").append(mOwnerUid);
         }
 
-        if (!mAdministratorUids.isEmpty()) {
-            sb.append(" AdministratorUids: ").append(mAdministratorUids);
+        if (mAdministratorUids.length == 0) {
+            sb.append(" AdministratorUids: ").append(Arrays.toString(mAdministratorUids));
         }
 
         if (null != mSSID) {
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 2f536ff..9c1fb41 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -21,7 +21,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
@@ -58,9 +57,12 @@
 public final class NetworkStats implements Parcelable {
     private static final String TAG = "NetworkStats";
 
-    /** {@link #iface} value when interface details unavailable. */
-    @SuppressLint("CompileTimeConstant")
+    /**
+     * {@link #iface} value when interface details unavailable.
+     * @hide
+     */
     @Nullable public static final String IFACE_ALL = null;
+
     /**
      * Virtual network interface for video telephony. This is for VT data usage counting
      * purpose.
@@ -248,7 +250,13 @@
     @UnsupportedAppUsage
     private long[] operations;
 
-    /** @hide */
+    /**
+     * Basic element of network statistics. Contains the number of packets and number of bytes
+     * transferred on both directions in a given set of conditions. See
+     * {@link Entry#Entry(String, int, int, int, int, int, int, long, long, long, long, long)}.
+     *
+     * @hide
+     */
     @SystemApi
     public static class Entry {
         /** @hide */
@@ -319,6 +327,35 @@
                     rxBytes, rxPackets, txBytes, txPackets, operations);
         }
 
+        /**
+         * Construct a {@link Entry} object by giving statistics of packet and byte transferred on
+         * both direction, and associated with a set of given conditions.
+         *
+         * @param iface interface name of this {@link Entry}. Or null if not specified.
+         * @param uid uid of this {@link Entry}. {@link #UID_TETHERING} if this {@link Entry} is
+         *            for tethering. Or {@link #UID_ALL} if this {@link NetworkStats} is only
+         *            counting iface stats.
+         * @param set usage state of this {@link Entry}. Should be one of the following
+         *            values: {@link #SET_DEFAULT}, {@link #SET_FOREGROUND}.
+         * @param tag tag of this {@link Entry}.
+         * @param metered metered state of this {@link Entry}. Should be one of the following
+         *                values: {link #METERED_YES}, {link #METERED_NO}.
+         * @param roaming roaming state of this {@link Entry}. Should be one of the following
+         *                values: {link #ROAMING_YES}, {link #ROAMING_NO}.
+         * @param defaultNetwork default network status of this {@link Entry}. Should be one
+         *                       of the following values: {link #DEFAULT_NETWORK_YES},
+         *                       {link #DEFAULT_NETWORK_NO}.
+         * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param rxPackets Number of packets received for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param operations count of network operations performed for this {@link Entry}. This can
+         *                   be used to derive bytes-per-operation.
+         */
         public Entry(@Nullable String iface, int uid, @State int set, int tag,
                 @Meteredness int metered, @Roaming int roaming, @DefaultNetwork int defaultNetwork,
                 long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
@@ -466,7 +503,7 @@
         NetworkStats.Entry entry = null;
         for (int i = 0; i < size; i++) {
             entry = getValues(i, entry);
-            clone.addEntry(entry);
+            clone.insertEntry(entry);
         }
         return clone;
     }
@@ -493,26 +530,26 @@
 
     /** @hide */
     @VisibleForTesting
-    public NetworkStats addIfaceValues(
+    public NetworkStats insertEntry(
             String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) {
-        return addEntry(
+        return insertEntry(
                 iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L);
     }
 
     /** @hide */
     @VisibleForTesting
-    public NetworkStats addEntry(String iface, int uid, int set, int tag, long rxBytes,
+    public NetworkStats insertEntry(String iface, int uid, int set, int tag, long rxBytes,
             long rxPackets, long txBytes, long txPackets, long operations) {
-        return addEntry(new Entry(
+        return insertEntry(new Entry(
                 iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
     }
 
     /** @hide */
     @VisibleForTesting
-    public NetworkStats addEntry(String iface, int uid, int set, int tag, int metered, int roaming,
-            int defaultNetwork, long rxBytes, long rxPackets, long txBytes, long txPackets,
-            long operations) {
-        return addEntry(new Entry(
+    public NetworkStats insertEntry(String iface, int uid, int set, int tag, int metered,
+            int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes,
+            long txPackets, long operations) {
+        return insertEntry(new Entry(
                 iface, uid, set, tag, metered, roaming, defaultNetwork, rxBytes, rxPackets,
                 txBytes, txPackets, operations));
     }
@@ -522,7 +559,7 @@
      * object can be recycled across multiple calls.
      * @hide
      */
-    public NetworkStats addEntry(Entry entry) {
+    public NetworkStats insertEntry(Entry entry) {
         if (size >= capacity) {
             final int newLength = Math.max(size, 10) * 3 / 2;
             iface = Arrays.copyOf(iface, newLength);
@@ -665,7 +702,7 @@
                 entry.roaming, entry.defaultNetwork);
         if (i == -1) {
             // only create new entry when positive contribution
-            addEntry(entry);
+            insertEntry(entry);
         } else {
             rxBytes[i] += entry.rxBytes;
             rxPackets[i] += entry.rxPackets;
@@ -684,7 +721,7 @@
      * @param entry the {@link Entry} to add.
      * @return a new constructed {@link NetworkStats} object that contains the result.
      */
-    public @NonNull NetworkStats addValues(@NonNull Entry entry) {
+    public @NonNull NetworkStats addEntry(@NonNull Entry entry) {
         return this.clone().combineValues(entry);
     }
 
@@ -1003,7 +1040,7 @@
                 entry.operations = Math.max(entry.operations, 0);
             }
 
-            result.addEntry(entry);
+            result.insertEntry(entry);
         }
 
         return result;
diff --git a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java b/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java
deleted file mode 100644
index 740aa92..0000000
--- a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 android.net.netstats.provider;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.net.NetworkStats;
-
-/**
- * A base class that allows external modules to implement a custom network statistics provider.
- * @hide
- */
-@SystemApi
-public abstract class AbstractNetworkStatsProvider {
-    /**
-     * A value used by {@link #setLimit} and {@link #setAlert} indicates there is no limit.
-     */
-    public static final int QUOTA_UNLIMITED = -1;
-
-    /**
-     * Called by {@code NetworkStatsService} when global polling is needed. Custom
-     * implementation of providers MUST respond to it by calling
-     * {@link NetworkStatsProviderCallback#onStatsUpdated} within one minute. Responding
-     * later than this may cause the stats to be dropped.
-     *
-     * @param token a positive number identifying the new state of the system under which
-     *              {@link NetworkStats} have to be gathered from now on. When this is called,
-     *              custom implementations of providers MUST report the latest stats with the
-     *              previous token, under which stats were being gathered so far.
-     */
-    public abstract void requestStatsUpdate(int token);
-
-    /**
-     * Called by {@code NetworkStatsService} when setting the interface quota for the specified
-     * upstream interface. When this is called, the custom implementation should block all egress
-     * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have
-     * been reached, and MUST respond to it by calling
-     * {@link NetworkStatsProviderCallback#onLimitReached()}.
-     *
-     * @param iface the interface requiring the operation.
-     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
-     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
-     */
-    public abstract void setLimit(@NonNull String iface, long quotaBytes);
-
-    /**
-     * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations
-     * MUST call {@link NetworkStatsProviderCallback#onAlertReached()} when {@code quotaBytes} bytes
-     * have been reached. Unlike {@link #setLimit(String, long)}, the custom implementation should
-     * not block all egress packets.
-     *
-     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
-     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert.
-     */
-    public abstract void setAlert(long quotaBytes);
-}
diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
index 55b3d4e..4078b24 100644
--- a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
+++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
@@ -22,7 +22,7 @@
  * @hide
  */
 oneway interface INetworkStatsProvider {
-    void requestStatsUpdate(int token);
-    void setLimit(String iface, long quotaBytes);
-    void setAlert(long quotaBytes);
+    void onRequestStatsUpdate(int token);
+    void onSetLimit(String iface, long quotaBytes);
+    void onSetAlert(long quotaBytes);
 }
diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
index 3ea9318..bd336dd 100644
--- a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
+++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
@@ -24,8 +24,8 @@
  * @hide
  */
 oneway interface INetworkStatsProviderCallback {
-    void onStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
-    void onAlertReached();
-    void onLimitReached();
+    void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
+    void notifyAlertReached();
+    void notifyLimitReached();
     void unregister();
 }
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java
new file mode 100644
index 0000000..7639d22
--- /dev/null
+++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java
@@ -0,0 +1,195 @@
+/*
+ * 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 android.net.netstats.provider;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.NetworkStats;
+import android.os.RemoteException;
+
+/**
+ * A base class that allows external modules to implement a custom network statistics provider.
+ * @hide
+ */
+@SystemApi
+public abstract class NetworkStatsProvider {
+    /**
+     * A value used by {@link #onSetLimit} and {@link #onSetAlert} indicates there is no limit.
+     */
+    public static final int QUOTA_UNLIMITED = -1;
+
+    @NonNull private final INetworkStatsProvider mProviderBinder =
+            new INetworkStatsProvider.Stub() {
+
+        @Override
+        public void onRequestStatsUpdate(int token) {
+            NetworkStatsProvider.this.onRequestStatsUpdate(token);
+        }
+
+        @Override
+        public void onSetLimit(String iface, long quotaBytes) {
+            NetworkStatsProvider.this.onSetLimit(iface, quotaBytes);
+        }
+
+        @Override
+        public void onSetAlert(long quotaBytes) {
+            NetworkStatsProvider.this.onSetAlert(quotaBytes);
+        }
+    };
+
+    // The binder given by the service when successfully registering. Only null before registering,
+    // never null once non-null.
+    @Nullable
+    private INetworkStatsProviderCallback mProviderCbBinder;
+
+    /**
+     * Return the binder invoked by the service and redirect function calls to the overridden
+     * methods.
+     * @hide
+     */
+    @NonNull
+    public INetworkStatsProvider getProviderBinder() {
+        return mProviderBinder;
+    }
+
+    /**
+     * Store the binder that was returned by the service when successfully registering. Note that
+     * the provider cannot be re-registered. Hence this method can only be called once per provider.
+     *
+     * @hide
+     */
+    public void setProviderCallbackBinder(@NonNull INetworkStatsProviderCallback binder) {
+        if (mProviderCbBinder != null) {
+            throw new IllegalArgumentException("provider is already registered");
+        }
+        mProviderCbBinder = binder;
+    }
+
+    /**
+     * Get the binder that was returned by the service when successfully registering. Or null if the
+     * provider was never registered.
+     *
+     * @hide
+     */
+    @Nullable
+    public INetworkStatsProviderCallback getProviderCallbackBinder() {
+        return mProviderCbBinder;
+    }
+
+    /**
+     * Get the binder that was returned by the service when successfully registering. Throw an
+     * {@link IllegalStateException} if the provider is not registered.
+     *
+     * @hide
+     */
+    @NonNull
+    public INetworkStatsProviderCallback getProviderCallbackBinderOrThrow() {
+        if (mProviderCbBinder == null) {
+            throw new IllegalStateException("the provider is not registered");
+        }
+        return mProviderCbBinder;
+    }
+
+    /**
+     * Notify the system of new network statistics.
+     *
+     * Send the network statistics recorded since the last call to {@link #notifyStatsUpdated}. Must
+     * be called as soon as possible after {@link NetworkStatsProvider#onRequestStatsUpdate(int)}
+     * being called. Responding later increases the probability stats will be dropped. The
+     * provider can also call this whenever it wants to reports new stats for any reason.
+     * Note that the system will not necessarily immediately propagate the statistics to
+     * reflect the update.
+     *
+     * @param token the token under which these stats were gathered. Providers can call this method
+     *              with the current token as often as they want, until the token changes.
+     *              {@see NetworkStatsProvider#onRequestStatsUpdate()}
+     * @param ifaceStats the {@link NetworkStats} per interface to be reported.
+     *                   The provider should not include any traffic that is already counted by
+     *                   kernel interface counters.
+     * @param uidStats the same stats as above, but counts {@link NetworkStats}
+     *                 per uid.
+     */
+    public void notifyStatsUpdated(int token, @NonNull NetworkStats ifaceStats,
+            @NonNull NetworkStats uidStats) {
+        try {
+            getProviderCallbackBinderOrThrow().notifyStatsUpdated(token, ifaceStats, uidStats);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Notify system that the quota set by {@code onSetAlert} has been reached.
+     */
+    public void notifyAlertReached() {
+        try {
+            getProviderCallbackBinderOrThrow().notifyAlertReached();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Notify system that the quota set by {@code onSetLimit} has been reached.
+     */
+    public void notifyLimitReached() {
+        try {
+            getProviderCallbackBinderOrThrow().notifyLimitReached();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Called by {@code NetworkStatsService} when it requires to know updated stats.
+     * The provider MUST respond by calling {@link #notifyStatsUpdated} as soon as possible.
+     * Responding later increases the probability stats will be dropped. Memory allowing, the
+     * system will try to take stats into account up to one minute after calling
+     * {@link #onRequestStatsUpdate}.
+     *
+     * @param token a positive number identifying the new state of the system under which
+     *              {@link NetworkStats} have to be gathered from now on. When this is called,
+     *              custom implementations of providers MUST tally and report the latest stats with
+     *              the previous token, under which stats were being gathered so far.
+     */
+    public abstract void onRequestStatsUpdate(int token);
+
+    /**
+     * Called by {@code NetworkStatsService} when setting the interface quota for the specified
+     * upstream interface. When this is called, the custom implementation should block all egress
+     * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have
+     * been reached, and MUST respond to it by calling
+     * {@link NetworkStatsProvider#notifyLimitReached()}.
+     *
+     * @param iface the interface requiring the operation.
+     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
+     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
+     */
+    public abstract void onSetLimit(@NonNull String iface, long quotaBytes);
+
+    /**
+     * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations
+     * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes
+     * have been reached. Unlike {@link #onSetLimit(String, long)}, the custom implementation should
+     * not block all egress packets.
+     *
+     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
+     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert.
+     */
+    public abstract void onSetAlert(long quotaBytes);
+}
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java b/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java
deleted file mode 100644
index e17a8ee..0000000
--- a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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 android.net.netstats.provider;
-
-import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.net.NetworkStats;
-import android.os.RemoteException;
-
-/**
- * A callback class that allows callers to report events to the system.
- * @hide
- */
-@SystemApi
-@SuppressLint("CallbackMethodName")
-public class NetworkStatsProviderCallback {
-    @NonNull private final INetworkStatsProviderCallback mBinder;
-
-    /** @hide */
-    public NetworkStatsProviderCallback(@NonNull INetworkStatsProviderCallback binder) {
-        mBinder = binder;
-    }
-
-    /**
-     * Notify the system of new network statistics.
-     *
-     * Send the network statistics recorded since the last call to {@link #onStatsUpdated}. Must be
-     * called within one minute of {@link AbstractNetworkStatsProvider#requestStatsUpdate(int)}
-     * being called. The provider can also call this whenever it wants to reports new stats for any
-     * reason. Note that the system will not necessarily immediately propagate the statistics to
-     * reflect the update.
-     *
-     * @param token the token under which these stats were gathered. Providers can call this method
-     *              with the current token as often as they want, until the token changes.
-     *              {@see AbstractNetworkStatsProvider#requestStatsUpdate()}
-     * @param ifaceStats the {@link NetworkStats} per interface to be reported.
-     *                   The provider should not include any traffic that is already counted by
-     *                   kernel interface counters.
-     * @param uidStats the same stats as above, but counts {@link NetworkStats}
-     *                 per uid.
-     */
-    public void onStatsUpdated(int token, @NonNull NetworkStats ifaceStats,
-            @NonNull NetworkStats uidStats) {
-        try {
-            mBinder.onStatsUpdated(token, ifaceStats, uidStats);
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
-    }
-
-    /**
-     * Notify system that the quota set by {@code setAlert} has been reached.
-     */
-    public void onAlertReached() {
-        try {
-            mBinder.onAlertReached();
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
-    }
-
-    /**
-     * Notify system that the quota set by {@code setLimit} has been reached.
-     */
-    public void onLimitReached() {
-        try {
-            mBinder.onLimitReached();
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
-    }
-
-    /**
-     * Unregister the provider and the referencing callback.
-     */
-    public void unregister() {
-        try {
-            mBinder.unregister();
-        } catch (RemoteException e) {
-            // Ignore error.
-        }
-    }
-}
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java b/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java
deleted file mode 100644
index 4bf7c9b..0000000
--- a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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 android.net.netstats.provider;
-
-import android.annotation.NonNull;
-
-/**
- * A wrapper class of {@link INetworkStatsProvider} that hides the binder interface from exposing
- * to outer world.
- *
- * @hide
- */
-public class NetworkStatsProviderWrapper extends INetworkStatsProvider.Stub {
-    @NonNull final AbstractNetworkStatsProvider mProvider;
-
-    public NetworkStatsProviderWrapper(AbstractNetworkStatsProvider provider) {
-        mProvider = provider;
-    }
-
-    @Override
-    public void requestStatsUpdate(int token) {
-        mProvider.requestStatsUpdate(token);
-    }
-
-    @Override
-    public void setLimit(@NonNull String iface, long quotaBytes) {
-        mProvider.setLimit(iface, quotaBytes);
-    }
-
-    @Override
-    public void setAlert(long quotaBytes) {
-        mProvider.setAlert(quotaBytes);
-    }
-}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index d320f61..c61f10f 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -245,13 +245,25 @@
 
     /**
      * Mandatory String extra field in {@link #ACTION_PREFERRED_PAYMENT_CHANGED}
-     * Indicates the condition when trigger this event.
+     * Indicates the condition when trigger this event. Possible values are:
+     * {@link #PREFERRED_PAYMENT_LOADED},
+     * {@link #PREFERRED_PAYMENT_CHANGED},
+     * {@link #PREFERRED_PAYMENT_UPDATED},
      */
     public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON =
             "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
-
+    /**
+     * Nfc is enabled and the preferred payment aids are registered.
+     */
     public static final int PREFERRED_PAYMENT_LOADED = 1;
+    /**
+     * User selected another payment application as the preferred payment.
+     */
     public static final int PREFERRED_PAYMENT_CHANGED = 2;
+    /**
+     * Current preferred payment has issued an update (registered/unregistered new aids or has been
+     * updated itself).
+     */
     public static final int PREFERRED_PAYMENT_UPDATED = 3;
 
     public static final int STATE_OFF = 1;
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index f1c74a6..7bf82e8 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -672,7 +672,7 @@
             recoverService();
             if (sService == null) {
                 Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
+                throw e.rethrowFromSystemServer();
             }
             try {
                 ApduServiceInfo serviceInfo =
@@ -680,7 +680,7 @@
                 return (serviceInfo != null ? serviceInfo.getAids() : null);
             } catch (RemoteException ee) {
                 Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
+                throw e.rethrowFromSystemServer();
             }
         }
     }
@@ -690,9 +690,16 @@
      *
      * @return The route destination secure element name of the preferred payment service.
      *         HCE payment: "Host"
-     *         OffHost payment: prefix SIM or prefix eSE string.
-     *                          "OffHost" if the payment service does not specify secure element
-     *                          name.
+     *         OffHost payment: 1. String with prefix SIM or prefix eSE string.
+     *                             Ref: GSMA TS.26 - NFC Handset Requirements
+     *                             TS26_NFC_REQ_069: For UICC, Secure Element Name SHALL be
+     *                                               SIM[smartcard slot]
+     *                                               (e.g. SIM/SIM1, SIM2… SIMn).
+     *                             TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be
+     *                                               eSE[number]
+     *                                               (e.g. eSE/eSE1, eSE2, etc.).
+     *                          2. "OffHost" if the payment service does not specify secure element
+     *                             name.
      */
     @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
     @Nullable
@@ -711,7 +718,7 @@
             recoverService();
             if (sService == null) {
                 Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
+                throw e.rethrowFromSystemServer();
             }
             try {
                 ApduServiceInfo serviceInfo =
@@ -727,7 +734,7 @@
 
             } catch (RemoteException ee) {
                 Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
+                throw e.rethrowFromSystemServer();
             }
         }
     }
@@ -739,7 +746,7 @@
      */
     @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
     @Nullable
-    public String getDescriptionForPreferredPaymentService() {
+    public CharSequence getDescriptionForPreferredPaymentService() {
         try {
             ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(mContext.getUserId());
             return (serviceInfo != null ? serviceInfo.getDescription() : null);
@@ -747,7 +754,7 @@
             recoverService();
             if (sService == null) {
                 Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
+                throw e.rethrowFromSystemServer();
             }
             try {
                 ApduServiceInfo serviceInfo =
@@ -755,7 +762,7 @@
                 return (serviceInfo != null ? serviceInfo.getDescription() : null);
             } catch (RemoteException ee) {
                 Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
+                throw e.rethrowFromSystemServer();
             }
         }
     }
diff --git a/core/java/android/os/ConfigUpdate.java b/core/java/android/os/ConfigUpdate.java
index 590fbb3..a28f5fb 100644
--- a/core/java/android/os/ConfigUpdate.java
+++ b/core/java/android/os/ConfigUpdate.java
@@ -17,6 +17,8 @@
 package android.os;
 
 import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 
 /**
@@ -125,6 +127,7 @@
     */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.UPDATE_CONFIG)
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB =
             "android.os.action.UPDATE_EMERGENCY_NUMBER_DB";
 
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index a557bd9..b7b3c4f 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -931,6 +931,19 @@
     public static final native void setProcessFrozen(int pid, int uid, boolean frozen);
 
     /**
+     * Enable or disable the freezer. When enable == false all frozen processes are unfrozen,
+     * but aren't removed from the freezer. Processes can still be added or removed
+     * by using setProcessFrozen, but they won't actually be frozen until the freezer is enabled
+     * again. If enable == true the freezer is enabled again, and all processes
+     * in the freezer (including the ones added while the freezer was disabled) are frozen.
+     *
+     * @param enable Specify whether to enable (true) or disable (false) the freezer.
+     *
+     * @hide
+     */
+    public static final native void enableFreezer(boolean enable);
+
+    /**
      * Return the scheduling group of requested process.
      *
      * @hide
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index f43a252..e05991b 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -144,4 +144,10 @@
      * @param uid the uid of the package
      */
     public abstract void prepareAppDataAfterInstall(@NonNull String packageName, int uid);
+
+
+    /**
+     * Return true if uid is external storage service.
+     */
+    public abstract boolean isExternalStorageService(int uid);
 }
diff --git a/core/java/android/permission/Permissions.md b/core/java/android/permission/Permissions.md
index e62bd0a..e116dc6 100644
--- a/core/java/android/permission/Permissions.md
+++ b/core/java/android/permission/Permissions.md
@@ -49,6 +49,10 @@
 to involve the user. This can be either because the API is not sensitive, or because additional
 checks exist.
 
+Another benefit of install time permissions is that is becomes very easy to monitor which apps can
+access certain APIs. E.g. by checking which apps have the `android.permission.INTERNET` permission
+you can list all apps that are allowed to use APIs that can send data to the internet.
+
 #### Defining a permission
 
 Any package can define a permission. For that it simply adds an entry in the manifest file
@@ -591,8 +595,9 @@
 ### Permission restricted components
 
 As [publicly documented](https://developer.android.com/guide/topics/permissions/overview#permission_enforcement)
-it is possible to restrict starting an activity/binding to a service by using permission. It is
-a common pattern to
+it is possible to restrict starting an activity/binding to a service by using permission.
+
+It is a common pattern to
 
 - define a permission in the platform as `signature`
 - protect a service in an app by this permission using the `android:permission` attribute of the
@@ -605,6 +610,75 @@
 This does not work for app-op or runtime permissions as the way to check these permissions is
 more complex than install time permissions.
 
+#### End-to-end A service only the system can bind to
+
+Make sure to set the `android:permission` flag for this service. As developers can forget this it is
+a good habit to check this before binding to the service. This makes sure that the services are
+implemented correctly and no random app can bind to the service.
+
+The result is that the permission is granted only to the system. It is not granted to the service's
+package, but this has no negative side-effects.
+
+##### Permission definition
+
+frameworks/base/core/res/AndroidManifest.xml:
+
+```xml
+<manifest>
+[...]
+    <permission android:name="android.permission.BIND_MY_SERVICE"
+        android:label="@string/permlab_bindMyService"
+        android:description="@string/permdesc_bindMyService"
+        android:protectionLevel="signature" />
+[...]
+</manifest>
+```
+
+##### Service definition
+
+Manifest of the service providing the functionality:
+
+```xml
+<manifest>
+        <service android:name="com.my.ServiceImpl"
+                 android:permission="android.permission.BIND_MY_SERVICE">
+            <!-- add an intent filter so that the system can find this package -->
+            <intent-filter>
+                <action android:name="android.my.Service" />
+            </intent-filter>
+        </service>
+</manifest>
+```
+
+##### System server code binding to service
+
+```kotlin
+val serviceConnections = mutableListOf<ServiceConnection>()
+
+val potentialServices = context.packageManager.queryIntentServicesAsUser(
+        Intent("android.my.Service"), GET_SERVICES or GET_META_DATA, userId)
+
+for (val ri in potentialServices) {
+    val serviceComponent = ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name)
+
+    if (android.Manifest.permission.BIND_MY_SERVICE != ri.serviceInfo.permission) {
+        Slog.w(TAG, "$serviceComponent is not protected by " +
+                "${android.Manifest.permission.BIND_MY_SERVICE}")
+        continue
+    }
+
+    val newConnection = object : ServiceConnection {
+        ...
+    }
+
+    val wasBound = context.bindServiceAsUser(Intent().setComponent(serviceComponent),
+            serviceConnection, BIND_AUTO_CREATE, UserHandle.of(userId))
+    if (wasBound) {
+        serviceConnections.add(newConnection)
+    }
+}
+```
+
 ## Permissions for system apps
 
 System apps need to integrate deeper with the system than regular apps. Hence they need to be
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d8679b2..ff34055 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -14192,19 +14192,6 @@
                 "power_button_suppression_delay_after_gesture_wake";
 
         /**
-         * An integer indicating whether the device is in Common Criteria mode. When enabled,
-         * certain device functionalities are tuned to meet the higher security level required
-         * by Common Criteria certification. Examples include:
-         *   Bluetooth long term key material is additionally integrity-protected with AES-GCM.
-         *   WiFi configuration store is additionally integrity-protected with AES-GCM.
-         * A value of 0 means Common Criteria mode is not enabled (default), a value of non-zero
-         * means Common Criteria mode is enabled.
-         * @hide
-         */
-        @SystemApi
-        public static final String COMMON_CRITERIA_MODE = "common_criteria_mode";
-
-        /**
          * The usage amount of advanced battery. The value is 0~100.
          *
          * @hide
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index e7b360d..17e3748 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1391,7 +1391,6 @@
      * Base column for the table that contain Carrier Public key.
      * @hide
      */
-    @SystemApi
     public interface CarrierColumns extends BaseColumns {
 
         /**
@@ -4704,7 +4703,6 @@
          * Contains mappings between matching rules with carrier id for all carriers.
          * @hide
          */
-        @SystemApi
         public static final class All implements BaseColumns {
 
             /**
diff --git a/core/java/android/se/omapi/Reader.java b/core/java/android/se/omapi/Reader.java
index 7f68d91..90c934d 100644
--- a/core/java/android/se/omapi/Reader.java
+++ b/core/java/android/se/omapi/Reader.java
@@ -160,7 +160,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED)
+    @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION)
     public boolean reset() {
         if (!mService.isConnected()) {
             Log.e(TAG, "service is not connected");
diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java
index f0a72c5..7fbc309 100644
--- a/core/java/android/service/autofill/InlineSuggestionRenderService.java
+++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java
@@ -97,6 +97,9 @@
             host.setView(suggestionRoot, lp);
             suggestionRoot.setOnClickListener((v) -> {
                 try {
+                    if (suggestionView.hasOnClickListeners()) {
+                        suggestionView.callOnClick();
+                    }
                     callback.onClick();
                 } catch (RemoteException e) {
                     Log.w(TAG, "RemoteException calling onClick()");
@@ -105,6 +108,9 @@
 
             suggestionRoot.setOnLongClickListener((v) -> {
                 try {
+                    if (suggestionView.hasOnLongClickListeners()) {
+                        suggestionView.performLongClick();
+                    }
                     callback.onLongClick();
                 } catch (RemoteException e) {
                     Log.w(TAG, "RemoteException calling onLongClick()");
diff --git a/core/java/android/service/autofill/InlineSuggestionRoot.java b/core/java/android/service/autofill/InlineSuggestionRoot.java
index bdcc253..6c9d36b 100644
--- a/core/java/android/service/autofill/InlineSuggestionRoot.java
+++ b/core/java/android/service/autofill/InlineSuggestionRoot.java
@@ -52,6 +52,11 @@
     }
 
     @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        return true;
+    }
+
+    @Override
     @SuppressLint("ClickableViewAccessibility")
     public boolean onTouchEvent(@NonNull MotionEvent event) {
         switch (event.getActionMasked()) {
diff --git a/core/java/android/service/dataloader/DataLoaderService.java b/core/java/android/service/dataloader/DataLoaderService.java
index d4db79e..0170726 100644
--- a/core/java/android/service/dataloader/DataLoaderService.java
+++ b/core/java/android/service/dataloader/DataLoaderService.java
@@ -102,21 +102,18 @@
     }
 
     private class DataLoaderBinderService extends IDataLoader.Stub {
-        private int mId;
-
         @Override
         public void create(int id, @NonNull DataLoaderParamsParcel params,
                 @NonNull FileSystemControlParcel control,
                 @NonNull IDataLoaderStatusListener listener)
                 throws RuntimeException {
-            mId = id;
             try {
                 if (!nativeCreateDataLoader(id, control, params, listener)) {
-                    Slog.e(TAG, "Failed to create native loader for " + mId);
+                    Slog.e(TAG, "Failed to create native loader for " + id);
                 }
             } catch (Exception ex) {
-                Slog.e(TAG, "Failed to create native loader for " + mId, ex);
-                destroy();
+                Slog.e(TAG, "Failed to create native loader for " + id, ex);
+                destroy(id);
                 throw new RuntimeException(ex);
             } finally {
                 // Closing FDs.
@@ -150,30 +147,31 @@
         }
 
         @Override
-        public void start() {
-            if (!nativeStartDataLoader(mId)) {
-                Slog.e(TAG, "Failed to start loader: " + mId);
+        public void start(int id) {
+            if (!nativeStartDataLoader(id)) {
+                Slog.e(TAG, "Failed to start loader: " + id);
             }
         }
 
         @Override
-        public void stop() {
-            if (!nativeStopDataLoader(mId)) {
-                Slog.w(TAG, "Failed to stop loader: " + mId);
+        public void stop(int id) {
+            if (!nativeStopDataLoader(id)) {
+                Slog.w(TAG, "Failed to stop loader: " + id);
             }
         }
 
         @Override
-        public void destroy() {
-            if (!nativeDestroyDataLoader(mId)) {
-                Slog.w(TAG, "Failed to destroy loader: " + mId);
+        public void destroy(int id) {
+            if (!nativeDestroyDataLoader(id)) {
+                Slog.w(TAG, "Failed to destroy loader: " + id);
             }
         }
 
         @Override
-        public void prepareImage(InstallationFileParcel[] addedFiles, String[] removedFiles) {
-            if (!nativePrepareImage(mId, addedFiles, removedFiles)) {
-                Slog.w(TAG, "Failed to prepare image for data loader: " + mId);
+        public void prepareImage(int id, InstallationFileParcel[] addedFiles,
+                String[] removedFiles) {
+            if (!nativePrepareImage(id, addedFiles, removedFiles)) {
+                Slog.w(TAG, "Failed to prepare image for data loader: " + id);
             }
         }
     }
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index d273500..28db270 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -176,7 +176,6 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
-    @SystemApi
     public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH          = 0x00000200;
 
     /**
diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java
index ff2f4ad..901957f 100644
--- a/core/java/android/telephony/SubscriptionPlan.java
+++ b/core/java/android/telephony/SubscriptionPlan.java
@@ -91,10 +91,11 @@
     private long dataUsageBytes = BYTES_UNKNOWN;
     private long dataUsageTime = TIME_UNKNOWN;
     private @NetworkType int[] networkTypes;
-    private long networkTypesBitMask;
 
     private SubscriptionPlan(RecurrenceRule cycleRule) {
         this.cycleRule = Preconditions.checkNotNull(cycleRule);
+        this.networkTypes = Arrays.copyOf(TelephonyManager.getAllNetworkTypes(),
+                TelephonyManager.getAllNetworkTypes().length);
     }
 
     private SubscriptionPlan(Parcel source) {
@@ -221,10 +222,10 @@
 
     /**
      * Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to.
-     * A null value means this SubscriptionPlan applies to all network types.
+     * @see TelephonyManager for network types values
      */
-    public @Nullable @NetworkType int[] getNetworkTypes() {
-        return networkTypes;
+    public @NonNull @NetworkType int[] getNetworkTypes() {
+        return Arrays.copyOf(networkTypes, networkTypes.length);
     }
 
     /**
@@ -361,14 +362,14 @@
         }
 
         /**
-         * Set the network types this SubscriptionPlan applies to.
+         * Set the network types this SubscriptionPlan applies to. By default the plan will apply
+         * to all network types. An empty array means this plan applies to no network types.
          *
-         * @param networkTypes a set of all {@link NetworkType}s that apply to this plan.
-         *            A null value means the plan applies to all network types,
-         *            and an empty array means the plan applies to no network types.
+         * @param networkTypes an array of all {@link NetworkType}s that apply to this plan.
+         * @see TelephonyManager for network type values
          */
-        public @NonNull Builder setNetworkTypes(@Nullable @NetworkType int[] networkTypes) {
-            plan.networkTypes = networkTypes;
+        public @NonNull Builder setNetworkTypes(@NonNull @NetworkType int[] networkTypes) {
+            plan.networkTypes = Arrays.copyOf(networkTypes, networkTypes.length);
             return this;
         }
     }
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index cfbe393..4dafc0d 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -67,9 +67,9 @@
         DEFAULT_FLAGS.put("settings_controller_loading_enhancement", "false");
         DEFAULT_FLAGS.put("settings_conditionals", "false");
         DEFAULT_FLAGS.put(NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
-        // Disabled by default until b/148278926 is resolved. This flags guards a feature
-        // introduced in R and will be removed in the next release (b/148367230).
-        DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "false");
+        // This flags guards a feature introduced in R and will be removed in the next release
+        // (b/148367230).
+        DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "true");
 
         DEFAULT_FLAGS.put("settings_tether_all_in_one", "false");
         DEFAULT_FLAGS.put(SETTINGS_SCHEDULES_FLAG, "false");
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
index 79eb9f6..2437af2 100644
--- a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
+++ b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
@@ -213,15 +213,24 @@
                     verityDigest, apk.length(), signatureInfo);
         }
 
-        if (contentDigests.containsKey(CONTENT_DIGEST_CHUNKED_SHA512)) {
-            result.digest = contentDigests.get(CONTENT_DIGEST_CHUNKED_SHA512);
-        } else if (contentDigests.containsKey(CONTENT_DIGEST_CHUNKED_SHA256)) {
-            result.digest = contentDigests.get(CONTENT_DIGEST_CHUNKED_SHA256);
-        }
+        result.digest = pickBestV3DigestForV4(contentDigests);
 
         return result;
     }
 
+    // Keep in sync with pickBestV3DigestForV4 in apksigner.V3SchemeVerifier.
+    private static byte[] pickBestV3DigestForV4(Map<Integer, byte[]> contentDigests) {
+        final int[] orderedContentDigestTypes =
+                {CONTENT_DIGEST_CHUNKED_SHA512, CONTENT_DIGEST_VERITY_CHUNKED_SHA256,
+                        CONTENT_DIGEST_CHUNKED_SHA256};
+        for (int contentDigestType : orderedContentDigestTypes) {
+            if (contentDigests.containsKey(contentDigestType)) {
+                return contentDigests.get(contentDigestType);
+            }
+        }
+        return null;
+    }
+
     private static VerifiedSigner verifySigner(
             ByteBuffer signerBlock,
             Map<Integer, byte[]> contentDigests,
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 0dcb9cc..dffcafe 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -1307,6 +1307,15 @@
     }
 
     /**
+     * Returns true if the display is in active state such as {@link #STATE_ON}
+     * or {@link #STATE_VR}.
+     * @hide
+     */
+    public static boolean isActiveState(int state) {
+        return state == STATE_ON || state == STATE_VR;
+    }
+
+    /**
      * A mode supported by a given display.
      *
      * @see Display#getSupportedModes()
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index baee412..d2e6036 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -200,6 +200,7 @@
         }
         setInsetsAndAlpha(shown ? mShownInsets : mHiddenInsets, 1f /* alpha */, 1f /* fraction */);
         mFinished = true;
+        mListener.onFinished(this);
 
         mShownOnFinish = shown;
     }
@@ -216,11 +217,17 @@
             return;
         }
         mCancelled = true;
-        mListener.onCancelled();
+        mListener.onCancelled(this);
 
         releaseLeashes();
     }
 
+    @Override
+    public boolean isFinished() {
+        return mFinished;
+    }
+
+    @Override
     public boolean isCancelled() {
         return mCancelled;
     }
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 123b9db..96f7340 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -213,7 +213,11 @@
         }
 
         @Override
-        public void onCancelled() {
+        public void onFinished(WindowInsetsAnimationController controller) {
+        }
+
+        @Override
+        public void onCancelled(WindowInsetsAnimationController controller) {
             // Animator can be null when it is cancelled before onReady() completes.
             if (mAnimator != null) {
                 mAnimator.cancel();
@@ -583,7 +587,7 @@
             boolean fromIme, long durationMs, @Nullable Interpolator interpolator,
             @AnimationType int animationType) {
         if (!checkDisplayFramesForControlling()) {
-            listener.onCancelled();
+            listener.onCancelled(null);
             return;
         }
         controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, durationMs,
@@ -608,7 +612,7 @@
             boolean useInsetsAnimationThread) {
         if (types == 0) {
             // nothing to animate.
-            listener.onCancelled();
+            listener.onCancelled(null);
             return;
         }
         cancelExistingControllers(types);
@@ -641,7 +645,7 @@
         }
 
         if (typesReady == 0) {
-            listener.onCancelled();
+            listener.onCancelled(null);
             return;
         }
 
@@ -756,7 +760,7 @@
 
     private void abortPendingImeControlRequest() {
         if (mPendingImeControlRequest != null) {
-            mPendingImeControlRequest.listener.onCancelled();
+            mPendingImeControlRequest.listener.onCancelled(null);
             mPendingImeControlRequest = null;
             mHandler.removeCallbacks(mPendingControlTimeout);
         }
diff --git a/core/java/android/view/PendingInsetsController.java b/core/java/android/view/PendingInsetsController.java
index e8d9bb5..229ee03 100644
--- a/core/java/android/view/PendingInsetsController.java
+++ b/core/java/android/view/PendingInsetsController.java
@@ -172,7 +172,7 @@
             mReplayedInsetsController.controlWindowInsetsAnimation(types, durationMillis,
                     interpolator, cancellationSignal, listener);
         } else {
-            listener.onCancelled();
+            listener.onCancelled(null);
         }
     }
 
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 25f5609..c87808b 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1960,7 +1960,7 @@
      * @hide
      */
     public static ScreenshotGraphicBuffer captureLayersExcluding(SurfaceControl layer,
-            Rect sourceCrop, float frameScale, SurfaceControl[] exclude) {
+          Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) {
         final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
         long[] nativeExcludeObjects = new long[exclude.length];
         for (int i = 0; i < exclude.length; i++) {
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 41a3847..cd22ad6 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -52,7 +52,7 @@
      * a SurfaceView by calling {@link SurfaceView#setChildSurfacePackage}.
      */
     public static final class SurfacePackage implements Parcelable {
-        private final SurfaceControl mSurfaceControl;
+        private SurfaceControl mSurfaceControl;
         private final IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection;
 
         SurfacePackage(SurfaceControl sc, IAccessibilityEmbeddedConnection connection) {
@@ -97,6 +97,19 @@
             out.writeStrongBinder(mAccessibilityEmbeddedConnection.asBinder());
         }
 
+        /**
+         * Release the {@link SurfaceControl} associated with this package.
+         * It's not necessary to call this if you pass the package to
+         * {@link SurfaceView#setChildSurfacePackage} as {@link SurfaceView} will
+         * take ownership in that case.
+         */
+        public void release() {
+            if (mSurfaceControl != null) {
+                mSurfaceControl.release();
+             }
+             mSurfaceControl = null;
+        }
+
         public static final @NonNull Creator<SurfacePackage> CREATOR
              = new Creator<SurfacePackage>() {
                      public SurfacePackage createFromParcel(Parcel in) {
@@ -220,7 +233,7 @@
      * and render the object unusable.
      */
     public void release() {
-        mViewRoot.dispatchDetachedFromWindow();
+        mViewRoot.die(false /* immediate */);
         mSurfaceControl.release();
     }
 
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1f7c3504..3e1e393 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -496,8 +496,17 @@
 
         updateSurface();
         releaseSurfaces();
-        mHaveFrame = false;
 
+        // We don't release this as part of releaseSurfaces as
+        // that is also called on transient visibility changes. We can't
+        // recreate this Surface, so only release it when we are fully
+        // detached.
+        if (mSurfacePackage != null) {
+            mSurfacePackage.release();
+            mSurfacePackage = null;
+        }
+
+        mHaveFrame = false;
         super.onDetachedFromWindow();
     }
 
@@ -1546,7 +1555,9 @@
      * Display the view-hierarchy embedded within a {@link SurfaceControlViewHost.SurfacePackage}
      * within this SurfaceView. If this SurfaceView is above it's host Surface (see
      * {@link #setZOrderOnTop} then the embedded Surface hierarchy will be able to receive
-     * input.
+     * input. This will take ownership of the SurfaceControl contained inside the SurfacePackage
+     * and free the caller of the obligation to call
+     * {@link SurfaceControlViewHost.SurfacePackage#release}.
      *
      * @param p The SurfacePackage to embed.
      */
@@ -1556,6 +1567,7 @@
             mSurfacePackage.getSurfaceControl() : null;
         if (mSurfaceControl != null && lastSc != null) {
             mTmpTransaction.reparent(lastSc, null).apply();
+            mSurfacePackage.release();
         } else if (mSurfaceControl != null) {
             reparentSurfacePackage(mTmpTransaction, p);
             mTmpTransaction.apply();
diff --git a/core/java/android/view/WindowContainerTransaction.java b/core/java/android/view/WindowContainerTransaction.java
index 9c16e13..56b4951 100644
--- a/core/java/android/view/WindowContainerTransaction.java
+++ b/core/java/android/view/WindowContainerTransaction.java
@@ -168,6 +168,18 @@
     }
 
     /**
+     * Sets whether a container or its children should be hidden. When {@code false}, the existing
+     * visibility of the container applies, but when {@code true} the container will be forced
+     * to be hidden.
+     */
+    public WindowContainerTransaction setHidden(IWindowContainer container, boolean hidden) {
+        Change chg = getOrCreateChange(container.asBinder());
+        chg.mHidden = hidden;
+        chg.mChangeMask |= Change.CHANGE_HIDDEN;
+        return this;
+    }
+
+    /**
      * Set the smallestScreenWidth of a container.
      */
     public WindowContainerTransaction setSmallestScreenWidthDp(IWindowContainer container,
@@ -250,9 +262,11 @@
         public static final int CHANGE_FOCUSABLE = 1;
         public static final int CHANGE_BOUNDS_TRANSACTION = 1 << 1;
         public static final int CHANGE_PIP_CALLBACK = 1 << 2;
+        public static final int CHANGE_HIDDEN = 1 << 3;
 
         private final Configuration mConfiguration = new Configuration();
         private boolean mFocusable = true;
+        private boolean mHidden = false;
         private int mChangeMask = 0;
         private @ActivityInfo.Config int mConfigSetMask = 0;
         private @WindowConfiguration.WindowConfig int mWindowSetMask = 0;
@@ -268,6 +282,7 @@
         protected Change(Parcel in) {
             mConfiguration.readFromParcel(in);
             mFocusable = in.readBoolean();
+            mHidden = in.readBoolean();
             mChangeMask = in.readInt();
             mConfigSetMask = in.readInt();
             mWindowSetMask = in.readInt();
@@ -296,7 +311,7 @@
             return mConfiguration;
         }
 
-        /** Gets the requested focusable value */
+        /** Gets the requested focusable state */
         public boolean getFocusable() {
             if ((mChangeMask & CHANGE_FOCUSABLE) == 0) {
                 throw new RuntimeException("Focusable not set. check CHANGE_FOCUSABLE first");
@@ -304,6 +319,14 @@
             return mFocusable;
         }
 
+        /** Gets the requested hidden state */
+        public boolean getHidden() {
+            if ((mChangeMask & CHANGE_HIDDEN) == 0) {
+                throw new RuntimeException("Hidden not set. check CHANGE_HIDDEN first");
+            }
+            return mHidden;
+        }
+
         public int getChangeMask() {
             return mChangeMask;
         }
@@ -369,6 +392,7 @@
         public void writeToParcel(Parcel dest, int flags) {
             mConfiguration.writeToParcel(dest, flags);
             dest.writeBoolean(mFocusable);
+            dest.writeBoolean(mHidden);
             dest.writeInt(mChangeMask);
             dest.writeInt(mConfigSetMask);
             dest.writeInt(mWindowSetMask);
diff --git a/core/java/android/view/WindowInsetsAnimationControlListener.java b/core/java/android/view/WindowInsetsAnimationControlListener.java
index faaf920..b61fa36 100644
--- a/core/java/android/view/WindowInsetsAnimationControlListener.java
+++ b/core/java/android/view/WindowInsetsAnimationControlListener.java
@@ -17,21 +17,31 @@
 package android.view;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.inputmethod.EditorInfo;
 
 /**
- * Interface that informs the client about {@link WindowInsetsAnimationController} state changes.
+ * Listener that encapsulates a request to
+ * {@link WindowInsetsController#controlWindowInsetsAnimation}.
+ *
+ * <p>
+ * Insets can be controlled with the supplied {@link WindowInsetsAnimationController} from
+ * {@link #onReady} until either {@link #onFinished} or {@link #onCancelled}.
+ *
+ * <p>
+ * Once the control over insets is finished or cancelled, it will not be regained until a new
+ * request to {@link WindowInsetsController#controlWindowInsetsAnimation} is made.
+ *
+ * <p>
+ * The request to control insets can fail immediately. In that case {@link #onCancelled} will be
+ * invoked without a preceding {@link #onReady}.
+ *
+ * @see WindowInsetsController#controlWindowInsetsAnimation
  */
 public interface WindowInsetsAnimationControlListener {
 
     /**
-     * @hide
-     */
-    default void onPrepare(int types) {
-    }
-
-    /**
      * Called when the animation is ready to be controlled. This may be delayed when the IME needs
      * to redraw because of an {@link EditorInfo} change, or when the window is starting up.
      *
@@ -41,14 +51,40 @@
      *              {@link WindowInsetsController#controlWindowInsetsAnimation} in case the window
      *              wasn't able to gain the controls because it wasn't the IME target or not
      *              currently the window that's controlling the system bars.
+     * @see WindowInsetsAnimationController#isReady
      */
     void onReady(@NonNull WindowInsetsAnimationController controller, @InsetsType int types);
 
     /**
-     * Called when the window no longer has control over the requested types. If it loses control
-     * over one type, the whole control will be cancelled. If none of the requested types were
-     * available when requesting the control, the animation control will be cancelled immediately
-     * without {@link #onReady} being called.
+     * Called when the request for control over the insets has
+     * {@link WindowInsetsAnimationController#finish finished}.
+     *
+     * Once this callback is invoked, the supplied {@link WindowInsetsAnimationController}
+     * is no longer {@link WindowInsetsAnimationController#isReady() ready}.
+     *
+     * Control will not be regained until a new request
+     * to {@link WindowInsetsController#controlWindowInsetsAnimation} is made.
+     *
+     * @param controller the controller which has finished.
+     * @see WindowInsetsAnimationController#isFinished
      */
-    void onCancelled();
+    void onFinished(@NonNull WindowInsetsAnimationController controller);
+
+    /**
+     * Called when the request for control over the insets has been cancelled, either
+     * because the {@link android.os.CancellationSignal} associated with the
+     * {@link WindowInsetsController#controlWindowInsetsAnimation request} has been invoked, or
+     * the window has lost control over the insets (e.g. because it lost focus).
+     *
+     * Once this callback is invoked, the supplied {@link WindowInsetsAnimationController}
+     * is no longer {@link WindowInsetsAnimationController#isReady() ready}.
+     *
+     * Control will not be regained until a new request
+     * to {@link WindowInsetsController#controlWindowInsetsAnimation} is made.
+     *
+     * @param controller the controller which has been cancelled, or null if the request
+     *                   was cancelled before {@link #onReady} was invoked.
+     * @see WindowInsetsAnimationController#isCancelled
+     */
+    void onCancelled(@Nullable WindowInsetsAnimationController controller);
 }
diff --git a/core/java/android/view/WindowInsetsAnimationController.java b/core/java/android/view/WindowInsetsAnimationController.java
index 2c7880b..c191a54 100644
--- a/core/java/android/view/WindowInsetsAnimationController.java
+++ b/core/java/android/view/WindowInsetsAnimationController.java
@@ -139,10 +139,43 @@
             @FloatRange(from = 0f, to = 1f) float fraction);
 
     /**
-     * Finishes the animation, and leaves the windows shown or hidden. After invoking
-     * {@link #finish(boolean)}, this instance is no longer valid.
+     * Finishes the animation, and leaves the windows shown or hidden.
+     * <p>
+     * After invoking {@link #finish(boolean)}, this instance is no longer {@link #isReady ready}.
+     *
      * @param shown if {@code true}, the windows will be shown after finishing the
      *              animation. Otherwise they will be hidden.
      */
     void finish(boolean shown);
+
+    /**
+     * Returns whether this instance is ready to be used to control window insets.
+     * <p>
+     * Instances are ready when passed in {@link WindowInsetsAnimationControlListener#onReady}
+     * and stop being ready when it is either {@link #isFinished() finished} or
+     * {@link #isCancelled() cancelled}.
+     *
+     * @return {@code true} if the instance is ready, {@code false} otherwise.
+     */
+    default boolean isReady() {
+        return !isFinished() && !isCancelled();
+    }
+
+    /**
+     * Returns whether this instance has been finished by a call to {@link #finish}.
+     *
+     * @see WindowInsetsAnimationControlListener#onFinished
+     * @return {@code true} if the instance is finished, {@code false} otherwise.
+     */
+    boolean isFinished();
+
+    /**
+     * Returns whether this instance has been cancelled by the system, or by invoking the
+     * {@link android.os.CancellationSignal} passed into
+     * {@link WindowInsetsController#controlWindowInsetsAnimation}.
+     *
+     * @see WindowInsetsAnimationControlListener#onCancelled
+     * @return {@code true} if the instance is cancelled, {@code false} otherwise.
+     */
+    boolean isCancelled();
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c5fa3c8..77ce5c1 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -89,6 +89,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 
@@ -2896,6 +2897,18 @@
         private boolean mFitInsetsIgnoringVisibility = false;
 
         /**
+         * {@link InsetsState.InternalInsetsType}s to be applied to the window
+         * If {@link #type} has the predefined insets (like {@link #TYPE_STATUS_BAR} or
+         * {@link #TYPE_NAVIGATION_BAR}), this field will be ignored.
+         *
+         * <p>Note: provide only one inset corresponding to the window type (like
+         * {@link InsetsState.InternalInsetsType#ITYPE_STATUS_BAR} or
+         * {@link InsetsState.InternalInsetsType#ITYPE_NAVIGATION_BAR})</p>
+         * @hide
+         */
+        public @InsetsState.InternalInsetsType int[] providesInsetsTypes;
+
+        /**
          * Specifies types of insets that this window should avoid overlapping during layout.
          *
          * @param types which types of insets that this window should avoid. The initial value of
@@ -3116,6 +3129,12 @@
             out.writeInt(mFitInsetsSides);
             out.writeBoolean(mFitInsetsIgnoringVisibility);
             out.writeBoolean(preferMinimalPostProcessing);
+            if (providesInsetsTypes != null) {
+                out.writeInt(providesInsetsTypes.length);
+                out.writeIntArray(providesInsetsTypes);
+            } else {
+                out.writeInt(0);
+            }
         }
 
         public static final @android.annotation.NonNull Parcelable.Creator<LayoutParams> CREATOR
@@ -3177,6 +3196,11 @@
             mFitInsetsSides = in.readInt();
             mFitInsetsIgnoringVisibility = in.readBoolean();
             preferMinimalPostProcessing = in.readBoolean();
+            int insetsTypesLength = in.readInt();
+            if (insetsTypesLength > 0) {
+                providesInsetsTypes = new int[insetsTypesLength];
+                in.readIntArray(providesInsetsTypes);
+            }
         }
 
         @SuppressWarnings({"PointlessBitwiseExpression"})
@@ -3437,6 +3461,11 @@
                 changes |= LAYOUT_CHANGED;
             }
 
+            if (!Arrays.equals(providesInsetsTypes, o.providesInsetsTypes)) {
+                providesInsetsTypes = o.providesInsetsTypes;
+                changes |= LAYOUT_CHANGED;
+            }
+
             return changes;
         }
 
@@ -3609,6 +3638,14 @@
                 sb.append(System.lineSeparator());
                 sb.append(prefix).append("  fitIgnoreVis");
             }
+            if (providesInsetsTypes != null) {
+                sb.append(System.lineSeparator());
+                sb.append(prefix).append("  insetsTypes=");
+                for (int i = 0; i < providesInsetsTypes.length; ++i) {
+                    if (i > 0) sb.append(' ');
+                    sb.append(InsetsState.typeToString(providesInsetsTypes[i]));
+                }
+            }
 
             sb.append('}');
             return sb.toString();
diff --git a/core/java/android/view/textclassifier/TextClassificationContext.java b/core/java/android/view/textclassifier/TextClassificationContext.java
index f2323c6..5d5683f 100644
--- a/core/java/android/view/textclassifier/TextClassificationContext.java
+++ b/core/java/android/view/textclassifier/TextClassificationContext.java
@@ -31,7 +31,6 @@
  */
 public final class TextClassificationContext implements Parcelable {
 
-    // NOTE: Modify packageName only in the constructor or in setSystemTextClassifierMetadata()
     private String mPackageName;
     private final String mWidgetType;
     @Nullable private final String mWidgetVersion;
@@ -47,7 +46,7 @@
     }
 
     /**
-     * Returns the package name for the calling package.
+     * Returns the package name of the app that this context originated in.
      */
     @NonNull
     public String getPackageName() {
@@ -57,14 +56,10 @@
     /**
      * Sets the information about the {@link SystemTextClassifier} that sent this request.
      *
-     * <p><b>NOTE: </b>This will override the value returned in {@link getPackageName()}.
      * @hide
      */
     void setSystemTextClassifierMetadata(@Nullable SystemTextClassifierMetadata systemTcMetadata) {
         mSystemTcMetadata = systemTcMetadata;
-        if (mSystemTcMetadata != null) {
-            mPackageName = mSystemTcMetadata.getCallingPackageName();
-        }
     }
 
     /**
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index 728824c..d661bc6 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -24,7 +24,6 @@
 import android.text.method.ArrowKeyMovementMethod;
 import android.text.method.MovementMethod;
 import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityNodeInfo;
 
 /*
  * This is supposed to be a *very* thin veneer over TextView.
@@ -179,13 +178,4 @@
     protected boolean supportsAutoSizeText() {
         return false;
     }
-
-    /** @hide */
-    @Override
-    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfoInternal(info);
-        if (isEnabled()) {
-            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_TEXT);
-        }
-    }
 }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 16d9ed3..4aeea10 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -317,6 +317,7 @@
     private SelectionActionModeHelper mSelectionActionModeHelper;
 
     boolean mIsBeingLongClicked;
+    boolean mIsBeingLongClickedByAccessibility;
 
     private SuggestionsPopupWindow mSuggestionsPopupWindow;
     SuggestionRangeSpan mSuggestionRangeSpan;
@@ -1312,6 +1313,12 @@
         if (TextView.DEBUG_CURSOR) {
             logCursor("performLongClick", "handled=%s", handled);
         }
+        if (mIsBeingLongClickedByAccessibility) {
+            if (!handled) {
+                toggleInsertionActionMode();
+            }
+            return true;
+        }
         // Long press in empty space moves cursor and starts the insertion action mode.
         if (!handled && !isPositionOnText(mTouchState.getLastDownX(), mTouchState.getLastDownY())
                 && !mTouchState.isOnHandle() && mInsertionControllerEnabled) {
@@ -1359,6 +1366,14 @@
         return handled;
     }
 
+    private void toggleInsertionActionMode() {
+        if (mTextActionMode != null) {
+            stopTextActionMode();
+        } else {
+            startInsertionActionMode();
+        }
+    }
+
     float getLastUpPositionX() {
         return mTouchState.getLastUpX();
     }
@@ -5436,11 +5451,7 @@
                                 config.getScaledTouchSlop());
                         if (isWithinTouchSlop) {
                             // Tapping on the handle toggles the insertion action mode.
-                            if (mTextActionMode != null) {
-                                stopTextActionMode();
-                            } else {
-                                startInsertionActionMode();
-                            }
+                            toggleInsertionActionMode();
                         }
                     } else {
                         if (mTextActionMode != null) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2168018..e178318 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -12108,6 +12108,23 @@
                     onEditorAction(getImeActionId());
                 }
             } return true;
+            case AccessibilityNodeInfo.ACTION_LONG_CLICK: {
+                if (isLongClickable()) {
+                    boolean handled;
+                    if (isEnabled() && (mBufferType == BufferType.EDITABLE)) {
+                        mEditor.mIsBeingLongClickedByAccessibility = true;
+                        try {
+                            handled = performLongClick();
+                        } finally {
+                            mEditor.mIsBeingLongClickedByAccessibility = false;
+                        }
+                    } else {
+                        handled = performLongClick();
+                    }
+                    return handled;
+                }
+            }
+            return false;
             default: {
                 return super.performAccessibilityActionInternal(action, arguments);
             }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 3696c83..78a0ae0 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1536,10 +1536,12 @@
                 labels.add(innerInfo.getResolveInfo().loadLabel(getPackageManager()));
             }
             f = new ResolverTargetActionsDialogFragment(mti.getDisplayLabel(), name,
-                    mti.getTargets(), labels);
+                    mti.getTargets(), labels,
+                    mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
         } else {
             f = new ResolverTargetActionsDialogFragment(
-                    ti.getResolveInfo().loadLabel(getPackageManager()), name, pinned);
+                    ti.getResolveInfo().loadLabel(getPackageManager()), name, pinned,
+                    mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
         }
 
         f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 086a718..8e64b97 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -49,6 +49,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Insets;
 import android.net.Uri;
 import android.os.Build;
@@ -65,6 +66,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
+import android.util.TypedValue;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -1303,7 +1305,7 @@
         Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                 .setData(Uri.fromParts("package", ri.activityInfo.packageName, null))
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
-        startActivity(in);
+        startActivityAsUser(in, mMultiProfilePagerAdapter.getCurrentUserHandle());
     }
 
     @VisibleForTesting
@@ -1606,7 +1608,10 @@
         for (int i = 0; i < tabWidget.getChildCount(); i++) {
             View tabView = tabWidget.getChildAt(i);
             TextView title = tabView.findViewById(android.R.id.title);
-            title.setTextColor(getColor(R.color.resolver_tabs_inactive_color));
+            title.setTextAppearance(android.R.style.TextAppearance_DeviceDefault_DialogWindowTitle);
+            title.setTextColor(getAttrColor(this, android.R.attr.textColorTertiary));
+            title.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                    getResources().getDimension(R.dimen.resolver_tab_text_size));
             if (title.getText().equals(getString(R.string.resolver_personal_tab))) {
                 tabView.setContentDescription(personalContentDescription);
             } else if (title.getText().equals(getString(R.string.resolver_work_tab))) {
@@ -1615,10 +1620,17 @@
         }
     }
 
+    private static int getAttrColor(Context context, int attr) {
+        TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
+        int colorAccent = ta.getColor(0, 0);
+        ta.recycle();
+        return colorAccent;
+    }
+
     private void updateActiveTabStyle(TabHost tabHost) {
         TextView title = tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab())
                 .findViewById(android.R.id.title);
-        title.setTextColor(getColor(R.color.resolver_tabs_active_color));
+        title.setTextColor(getAttrColor(this, android.R.attr.colorAccent));
     }
 
     private void setupViewVisibilities() {
diff --git a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java
index 21efc78..35d9bcd 100644
--- a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java
+++ b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java
@@ -27,6 +27,7 @@
 import android.content.res.Configuration;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.provider.Settings;
 
 import com.android.internal.R;
@@ -43,6 +44,7 @@
     private static final String NAME_KEY = "componentName";
     private static final String TITLE_KEY = "title";
     private static final String PINNED_KEY = "pinned";
+    private static final String USER_ID_KEY = "userId";
 
     // Sync with R.array.resolver_target_actions_* resources
     private static final int TOGGLE_PIN_INDEX = 0;
@@ -56,19 +58,21 @@
     }
 
     public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name,
-            boolean pinned) {
+            boolean pinned, UserHandle userHandle) {
         Bundle args = new Bundle();
         args.putCharSequence(TITLE_KEY, title);
         args.putParcelable(NAME_KEY, name);
         args.putBoolean(PINNED_KEY, pinned);
+        args.putParcelable(USER_ID_KEY, userHandle);
         setArguments(args);
     }
 
     public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name,
-            List<DisplayResolveInfo> targets, List<CharSequence> labels) {
+            List<DisplayResolveInfo> targets, List<CharSequence> labels, UserHandle userHandle) {
         Bundle args = new Bundle();
         args.putCharSequence(TITLE_KEY, title);
         args.putParcelable(NAME_KEY, name);
+        args.putParcelable(USER_ID_KEY, userHandle);
         mTargetInfos = targets;
         mLabels = labels;
         setArguments(args);
@@ -122,7 +126,8 @@
             Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                     .setData(Uri.fromParts("package", name.getPackageName(), null))
                     .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
-            startActivity(in);
+            UserHandle userHandle = args.getParcelable(USER_ID_KEY);
+            getActivity().startActivityAsUser(in, userHandle);
         }
         dismiss();
     }
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReader.java b/core/java/com/android/internal/os/KernelCpuThreadReader.java
index d92f725b..3407670 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReader.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReader.java
@@ -25,6 +25,7 @@
 import com.android.internal.util.Preconditions;
 
 import java.io.IOException;
+import java.nio.file.DirectoryIteratorException;
 import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -276,7 +277,7 @@
                 }
                 threadCpuUsages.add(threadCpuUsage);
             }
-        } catch (IOException e) {
+        } catch (IOException | DirectoryIteratorException e) {
             // Expected when a process finishes
             return null;
         }
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java b/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java
index ffdc33c..c11b939 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.os;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
+
 import android.annotation.Nullable;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -99,7 +101,7 @@
 
     @VisibleForTesting
     public KernelCpuThreadReaderDiff(KernelCpuThreadReader reader, int minimumTotalCpuUsageMillis) {
-        mReader = reader;
+        mReader = checkNotNull(reader);
         mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
         mPreviousCpuUsage = null;
     }
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
index fdcc8a8..c908b8c 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
@@ -95,8 +95,10 @@
                 KernelCpuThreadReader.create(
                         NUM_BUCKETS_DEFAULT, UidPredicate.fromString(COLLECTED_UIDS_DEFAULT));
         mKernelCpuThreadReaderDiff =
-                new KernelCpuThreadReaderDiff(
-                        mKernelCpuThreadReader, MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT);
+                mKernelCpuThreadReader == null
+                        ? null
+                        : new KernelCpuThreadReaderDiff(
+                                mKernelCpuThreadReader, MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT);
     }
 
     @Override
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 0eb364d..b32b4ae 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -346,6 +346,22 @@
     }
 }
 
+void android_os_Process_enableFreezer(
+        JNIEnv *env, jobject clazz, jboolean enable)
+{
+    bool success = true;
+
+    if (enable) {
+        success = SetTaskProfiles(0, {"FreezerFrozen"}, true);
+    } else {
+        success = SetTaskProfiles(0, {"FreezerThawed"}, true);
+    }
+
+    if (!success) {
+        jniThrowException(env, "java/lang/RuntimeException", "Unknown error");
+    }
+}
+
 jint android_os_Process_getProcessGroup(JNIEnv* env, jobject clazz, jint pid)
 {
     SchedPolicy sp;
@@ -1344,6 +1360,7 @@
         {"sendSignal", "(II)V", (void*)android_os_Process_sendSignal},
         {"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet},
         {"setProcessFrozen", "(IIZ)V", (void*)android_os_Process_setProcessFrozen},
+        {"enableFreezer", "(Z)V", (void*)android_os_Process_enableFreezer},
         {"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory},
         {"getTotalMemory", "()J", (void*)android_os_Process_getTotalMemory},
         {"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V",
diff --git a/core/proto/android/app/appexitinfo.proto b/core/proto/android/app/appexitinfo.proto
index 66173f6..4b9444e 100644
--- a/core/proto/android/app/appexitinfo.proto
+++ b/core/proto/android/app/appexitinfo.proto
@@ -42,4 +42,6 @@
     optional int64 rss = 12;
     optional int64 timestamp = 13;
     optional string description = 14;
+    optional bytes state = 15;
+    optional string trace_file = 16;
 }
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index d6687f0..64cf75d 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -376,8 +376,7 @@
     optional bytes system_trace = 3026 [
         (section).type = SECTION_FILE,
         (section).args = "/data/misc/perfetto-traces/incident-trace",
-        (privacy).dest = DEST_AUTOMATIC,
-        (section).userdebug_and_eng_only = true
+        (privacy).dest = DEST_AUTOMATIC
     ];
 
     // Dropbox entries split by tags.
diff --git a/core/proto/android/util/quotatracker.proto b/core/proto/android/util/quotatracker.proto
index 5d022ed..d98e5ee 100644
--- a/core/proto/android/util/quotatracker.proto
+++ b/core/proto/android/util/quotatracker.proto
@@ -131,93 +131,3 @@
 
   // Next tag: 4
 }
-
-// A com.android.util.quota.DurationQuotaTracker object.
-message DurationQuotaTrackerProto {
-  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-  optional QuotaTrackerProto base_quota_data = 1;
-
-  message DurationLimit {
-    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-    optional CategoryProto category = 1;
-    optional int64 limit_ms = 2;
-    optional int64 window_size_ms = 3;
-  }
-  repeated DurationLimit duration_limit = 2;
-
-  message ExecutionStats {
-    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-    // The time after which this record should be considered invalid (out of date), in the
-    // elapsed realtime timebase.
-    optional int64 expiration_time_elapsed = 1;
-
-    optional int32 window_size_ms = 2;
-    optional int64 duration_limit_ms = 3;
-
-    // The overall session duration in the window.
-    optional int64 session_duration_in_window_ms = 4;
-    // The number of individual long-running events in the window.
-    optional int32 event_count_in_window = 5;
-
-    // The time after which the app will be under the bucket quota. This is only valid if
-    // session_duration_in_window_ms >= duration_limit_ms.
-    optional int64 in_quota_time_elapsed = 6;
-  }
-
-  message Timer {
-    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-    // True if the Timer is actively tracking long-running events.
-    optional bool is_active = 1;
-    // The time this timer last became active. Only valid if is_active is true.
-    optional int64 start_time_elapsed = 2;
-    // How many long-running events are currently running. Valid only if is_active is true.
-    optional int32 event_count = 3;
-  }
-
-  message TimingSession {
-    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-    optional int64 start_time_elapsed = 1;
-    optional int64 end_time_elapsed = 2;
-    // How many events started during this session. This only count long-running events, not
-    // instantaneous events.
-    optional int32 event_count = 3;
-  }
-
-  message UptcStats {
-    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-    optional UptcProto uptc = 1;
-
-    // True if the UPTC has been given free quota.
-    optional bool is_quota_free = 2;
-
-    optional Timer timer = 3;
-
-    repeated TimingSession saved_sessions = 4;
-
-    repeated ExecutionStats execution_stats = 5;
-  }
-  repeated UptcStats uptc_stats = 3;
-
-  message ReachedQuotaAlarmListener {
-    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-    optional int64 trigger_time_elapsed = 1;
-
-    message UptcTimes {
-      option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-      optional UptcProto uptc = 1;
-      optional int64 out_of_quota_time_elapsed = 2;
-    }
-    repeated UptcTimes uptc_times = 2;
-  }
-  optional ReachedQuotaAlarmListener reached_quota_alarm_listener = 4;
-
-  // Next tag: 5
-}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7a3ec95..ad984e6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -737,7 +737,7 @@
     <!-- @SystemApi Allows accessing the messages on ICC
          @hide Used internally. -->
     <permission android:name="android.permission.ACCESS_MESSAGES_ON_ICC"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- Used for runtime permissions related to user's SMS messages. -->
     <permission-group android:name="android.permission-group.SMS"
@@ -1109,13 +1109,12 @@
          grants your app this permission. If you don't need this permission, be sure your <a
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
          targetSdkVersion}</a> is 4 or higher.
-         <p>Protection level: dangerous
+         <p>Protection level: normal
     -->
     <permission android:name="android.permission.READ_PHONE_STATE"
-        android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readPhoneState"
         android:description="@string/permdesc_readPhoneState"
-        android:protectionLevel="dangerous" />
+        android:protectionLevel="normal" />
 
     <!-- Allows read access to the device's phone number(s). This is a subset of the capabilities
          granted by {@link #READ_PHONE_STATE} but is exposed to instant applications.
@@ -1689,13 +1688,17 @@
     <permission android:name="android.permission.NETWORK_FACTORY"
                 android:protectionLevel="signature" />
 
+    <!-- @SystemApi @hide Allows applications to access network stats provider -->
+    <permission android:name="android.permission.NETWORK_STATS_PROVIDER"
+                android:protectionLevel="signature" />
+
     <!-- Allows Settings and SystemUI to call methods in Networking services
          <p>Not for use by third-party or privileged applications.
          @SystemApi @TestApi
          @hide This should only be used by Settings and SystemUI.
     -->
     <permission android:name="android.permission.NETWORK_SETTINGS"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- Allows holder to request bluetooth/wifi scan bypassing global "use location" setting and
          location permissions.
@@ -1841,7 +1844,7 @@
          and bypass OMAPI AccessControlEnforcer.
          <p>Not for use by third-party applications.
          @hide -->
-    <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED"
+    <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION"
         android:protectionLevel="signature|privileged" />
 
     <!-- @deprecated This permission used to allow too broad access to sensitive methods and all its
@@ -2136,7 +2139,7 @@
     <!-- @SystemApi Allows granting runtime permissions to telephony related components.
          @hide -->
     <permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- Allows modification of the telephony state - power on, mmi, etc.
          Does not include placing calls.
@@ -2164,7 +2167,7 @@
     <!-- @SystemApi Allows listen permission to always reported signal strength.
          @hide Used internally. -->
     <permission android:name="android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Protects the ability to register any PhoneAccount with
          PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION. This capability indicates that the PhoneAccount
@@ -2277,21 +2280,21 @@
 
     <!-- Must be required by a telephony data service to ensure that only the
          system can bind to it.
-         <p>Protection level: signature|telephony
+         <p>Protection level: signature
          @SystemApi
          @hide
     -->
     <permission android:name="android.permission.BIND_TELEPHONY_DATA_SERVICE"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a NetworkService to ensure that only the
          system can bind to it.
-         <p>Protection level: signature|telephony
+         <p>Protection level: signature
          @SystemApi
          @hide
     -->
     <permission android:name="android.permission.BIND_TELEPHONY_NETWORK_SERVICE"
-                android:protectionLevel="signature|telephony" />
+                android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to manage embedded subscriptions (those on a eUICC)
          through EuiccManager APIs.
@@ -2303,19 +2306,19 @@
 
     <!-- @SystemApi Must be required by an EuiccService to ensure that only the system can bind to
          it.
-         <p>Protection level: signature|telephony
+         <p>Protection level: signature
          @hide
     -->
     <permission android:name="android.permission.BIND_EUICC_SERVICE"
-                android:protectionLevel="signature|telephony" />
+                android:protectionLevel="signature" />
 
     <!-- Required for reading information about carrier apps from SystemConfigManager.
-         <p>Protection level: signature|telephony
+         <p>Protection level: signature
          @SystemApi
          @hide
     -->
     <permission android:name="android.permission.READ_CARRIER_APP_INFO"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
@@ -2435,7 +2438,7 @@
          types of interactions
          @hide -->
     <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
-        android:protectionLevel="signature|installer|telephony" />
+        android:protectionLevel="signature|installer" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
 
     <!-- Allows interaction across profiles in the same profile group. -->
@@ -2673,7 +2676,7 @@
          @hide
      -->
     <permission android:name="android.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- Allows applications like settings to suggest the user's manually chosen time / time zone.
          <p>Not for use by third-party applications.
@@ -3095,9 +3098,8 @@
 
     <!-- Allows an application to be the status bar.  Currently used only by SystemUI.apk
     @hide -->
-    // TODO: remove telephony once decouple settings activity from phone process
     <permission android:name="android.permission.STATUS_BAR_SERVICE"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to bind to third party quick settings tiles.
          <p>Should only be requested by the System, should be required by
@@ -3154,7 +3156,7 @@
          @hide
     -->
     <permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to use
          {@link android.view.WindowManager.LayoutsParams#SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS}
@@ -3231,7 +3233,7 @@
          @hide
     -->
     <permission android:name="android.permission.SET_ACTIVITY_WATCHER"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to call the activity manager shutdown() API
          to put the higher-level system there into a shutdown state.
@@ -3775,7 +3777,7 @@
          @hide
          STOPSHIP b/145526313: Remove wellbeing protection flag from MANAGE_ROLE_HOLDERS. -->
     <permission android:name="android.permission.MANAGE_ROLE_HOLDERS"
-                android:protectionLevel="signature|installer|telephony|wellbeing" />
+                android:protectionLevel="signature|installer|wellbeing" />
 
     <!-- @SystemApi Allows an application to observe role holder changes.
          @hide -->
@@ -4012,7 +4014,7 @@
         @hide
     -->
    <permission android:name="android.permission.DEVICE_POWER"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- Allows toggling battery saver on the system.
          Superseded by DEVICE_POWER permission. @hide @SystemApi
@@ -4047,13 +4049,13 @@
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.BROADCAST_SMS"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast a WAP PUSH receipt notification.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.BROADCAST_WAP_PUSH"
-        android:protectionLevel="signature|telephony" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to broadcast privileged networking requests.
          <p>Not for use by third-party applications.
@@ -4719,13 +4721,13 @@
          {@link android.provider.BlockedNumberContract}.
          @hide -->
     <permission android:name="android.permission.READ_BLOCKED_NUMBERS"
-                android:protectionLevel="signature|telephony" />
+                android:protectionLevel="signature" />
 
     <!-- Allows the holder to write blocked numbers. See
          {@link android.provider.BlockedNumberContract}.
          @hide -->
     <permission android:name="android.permission.WRITE_BLOCKED_NUMBERS"
-                android:protectionLevel="signature|telephony" />
+                android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.service.vr.VrListenerService}, to ensure that only
          the system can bind to it.
@@ -4885,7 +4887,7 @@
     <!-- @hide Permission that allows configuring appops.
      <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MANAGE_APPOPS"
-                android:protectionLevel="signature|telephony" />
+                android:protectionLevel="signature" />
 
     <!-- @hide Permission that allows background clipboard access.
          <p>Not for use by third-party applications. -->
diff --git a/core/res/res/drawable/tab_indicator_resolver.xml b/core/res/res/drawable/tab_indicator_resolver.xml
index ff16d81a..f97773e 100644
--- a/core/res/res/drawable/tab_indicator_resolver.xml
+++ b/core/res/res/drawable/tab_indicator_resolver.xml
@@ -25,7 +25,7 @@
     </item>
     <item android:gravity="bottom">
         <shape android:shape="rectangle"
-               android:tint="@color/resolver_tabs_active_color">
+               android:tint="?attr/colorAccent">
             <size android:height="2dp" />
             <solid android:color="@color/tab_indicator_material" />
         </shape>
diff --git a/core/res/res/layout/resolver_empty_states.xml b/core/res/res/layout/resolver_empty_states.xml
index 176f289..5fdf190 100644
--- a/core/res/res/layout/resolver_empty_states.xml
+++ b/core/res/res/layout/resolver_empty_states.xml
@@ -60,7 +60,7 @@
         android:background="@null"
         android:fontFamily="@string/config_headlineFontFamilyMedium"
         android:textSize="14sp"
-        android:textColor="@color/resolver_tabs_active_color"
+        android:textColor="?attr/colorAccent"
         android:layout_centerHorizontal="true" />
     <ProgressBar
         android:id="@+id/resolver_empty_state_progress"
@@ -71,5 +71,5 @@
         android:indeterminate="true"
         android:layout_centerHorizontal="true"
         android:layout_below="@+id/resolver_empty_state_subtitle"
-        android:indeterminateTint="@color/resolver_tabs_active_color"/>
+        android:indeterminateTint="?attr/colorAccent"/>
 </RelativeLayout>
\ No newline at end of file
diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml
index 7f77e6c..708b4f3 100644
--- a/core/res/res/values-night/colors.xml
+++ b/core/res/res/values-night/colors.xml
@@ -33,7 +33,6 @@
     <color name="chooser_gradient_background">@color/loading_gradient_background_color_dark</color>
     <color name="chooser_gradient_highlight">@color/loading_gradient_highlight_color_dark</color>
 
-    <color name="resolver_tabs_active_color">#FF8AB4F8</color>
     <color name="resolver_empty_state_text">#FFFFFF</color>
     <color name="resolver_empty_state_icon">#FFFFFF</color>
 </resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f3ca5ac..2496900 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -296,9 +296,6 @@
             granted to the system app predictor -->
         <flag name="appPredictor" value="0x200000" />
         <!-- Additional flag from base permission type: this permission can be automatically
-            granted to the system telephony apps -->
-        <flag name="telephony" value="0x400000" />
-        <!-- Additional flag from base permission type: this permission can be automatically
             granted to the system companion device manager service -->
         <flag name="companion" value="0x800000" />
         <!-- Additional flag from base permission type: this permission will be granted to the
@@ -1835,7 +1832,7 @@
              revoked when the app is unused for an extended amount of time.
 
              The default value is {@code false}. -->
-        <attr name="requestDontAutoRevokePermissions" format="boolean" />
+        <attr name="requestAutoRevokePermissionsExemption" format="boolean" />
 
         <!-- If {@code true} its permissions shouldn't get automatically
              revoked when the app is unused for an extended amount of time.
@@ -1843,7 +1840,7 @@
              This implies {@code requestDontAutoRevokePermissions=true}
 
              The default value is {@code false}. -->
-        <attr name="allowDontAutoRevokePermissions" format="boolean" />
+        <attr name="allowAutoRevokePermissionsExemption" format="boolean" />
     </declare-styleable>
 
     <!-- An attribution is a logical part of an app and is identified by a tag.
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index bdec096..91248f1 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -224,8 +224,6 @@
 
     <!-- Resolver/Chooser -->
     <color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
-    <color name="resolver_tabs_active_color">#FF1A73E8</color>
-    <color name="resolver_tabs_inactive_color">#FF80868B</color>
     <color name="resolver_empty_state_text">#FF202124</color>
     <color name="resolver_empty_state_icon">#FF5F6368</color>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6060d9a..94764ca 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2978,6 +2978,10 @@
     <!-- Whether to use voip audio mode for ims call -->
     <bool name="config_use_voip_mode_for_ims">false</bool>
 
+    <!-- Boolean indicating USSD over IMS is allowed.
+     If it is not supported due to modem limitations, USSD send over the CS pipe instead.-->
+    <bool name="config_allow_ussd_over_ims">false</bool>
+
     <!-- String array containing numbers that shouldn't be logged. Country-specific. -->
     <string-array name="unloggable_phone_numbers" />
 
@@ -3637,15 +3641,6 @@
      -->
     <string name="config_defaultWellbeingPackage" translatable="false"></string>
 
-    <!-- The package name for the system telephony apps.
-         This package must be trusted, as it will be granted with permissions with special telephony
-         protection level. Note, framework by default support multiple telephony apps, each package
-         name is separated by comma.
-         Example: "com.android.phone,com.android.stk,com.android.providers.telephony"
-         (Note: shell is included for testing purposes)
-     -->
-    <string name="config_telephonyPackages" translatable="false">"com.android.phone,com.android.stk,com.android.providers.telephony,com.android.ons"</string>
-
     <!-- The component name for the default system attention service.
          This service must be trusted, as it can be activated without explicit consent of the user.
          See android.attention.AttentionManagerService.
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 15ef09c..4dedc63 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -800,6 +800,7 @@
     <dimen name="resolver_empty_state_height_with_tabs">268dp</dimen>
     <dimen name="resolver_max_collapsed_height">192dp</dimen>
     <dimen name="resolver_max_collapsed_height_with_tabs">248dp</dimen>
+    <dimen name="resolver_tab_text_size">14sp</dimen>
 
     <dimen name="chooser_action_button_icon_size">18dp</dimen>
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index cf68aff..5306518 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3014,8 +3014,8 @@
       <!-- @hide @SystemApi -->
       <public name="minExtensionVersion" />
       <public name="allowNativeHeapPointerTagging" />
-      <public name="requestDontAutoRevokePermissions" />
-      <public name="allowDontAutoRevokePermissions" />
+      <public name="requestAutoRevokePermissionsExemption" />
+      <public name="allowAutoRevokePermissionsExemption" />
       <public name="preserveLegacyExternalStorage" />
       <public name="mimeGroup" />
       <public name="enableGwpAsan" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f101f59..26024ed 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1169,7 +1169,7 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
     <string name="permlab_cameraOpenCloseListener">Allow an application or service to receive callbacks about camera devices being opened or closed.</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
-    <string name="permdesc_cameraOpenCloseListener">This signature app can receive callbacks when any camera device is being opened (by what application package) or closed.</string>
+    <string name="permdesc_cameraOpenCloseListener">This app can receive callbacks when any camera device is being opened (by what application) or closed.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_vibrate">control vibration</string>
@@ -2985,72 +2985,6 @@
     <!-- Title for EditText context menu [CHAR LIMIT=20] -->
     <string name="editTextMenuTitle">Text actions</string>
 
-    <!-- Label for item in the text selection menu to trigger an Email app. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="email">Email</string>
-
-    <!-- Accessibility description for an item in the text selection menu to trigger an Email app [CHAR LIMIT=NONE] -->
-    <string name="email_desc">Email selected address</string>
-
-    <!-- Label for item in the text selection menu to trigger a Dialer app. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="dial">Call</string>
-
-    <!-- Accessibility description for an item in the text selection menu to call a phone number [CHAR LIMIT=NONE] -->
-    <string name="dial_desc">Call selected phone number</string>
-
-    <!-- Label for item in the text selection menu to trigger a Map app. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="map">Map</string>
-
-    <!-- Accessibility description for an item in the text selection menu to open maps for an address [CHAR LIMIT=NONE] -->
-    <string name="map_desc">Locate selected address</string>
-
-    <!-- Label for item in the text selection menu to trigger a Browser app. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="browse">Open</string>
-
-    <!-- Accessibility description for an item in the text selection menu to open a URL in a browser [CHAR LIMIT=NONE] -->
-    <string name="browse_desc">Open selected URL</string>
-
-    <!-- Label for item in the text selection menu to trigger an SMS app. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="sms">Message</string>
-
-    <!-- Accessibility description for an item in the text selection menu to send an SMS to a phone number [CHAR LIMIT=NONE] -->
-    <string name="sms_desc">Message selected phone number</string>
-
-    <!-- Label for item in the text selection menu to trigger adding a contact. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="add_contact">Add</string>
-
-    <!-- Accessibility description for an item in the text selection menu to add the selected detail to contacts [CHAR LIMIT=NONE] -->
-    <string name="add_contact_desc">Add to contacts</string>
-
-    <!-- Label for item in the text selection menu to view the calendar for the selected time/date. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="view_calendar">View</string>
-
-    <!-- Accessibility description for an item in the text selection menu to view the calendar for a date [CHAR LIMIT=NONE]-->
-    <string name="view_calendar_desc">View selected time in calendar</string>
-
-    <!-- Label for item in the text selection menu to create a calendar event at the selected time/date. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="add_calendar_event">Schedule</string>
-
-    <!-- Accessibility description for an item in the text selection menu to schedule an event for a date [CHAR LIMIT=NONE] -->
-    <string name="add_calendar_event_desc">Schedule event for selected time</string>
-
-    <!-- Label for item in the text selection menu to track a selected flight number. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="view_flight">Track</string>
-
-    <!-- Accessibility description for an item in the text selection menu to track a flight [CHAR LIMIT=NONE] -->
-    <string name="view_flight_desc">Track selected flight</string>
-
-    <!-- Label for item in the text selection menu to translate selected text with a translation app. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="translate">Translate</string>
-
-    <!-- Accessibility description for an item in the text selection menu to translate selected text with a translation app. [CHAR LIMIT=NONE] -->
-    <string name="translate_desc">Translate selected text</string>
-
-    <!-- Label for item in the text selection menu to define selected text with a dictionary app. Should be a verb. [CHAR LIMIT=30] -->
-    <string name="define">Define</string>
-
-    <!-- Accessibility description for an item in the text selection menu to define selected text with a dictionary app. Should be a verb. [CHAR LIMIT=NONE] -->
-    <string name="define_desc">Define selected text</string>
-
     <!-- If the device is getting low on internal storage, a notification is shown to the user.  This is the title of that notification. -->
     <string name="low_internal_storage_view_title">Storage space running out</string>
     <!-- If the device is getting low on internal storage, a notification is shown to the user.  This is the message of that notification. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4c0dd8d..a1b00f2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -551,28 +551,6 @@
   <java-symbol type="string" name="replace" />
   <java-symbol type="string" name="undo" />
   <java-symbol type="string" name="redo" />
-  <java-symbol type="string" name="email" />
-  <java-symbol type="string" name="email_desc" />
-  <java-symbol type="string" name="dial" />
-  <java-symbol type="string" name="dial_desc" />
-  <java-symbol type="string" name="map" />
-  <java-symbol type="string" name="map_desc" />
-  <java-symbol type="string" name="browse" />
-  <java-symbol type="string" name="browse_desc" />
-  <java-symbol type="string" name="sms" />
-  <java-symbol type="string" name="sms_desc" />
-  <java-symbol type="string" name="add_contact" />
-  <java-symbol type="string" name="add_contact_desc" />
-  <java-symbol type="string" name="view_calendar" />
-  <java-symbol type="string" name="view_calendar_desc" />
-  <java-symbol type="string" name="add_calendar_event" />
-  <java-symbol type="string" name="add_calendar_event_desc" />
-  <java-symbol type="string" name="view_flight" />
-  <java-symbol type="string" name="view_flight_desc" />
-  <java-symbol type="string" name="translate" />
-  <java-symbol type="string" name="translate_desc" />
-  <java-symbol type="string" name="define" />
-  <java-symbol type="string" name="define_desc" />
   <java-symbol type="string" name="textSelectionCABTitle" />
   <java-symbol type="string" name="BaMmi" />
   <java-symbol type="string" name="CLIRDefaultOffNextCallOff" />
@@ -2553,6 +2531,7 @@
   <java-symbol type="bool" name="config_device_wfc_ims_available" />
   <java-symbol type="bool" name="config_carrier_wfc_ims_available" />
   <java-symbol type="bool" name="config_use_voip_mode_for_ims" />
+  <java-symbol type="bool" name="config_allow_ussd_over_ims" />
   <java-symbol type="attr" name="touchscreenBlocksFocus" />
   <java-symbol type="layout" name="resolver_list_with_default" />
   <java-symbol type="string" name="activity_resolver_set_always" />
@@ -3418,7 +3397,6 @@
   <java-symbol type="string" name="config_defaultAutofillService" />
   <java-symbol type="string" name="config_defaultTextClassifierPackage" />
   <java-symbol type="string" name="config_defaultWellbeingPackage" />
-  <java-symbol type="string" name="config_telephonyPackages" />
   <java-symbol type="string" name="config_defaultContentCaptureService" />
   <java-symbol type="string" name="config_defaultAugmentedAutofillService" />
   <java-symbol type="string" name="config_defaultAppPredictionService" />
@@ -3906,8 +3884,6 @@
   <java-symbol type="layout" name="conversation_face_pile_layout" />
 
   <!-- Intent resolver and share sheet -->
-  <java-symbol type="color" name="resolver_tabs_active_color" />
-  <java-symbol type="color" name="resolver_tabs_inactive_color" />
   <java-symbol type="string" name="resolver_personal_tab" />
   <java-symbol type="string" name="resolver_personal_tab_accessibility" />
   <java-symbol type="string" name="resolver_work_tab" />
@@ -3938,6 +3914,7 @@
   <java-symbol type="dimen" name="resolver_empty_state_height_with_tabs" />
   <java-symbol type="dimen" name="resolver_max_collapsed_height_with_tabs" />
   <java-symbol type="bool" name="sharesheet_show_content_preview" />
+  <java-symbol type="dimen" name="resolver_tab_text_size" />
 
   <!-- Toast message for background started foreground service while-in-use permission restriction feature -->
   <java-symbol type="string" name="allow_while_in_use_permission_in_fgs" />
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
index 5d42915..4b42f4ae 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -268,7 +268,7 @@
         File snd_stat = new File (root_filepath + "tcp_snd");
         int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat);
         NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
-        stats.addEntry(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT,
+        stats.insertEntry(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT,
                 NetworkStats.TAG_NONE, rx, 0, tx, 0, 0);
         return stats;
     }
diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
index 239f971..3ebe103 100644
--- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
@@ -54,7 +54,7 @@
             recycle.txBytes = 150000;
             recycle.txPackets = 1500;
             recycle.operations = 0;
-            mNetworkStats.addEntry(recycle);
+            mNetworkStats.insertEntry(recycle);
             if (recycle.set == 1) {
                 uid++;
             }
@@ -70,7 +70,7 @@
             recycle.txBytes = 180000 * mSize;
             recycle.txPackets = 1200 * mSize;
             recycle.operations = 0;
-            mNetworkStats.addEntry(recycle);
+            mNetworkStats.insertEntry(recycle);
         }
     }
 
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index c328d72..90d8bab 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -40,7 +40,10 @@
 import android.app.servertransaction.StopActivityItem;
 import android.content.Intent;
 import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
 import android.os.IBinder;
+import android.util.DisplayMetrics;
 import android.util.MergedConfiguration;
 import android.view.Display;
 import android.view.View;
@@ -307,6 +310,58 @@
     }
 
     @Test
+    public void testHandleConfigurationChangedDoesntOverrideActivityConfig() {
+        final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            final Configuration oldActivityConfig =
+                    new Configuration(activity.getResources().getConfiguration());
+            final DisplayMetrics oldActivityMetrics = new DisplayMetrics();
+            activity.getDisplay().getMetrics(oldActivityMetrics);
+            final Resources oldAppResources = activity.getApplication().getResources();
+            final Configuration oldAppConfig =
+                    new Configuration(oldAppResources.getConfiguration());
+            final DisplayMetrics oldApplicationMetrics = new DisplayMetrics();
+            oldApplicationMetrics.setTo(oldAppResources.getDisplayMetrics());
+            assertEquals("Process config must match the top activity config by default",
+                    0, oldActivityConfig.diffPublicOnly(oldAppConfig));
+            assertEquals("Process config must match the top activity config by default",
+                    oldActivityMetrics, oldApplicationMetrics);
+
+            // Update the application configuration separately from activity config
+            final Configuration newAppConfig = new Configuration(oldAppConfig);
+            newAppConfig.densityDpi += 100;
+            newAppConfig.screenHeightDp += 100;
+            final Rect newBounds = new Rect(newAppConfig.windowConfiguration.getAppBounds());
+            newBounds.bottom += 100;
+            newAppConfig.windowConfiguration.setAppBounds(newBounds);
+            newAppConfig.windowConfiguration.setBounds(newBounds);
+            newAppConfig.seq++;
+
+            final ActivityThread activityThread = activity.getActivityThread();
+            activityThread.handleConfigurationChanged(newAppConfig);
+
+            // Verify that application config update was applied, but didn't change activity config.
+            assertEquals("Activity config must not change if the process config changes",
+                    oldActivityConfig, activity.getResources().getConfiguration());
+
+            final DisplayMetrics newActivityMetrics = new DisplayMetrics();
+            activity.getDisplay().getMetrics(newActivityMetrics);
+            assertEquals("Activity display size must not change if the process config changes",
+                    oldActivityMetrics, newActivityMetrics);
+            final Resources newAppResources = activity.getApplication().getResources();
+            assertEquals("Application config must be updated",
+                    newAppConfig, newAppResources.getConfiguration());
+            final DisplayMetrics newApplicationMetrics = new DisplayMetrics();
+            newApplicationMetrics.setTo(newAppResources.getDisplayMetrics());
+            assertNotEquals("Application display size must be updated after config update",
+                    oldApplicationMetrics, newApplicationMetrics);
+            assertNotEquals("Application display size must be updated after config update",
+                    newActivityMetrics, newApplicationMetrics);
+        });
+    }
+
+    @Test
     public void testResumeAfterNewIntent() {
         final Activity activity = mActivityTestRule.launchActivity(new Intent());
         final ActivityThread activityThread = activity.getActivityThread();
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index fe25e79..22b4e45 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -188,7 +188,7 @@
             fail("Expected exception to be thrown");
         } catch (IllegalStateException ignored) {
         }
-        verify(mMockListener).onCancelled();
+        verify(mMockListener).onCancelled(mController);
         mController.finish(true /* shown */);
     }
 
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 42ab2e7..90a62e7 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -204,7 +204,7 @@
             mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
             verify(mockListener).onReady(any(), anyInt());
             mController.onControlsChanged(new InsetsSourceControl[0]);
-            verify(mockListener).onCancelled();
+            verify(mockListener).onCancelled(notNull());
         });
     }
 
@@ -221,7 +221,7 @@
                 new CancellationSignal(), controlListener);
         mController.addOnControllableInsetsChangedListener(
                 (controller, typeMask) -> assertEquals(0, typeMask));
-        verify(controlListener).onCancelled();
+        verify(controlListener).onCancelled(null);
         verify(controlListener, never()).onReady(any(), anyInt());
     }
 
@@ -533,7 +533,7 @@
             verify(mockListener).onReady(any(), anyInt());
 
             cancellationSignal.cancel();
-            verify(mockListener).onCancelled();
+            verify(mockListener).onCancelled(notNull());
         });
         waitUntilNextFrame();
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
@@ -584,7 +584,7 @@
             // Pretend that we are losing control
             mController.onControlsChanged(new InsetsSourceControl[0]);
 
-            verify(listener).onCancelled();
+            verify(listener).onCancelled(null);
         });
     }
 
@@ -606,7 +606,7 @@
             mTestClock.fastForward(2500);
             mTestHandler.timeAdvance();
 
-            verify(listener).onCancelled();
+            verify(listener).onCancelled(null);
         });
     }
 
@@ -621,7 +621,7 @@
                     cancellationSignal, listener);
             cancellationSignal.cancel();
 
-            verify(listener).onCancelled();
+            verify(listener).onCancelled(null);
 
             // Ready gets deferred until next predraw
             mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
diff --git a/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java b/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java
index 33f859e..03c8b1b 100644
--- a/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java
@@ -99,7 +99,7 @@
         CancellationSignal cancellationSignal = new CancellationSignal();
         mPendingInsetsController.controlWindowInsetsAnimation(
                 systemBars(), 0, new LinearInterpolator(), cancellationSignal, listener);
-        verify(listener).onCancelled();
+        verify(listener).onCancelled(null);
         assertFalse(cancellationSignal.isCanceled());
     }
 
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index a72be25..45d4b38 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -65,6 +65,7 @@
 import android.app.Instrumentation;
 import android.content.ClipData;
 import android.content.ClipboardManager;
+import android.os.Bundle;
 import android.support.test.uiautomator.UiDevice;
 import android.text.InputType;
 import android.text.Selection;
@@ -75,6 +76,7 @@
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.textclassifier.SelectionEvent;
 import android.view.textclassifier.TextClassificationManager;
 import android.view.textclassifier.TextClassifier;
@@ -358,6 +360,20 @@
     }
 
     @Test
+    public void testToolbarAppearsAccessibilityLongClick() throws Throwable {
+        final String text = "Toolbar appears after performing accessibility's ACTION_LONG_CLICK.";
+        mActivityRule.runOnUiThread(() -> {
+            final TextView textView = mActivity.findViewById(R.id.textview);
+            final Bundle args = new Bundle();
+            textView.performAccessibilityAction(AccessibilityNodeInfo.ACTION_LONG_CLICK, args);
+        });
+        mInstrumentation.waitForIdleSync();
+
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+    }
+
+    @Test
     public void testSelectionRemovedWhenNonselectableTextLosesFocus() throws Throwable {
         final TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview);
         final int position = (textLink.getStart() + textLink.getEnd()) / 2;
diff --git a/data/etc/com.android.launcher3.xml b/data/etc/com.android.launcher3.xml
index 337e153..17d614e 100644
--- a/data/etc/com.android.launcher3.xml
+++ b/data/etc/com.android.launcher3.xml
@@ -19,5 +19,6 @@
         <permission name="android.permission.BIND_APPWIDGET"/>
         <permission name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/>
         <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
     </privapp-permissions>
 </permissions>
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 83a8995..5e3b8aa 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -21,8 +21,8 @@
 import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_FREQUENCY;
 import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_PHASE;
 import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_PHASE_UNCERTAINTY;
-import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_RECEIVER_ISB;
-import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_RECEIVER_ISB_UNCERTAINTY;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_FULL_ISB;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_FULL_ISB_UNCERTAINTY;
 import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_SATELLITE_ISB;
 import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_SATELLITE_ISB_UNCERTAINTY;
 import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_SNR;
@@ -63,8 +63,8 @@
     private double mSnrInDb;
     private double mAutomaticGainControlLevelInDb;
     @NonNull private String mCodeType;
-    private double mReceiverInterSignalBiasNanos;
-    private double mReceiverInterSignalBiasUncertaintyNanos;
+    private double mFullInterSignalBiasNanos;
+    private double mFullInterSignalBiasUncertaintyNanos;
     private double mSatelliteInterSignalBiasNanos;
     private double mSatelliteInterSignalBiasUncertaintyNanos;
 
@@ -268,9 +268,9 @@
         mSnrInDb = measurement.mSnrInDb;
         mAutomaticGainControlLevelInDb = measurement.mAutomaticGainControlLevelInDb;
         mCodeType = measurement.mCodeType;
-        mReceiverInterSignalBiasNanos = measurement.mReceiverInterSignalBiasNanos;
-        mReceiverInterSignalBiasUncertaintyNanos =
-                measurement.mReceiverInterSignalBiasUncertaintyNanos;
+        mFullInterSignalBiasNanos = measurement.mFullInterSignalBiasNanos;
+        mFullInterSignalBiasUncertaintyNanos =
+                measurement.mFullInterSignalBiasUncertaintyNanos;
         mSatelliteInterSignalBiasNanos = measurement.mSatelliteInterSignalBiasNanos;
         mSatelliteInterSignalBiasUncertaintyNanos =
                 measurement.mSatelliteInterSignalBiasUncertaintyNanos;
@@ -1435,99 +1435,110 @@
     }
 
     /**
-     * Returns {@code true} if {@link #getReceiverInterSignalBiasNanos()} is available,
+     * Returns {@code true} if {@link #getFullInterSignalBiasNanos()} is available,
      * {@code false} otherwise.
      */
-    public boolean hasReceiverInterSignalBiasNanos() {
-        return isFlagSet(HAS_RECEIVER_ISB);
+    public boolean hasFullInterSignalBiasNanos() {
+        return isFlagSet(HAS_FULL_ISB);
     }
 
     /**
-     * Gets the GNSS measurement's receiver inter-signal bias in nanoseconds with sub-nanosecond
-     * accuracy.
+     * Gets the GNSS measurement's inter-signal bias in nanoseconds with sub-nanosecond accuracy.
      *
-     * <p>This value is the estimated receiver-side inter-system (different from the
-     * constellation in {@link GnssClock#getReferenceConstellationTypeForIsb()} bias and
-     * inter-frequency (different from the carrier frequency in
-     * {@link GnssClock#getReferenceCarrierFrequencyHzForIsb()}) bias. The reported receiver
-     * inter-signal bias must include signal delays caused by:
+     * <p>This value is the sum of the estimated receiver-side and the space-segment-side
+     * inter-system bias, inter-frequency bias and inter-code bias, including:
      *
      * <ul>
-     * <li>Receiver inter-constellation bias</li>
-     * <li>Receiver inter-frequency bias</li>
-     * <li>Receiver inter-code bias</li>
+     * <li>Receiver inter-constellation bias (with respect to the constellation in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Receiver inter-frequency bias (with respect to the carrier frequency in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Receiver inter-code bias (with respect to the code type in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPS-UTC Time Offset (TauGps),
+     * BDS-GLO Time Offset (BGTO))(with respect to the constellation in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Group delay (e.g., Total Group Delay (TGD))</li>
+     * <li>Satellite inter-frequency bias (GLO only) (with respect to the carrier frequency in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Satellite inter-code bias (e.g., Differential Code Bias (DCB)) (with respect to the code
+     * type in {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
      * </ul>
      *
+     * <p>If a component of the above is already compensated in the provided
+     * {@link GnssMeasurement#getReceivedSvTimeNanos()}, then it must not be included in the
+     * reported full ISB.
+     *
      * <p>The value does not include the inter-frequency Ionospheric bias.
      *
-     * <p>The value is only available if {@link #hasReceiverInterSignalBiasNanos()} is {@code true}.
+     * <p>The value is only available if {@link #hasFullInterSignalBiasNanos()} is {@code true}.
      */
-    public double getReceiverInterSignalBiasNanos() {
-        return mReceiverInterSignalBiasNanos;
+    public double getFullInterSignalBiasNanos() {
+        return mFullInterSignalBiasNanos;
     }
 
     /**
-     * Sets the GNSS measurement's receiver inter-signal bias in nanoseconds.
+     * Sets the GNSS measurement's inter-signal bias in nanoseconds.
      *
      * @hide
      */
     @TestApi
-    public void setReceiverInterSignalBiasNanos(double receiverInterSignalBiasNanos) {
-        setFlag(HAS_RECEIVER_ISB);
-        mReceiverInterSignalBiasNanos = receiverInterSignalBiasNanos;
+    public void setFullInterSignalBiasNanos(double fullInterSignalBiasNanos) {
+        setFlag(HAS_FULL_ISB);
+        mFullInterSignalBiasNanos = fullInterSignalBiasNanos;
     }
 
     /**
-     * Resets the GNSS measurement's receiver inter-signal bias in nanoseconds.
+     * Resets the GNSS measurement's inter-signal bias in nanoseconds.
      *
      * @hide
      */
     @TestApi
-    public void resetReceiverInterSignalBiasNanos() {
-        resetFlag(HAS_RECEIVER_ISB);
+    public void resetFullInterSignalBiasNanos() {
+        resetFlag(HAS_FULL_ISB);
     }
 
     /**
-     * Returns {@code true} if {@link #getReceiverInterSignalBiasUncertaintyNanos()} is available,
+     * Returns {@code true} if {@link #getFullInterSignalBiasUncertaintyNanos()} is available,
      * {@code false} otherwise.
      */
-    public boolean hasReceiverInterSignalBiasUncertaintyNanos() {
-        return isFlagSet(HAS_RECEIVER_ISB_UNCERTAINTY);
+    public boolean hasFullInterSignalBiasUncertaintyNanos() {
+        return isFlagSet(HAS_FULL_ISB_UNCERTAINTY);
     }
 
     /**
-     * Gets the GNSS measurement's receiver inter-signal bias uncertainty (1 sigma) in
+     * Gets the GNSS measurement's inter-signal bias uncertainty (1 sigma) in
      * nanoseconds with sub-nanosecond accuracy.
      *
-     * <p>The value is only available if {@link #hasReceiverInterSignalBiasUncertaintyNanos()} is
+     * <p>The value is only available if {@link #hasFullInterSignalBiasUncertaintyNanos()} is
      * {@code true}.
      */
     @FloatRange(from = 0.0)
-    public double getReceiverInterSignalBiasUncertaintyNanos() {
-        return mReceiverInterSignalBiasUncertaintyNanos;
+    public double getFullInterSignalBiasUncertaintyNanos() {
+        return mFullInterSignalBiasUncertaintyNanos;
     }
 
     /**
-     * Sets the GNSS measurement's receiver inter-signal bias uncertainty (1 sigma) in nanoseconds.
+     * Sets the GNSS measurement's inter-signal bias uncertainty (1 sigma) in nanoseconds.
      *
      * @hide
      */
     @TestApi
-    public void setReceiverInterSignalBiasUncertaintyNanos(@FloatRange(from = 0.0)
-            double receiverInterSignalBiasUncertaintyNanos) {
-        setFlag(HAS_RECEIVER_ISB_UNCERTAINTY);
-        mReceiverInterSignalBiasUncertaintyNanos = receiverInterSignalBiasUncertaintyNanos;
+    public void setFullInterSignalBiasUncertaintyNanos(@FloatRange(from = 0.0)
+            double fullInterSignalBiasUncertaintyNanos) {
+        setFlag(HAS_FULL_ISB_UNCERTAINTY);
+        mFullInterSignalBiasUncertaintyNanos = fullInterSignalBiasUncertaintyNanos;
     }
 
     /**
-     * Resets the GNSS measurement's receiver inter-signal bias uncertainty (1 sigma) in
+     * Resets the GNSS measurement's inter-signal bias uncertainty (1 sigma) in
      * nanoseconds.
      *
      * @hide
      */
     @TestApi
-    public void resetReceiverInterSignalBiasUncertaintyNanos() {
-        resetFlag(HAS_RECEIVER_ISB_UNCERTAINTY);
+    public void resetFullInterSignalBiasUncertaintyNanos() {
+        resetFlag(HAS_FULL_ISB_UNCERTAINTY);
     }
 
     /**
@@ -1542,17 +1553,18 @@
      * Gets the GNSS measurement's satellite inter-signal bias in nanoseconds with sub-nanosecond
      * accuracy.
      *
-     * <p>This value is the satellite-and-control-segment-side inter-system (different from the
-     * constellation in {@link GnssClock#getReferenceConstellationTypeForIsb()}) bias and
-     * inter-frequency (different from the carrier frequency in
-     * {@link GnssClock#getReferenceCarrierFrequencyHzForIsb()}) bias, including:
+     * <p>This value is the space-segment-side inter-system bias, inter-frequency bias and
+     * inter-code bias, including:
      *
      * <ul>
-     * <li>Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPT-UTC Time Offset (TauGps),
-     * BDS-GLO Time Offset (BGTO))</li>
+     * <li>Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPS-UTC Time Offset (TauGps),
+     * BDS-GLO Time Offset (BGTO))(with respect to the constellation in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
      * <li>Group delay (e.g., Total Group Delay (TGD))</li>
-     * <li>Satellite inter-signal bias, which includes satellite inter-frequency bias (GLO only),
-     * and satellite inter-code bias (e.g., Differential Code Bias (DCB)).</li>
+     * <li>Satellite inter-frequency bias (GLO only) (with respect to the carrier frequency in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Satellite inter-code bias (e.g., Differential Code Bias (DCB)) (with respect to the code
+     * type in {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
      * </ul>
      *
      * <p>The value is only available if {@link #hasSatelliteInterSignalBiasNanos()} is {@code
@@ -1654,8 +1666,8 @@
             gnssMeasurement.mAutomaticGainControlLevelInDb = parcel.readDouble();
             gnssMeasurement.mCodeType = parcel.readString();
             gnssMeasurement.mBasebandCn0DbHz = parcel.readDouble();
-            gnssMeasurement.mReceiverInterSignalBiasNanos = parcel.readDouble();
-            gnssMeasurement.mReceiverInterSignalBiasUncertaintyNanos = parcel.readDouble();
+            gnssMeasurement.mFullInterSignalBiasNanos = parcel.readDouble();
+            gnssMeasurement.mFullInterSignalBiasUncertaintyNanos = parcel.readDouble();
             gnssMeasurement.mSatelliteInterSignalBiasNanos = parcel.readDouble();
             gnssMeasurement.mSatelliteInterSignalBiasUncertaintyNanos = parcel.readDouble();
 
@@ -1692,8 +1704,8 @@
         parcel.writeDouble(mAutomaticGainControlLevelInDb);
         parcel.writeString(mCodeType);
         parcel.writeDouble(mBasebandCn0DbHz);
-        parcel.writeDouble(mReceiverInterSignalBiasNanos);
-        parcel.writeDouble(mReceiverInterSignalBiasUncertaintyNanos);
+        parcel.writeDouble(mFullInterSignalBiasNanos);
+        parcel.writeDouble(mFullInterSignalBiasUncertaintyNanos);
         parcel.writeDouble(mSatelliteInterSignalBiasNanos);
         parcel.writeDouble(mSatelliteInterSignalBiasUncertaintyNanos);
     }
@@ -1778,14 +1790,14 @@
             builder.append(String.format(format, "CodeType", mCodeType));
         }
 
-        if (hasReceiverInterSignalBiasNanos() || hasReceiverInterSignalBiasUncertaintyNanos()) {
+        if (hasFullInterSignalBiasNanos() || hasFullInterSignalBiasUncertaintyNanos()) {
             builder.append(String.format(
                     formatWithUncertainty,
-                    "ReceiverInterSignalBiasNs",
-                    hasReceiverInterSignalBiasNanos() ? mReceiverInterSignalBiasNanos : null,
-                    "ReceiverInterSignalBiasUncertaintyNs",
-                    hasReceiverInterSignalBiasUncertaintyNanos()
-                            ? mReceiverInterSignalBiasUncertaintyNanos : null));
+                    "InterSignalBiasNs",
+                    hasFullInterSignalBiasNanos() ? mFullInterSignalBiasNanos : null,
+                    "InterSignalBiasUncertaintyNs",
+                    hasFullInterSignalBiasUncertaintyNanos()
+                            ? mFullInterSignalBiasUncertaintyNanos : null));
         }
 
         if (hasSatelliteInterSignalBiasNanos() || hasSatelliteInterSignalBiasUncertaintyNanos()) {
@@ -1824,8 +1836,8 @@
         resetAutomaticGainControlLevel();
         resetCodeType();
         resetBasebandCn0DbHz();
-        resetReceiverInterSignalBiasNanos();
-        resetReceiverInterSignalBiasUncertaintyNanos();
+        resetFullInterSignalBiasNanos();
+        resetFullInterSignalBiasUncertaintyNanos();
         resetSatelliteInterSignalBiasNanos();
         resetSatelliteInterSignalBiasUncertaintyNanos();
     }
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index 3a771bb..ad9486c 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -870,16 +870,17 @@
     private int getSessionResourceId() throws MediaCasException {
         validateInternalStates();
 
-        int[] sessionResourceId = new int[1];
-        sessionResourceId[0] = -1;
+        int[] sessionResourceHandle = new int[1];
+        sessionResourceHandle[0] = -1;
         if (mTunerResourceManager != null) {
             CasSessionRequest casSessionRequest = new CasSessionRequest(mClientId, mCasSystemId);
-            if (!mTunerResourceManager.requestCasSession(casSessionRequest, sessionResourceId)) {
-                throw new MediaCasException.ResourceBusyException(
+            if (!mTunerResourceManager
+                    .requestCasSession(casSessionRequest, sessionResourceHandle)) {
+                throw new MediaCasException.InsufficientResourceException(
                     "insufficient resource to Open Session");
             }
         }
-        return  sessionResourceId[0];
+        return  sessionResourceHandle[0];
     }
 
     private void addSessionToResourceMap(Session session, int sessionResourceId) {
@@ -905,6 +906,10 @@
      * Open a session to descramble one or more streams scrambled by the
      * conditional access system.
      *
+     * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+     * to get cas session resource if cas session resources is limited. If the client can't get the
+     * resource, this call returns {@link MediaCasException.InsufficientResourceException }.
+     *
      * @return session the newly opened session.
      *
      * @throws IllegalStateException if the MediaCas instance is not valid.
@@ -930,6 +935,10 @@
      * Open a session with usage and scrambling information, so that descrambler can be configured
      * to descramble one or more streams scrambled by the conditional access system.
      *
+     * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+     * to get cas session resource if cas session resources is limited. If the client can't get the
+     * resource, this call returns {@link MediaCasException.InsufficientResourceException}.
+     *
      * @param sessionUsage used for the created session.
      * @param scramblingMode used for the created session.
      *
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index 392e8fe..a5da648 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -20,9 +20,10 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.Message;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
+
 import java.lang.ref.WeakReference;
 
 /**
@@ -158,6 +159,7 @@
     /**
      * Indicates the state of the Visualizer instance
      */
+    @GuardedBy("mStateLock")
     private int mState = STATE_UNINITIALIZED;
     /**
      * Lock to synchronize access to mState
@@ -166,6 +168,7 @@
     /**
      * System wide unique Identifier of the visualizer engine used by this Visualizer instance
      */
+    @GuardedBy("mStateLock")
     @UnsupportedAppUsage
     private int mId;
 
@@ -176,19 +179,24 @@
     /**
      * Handler for events coming from the native code
      */
-    private NativeEventHandler mNativeEventHandler = null;
+    @GuardedBy("mListenerLock")
+    private Handler mNativeEventHandler = null;
     /**
      *  PCM and FFT capture listener registered by client
      */
+    @GuardedBy("mListenerLock")
     private OnDataCaptureListener mCaptureListener = null;
     /**
      *  Server Died listener registered by client
      */
+    @GuardedBy("mListenerLock")
     private OnServerDiedListener mServerDiedListener = null;
 
     // accessed by native methods
-    private long mNativeVisualizer;
-    private long mJniData;
+    private long mNativeVisualizer;  // guarded by a static lock in native code
+    private long mJniData;  // set in native_setup, _release;
+                            // get in native_release, _setEnabled, _setPeriodicCapture
+                            // thus, effectively guarded by mStateLock
 
     //--------------------------------------------------------------------------
     // Constructor, Finalize
@@ -244,7 +252,9 @@
 
     @Override
     protected void finalize() {
-        native_finalize();
+        synchronized (mStateLock) {
+            native_finalize();
+        }
     }
 
     /**
@@ -601,25 +611,28 @@
      */
     public int setDataCaptureListener(OnDataCaptureListener listener,
             int rate, boolean waveform, boolean fft) {
-        synchronized (mListenerLock) {
-            mCaptureListener = listener;
-        }
         if (listener == null) {
             // make sure capture callback is stopped in native code
             waveform = false;
             fft = false;
         }
-        int status = native_setPeriodicCapture(rate, waveform, fft);
+        int status;
+        synchronized (mStateLock) {
+            status = native_setPeriodicCapture(rate, waveform, fft);
+        }
         if (status == SUCCESS) {
-            if ((listener != null) && (mNativeEventHandler == null)) {
-                Looper looper;
-                if ((looper = Looper.myLooper()) != null) {
-                    mNativeEventHandler = new NativeEventHandler(this, looper);
-                } else if ((looper = Looper.getMainLooper()) != null) {
-                    mNativeEventHandler = new NativeEventHandler(this, looper);
-                } else {
-                    mNativeEventHandler = null;
-                    status = ERROR_NO_INIT;
+            synchronized (mListenerLock) {
+                mCaptureListener = listener;
+                if ((listener != null) && (mNativeEventHandler == null)) {
+                    Looper looper;
+                    if ((looper = Looper.myLooper()) != null) {
+                        mNativeEventHandler = new Handler(looper);
+                    } else if ((looper = Looper.getMainLooper()) != null) {
+                        mNativeEventHandler = new Handler(looper);
+                    } else {
+                        mNativeEventHandler = null;
+                        status = ERROR_NO_INIT;
+                    }
                 }
             }
         }
@@ -663,112 +676,61 @@
         return SUCCESS;
     }
 
-    /**
-     * Helper class to handle the forwarding of native events to the appropriate listeners
-     */
-    private class NativeEventHandler extends Handler
-    {
-        private Visualizer mVisualizer;
-
-        public NativeEventHandler(Visualizer v, Looper looper) {
-            super(looper);
-            mVisualizer = v;
-        }
-
-        private void handleCaptureMessage(Message msg) {
-            OnDataCaptureListener l = null;
-            synchronized (mListenerLock) {
-                l = mVisualizer.mCaptureListener;
-            }
-
-            if (l != null) {
-                byte[] data = (byte[])msg.obj;
-                int samplingRate = msg.arg1;
-
-                switch(msg.what) {
-                case NATIVE_EVENT_PCM_CAPTURE:
-                    l.onWaveFormDataCapture(mVisualizer, data, samplingRate);
-                    break;
-                case NATIVE_EVENT_FFT_CAPTURE:
-                    l.onFftDataCapture(mVisualizer, data, samplingRate);
-                    break;
-                default:
-                    Log.e(TAG,"Unknown native event in handleCaptureMessge: "+msg.what);
-                    break;
-                }
-            }
-        }
-
-        private void handleServerDiedMessage(Message msg) {
-            OnServerDiedListener l = null;
-            synchronized (mListenerLock) {
-                l = mVisualizer.mServerDiedListener;
-            }
-
-            if (l != null)
-                l.onServerDied();
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            if (mVisualizer == null) {
-                return;
-            }
-
-            switch(msg.what) {
-            case NATIVE_EVENT_PCM_CAPTURE:
-            case NATIVE_EVENT_FFT_CAPTURE:
-                handleCaptureMessage(msg);
-                break;
-            case NATIVE_EVENT_SERVER_DIED:
-                handleServerDiedMessage(msg);
-                break;
-            default:
-                Log.e(TAG,"Unknown native event: "+msg.what);
-                break;
-            }
-        }
-    }
-
     //---------------------------------------------------------
     // Interface definitions
     //--------------------
 
     private static native final void native_init();
 
+    @GuardedBy("mStateLock")
     private native final int native_setup(Object audioeffect_this,
                                           int audioSession,
                                           int[] id,
                                           String opPackageName);
 
+    @GuardedBy("mStateLock")
     private native final void native_finalize();
 
+    @GuardedBy("mStateLock")
     private native final void native_release();
 
+    @GuardedBy("mStateLock")
     private native final int native_setEnabled(boolean enabled);
 
+    @GuardedBy("mStateLock")
     private native final boolean native_getEnabled();
 
+    @GuardedBy("mStateLock")
     private native final int native_setCaptureSize(int size);
 
+    @GuardedBy("mStateLock")
     private native final int native_getCaptureSize();
 
+    @GuardedBy("mStateLock")
     private native final int native_setScalingMode(int mode);
 
+    @GuardedBy("mStateLock")
     private native final int native_getScalingMode();
 
+    @GuardedBy("mStateLock")
     private native final int native_setMeasurementMode(int mode);
 
+    @GuardedBy("mStateLock")
     private native final int native_getMeasurementMode();
 
+    @GuardedBy("mStateLock")
     private native final int native_getSamplingRate();
 
+    @GuardedBy("mStateLock")
     private native final int native_getWaveForm(byte[] waveform);
 
+    @GuardedBy("mStateLock")
     private native final int native_getFft(byte[] fft);
 
+    @GuardedBy("mStateLock")
     private native final int native_getPeakRms(MeasurementPeakRms measurement);
 
+    @GuardedBy("mStateLock")
     private native final int native_setPeriodicCapture(int rate, boolean waveForm, boolean fft);
 
     //---------------------------------------------------------
@@ -776,17 +738,47 @@
     //--------------------
     @SuppressWarnings("unused")
     private static void postEventFromNative(Object effect_ref,
-            int what, int arg1, int arg2, Object obj) {
-        Visualizer visu = (Visualizer)((WeakReference)effect_ref).get();
-        if (visu == null) {
-            return;
-        }
+            int what, int samplingRate, byte[] data) {
+        final Visualizer visualizer = (Visualizer) ((WeakReference) effect_ref).get();
+        if (visualizer == null) return;
 
-        if (visu.mNativeEventHandler != null) {
-            Message m = visu.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj);
-            visu.mNativeEventHandler.sendMessage(m);
+        final Handler handler;
+        synchronized (visualizer.mListenerLock) {
+            handler = visualizer.mNativeEventHandler;
         }
+        if (handler == null) return;
 
+        switch (what) {
+            case NATIVE_EVENT_PCM_CAPTURE:
+            case NATIVE_EVENT_FFT_CAPTURE:
+                handler.post(() -> {
+                    final OnDataCaptureListener l;
+                    synchronized (visualizer.mListenerLock) {
+                        l = visualizer.mCaptureListener;
+                    }
+                    if (l != null) {
+                        if (what == NATIVE_EVENT_PCM_CAPTURE) {
+                            l.onWaveFormDataCapture(visualizer, data, samplingRate);
+                        } else { // what == NATIVE_EVENT_FFT_CAPTURE
+                            l.onFftDataCapture(visualizer, data, samplingRate);
+                        }
+                    }
+                });
+                break;
+            case NATIVE_EVENT_SERVER_DIED:
+                handler.post(() -> {
+                    final OnServerDiedListener l;
+                    synchronized (visualizer.mListenerLock) {
+                        l = visualizer.mServerDiedListener;
+                    }
+                    if (l != null) {
+                        l.onServerDied();
+                    }
+                });
+                break;
+            default:
+                Log.e(TAG, "Unknown native event in postEventFromNative: " + what);
+                break;
+        }
     }
 }
-
diff --git a/media/java/android/media/tv/OWNERS b/media/java/android/media/tv/OWNERS
index 64c0bb5..a891154 100644
--- a/media/java/android/media/tv/OWNERS
+++ b/media/java/android/media/tv/OWNERS
@@ -3,3 +3,7 @@
 shubang@google.com
 quxiangfang@google.com
 
+# For android remote service
+per-file ITvRemoteServiceInput.aidl = file:/media/lib/tvremote/OWNERS
+per-file ITvRemoteProvider.aidl = file:/media/lib/tvremote/OWNERS
+
diff --git a/media/java/android/media/tv/tuner/Descrambler.java b/media/java/android/media/tv/tuner/Descrambler.java
index 40add56..975604c 100644
--- a/media/java/android/media/tv/tuner/Descrambler.java
+++ b/media/java/android/media/tv/tuner/Descrambler.java
@@ -20,7 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
 import android.media.tv.tuner.filter.Filter;
 
 import java.lang.annotation.Retention;
diff --git a/media/java/android/media/tv/tuner/Lnb.java b/media/java/android/media/tv/tuner/Lnb.java
index ea06632..525ee4d 100644
--- a/media/java/android/media/tv/tuner/Lnb.java
+++ b/media/java/android/media/tv/tuner/Lnb.java
@@ -23,7 +23,7 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 08a33f1..d24d752 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -26,7 +26,6 @@
 import android.content.Context;
 import android.hardware.tv.tuner.V1_0.Constants;
 import android.media.tv.TvInputService;
-import android.media.tv.tuner.TunerConstants.Result;
 import android.media.tv.tuner.dvr.DvrPlayback;
 import android.media.tv.tuner.dvr.DvrRecorder;
 import android.media.tv.tuner.dvr.OnPlaybackStatusChangedListener;
@@ -44,12 +43,14 @@
 import android.media.tv.tuner.frontend.OnTuneEventListener;
 import android.media.tv.tuner.frontend.ScanCallback;
 import android.media.tv.tunerresourcemanager.ResourceClientProfile;
+import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
 import android.media.tv.tunerresourcemanager.TunerLnbRequest;
 import android.media.tv.tunerresourcemanager.TunerResourceManager;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.Looper;
 import android.os.Message;
+import android.util.Log;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -68,6 +69,96 @@
  */
 @SystemApi
 public class Tuner implements AutoCloseable  {
+    /**
+     * Invalid TS packet ID.
+     */
+    public static final int INVALID_TS_PID = Constants.Constant.INVALID_TS_PID;
+    /**
+     * Invalid stream ID.
+     */
+    public static final int INVALID_STREAM_ID = Constants.Constant.INVALID_STREAM_ID;
+    /**
+     * Invalid filter ID.
+     */
+    public static final int INVALID_FILTER_ID = Constants.Constant.INVALID_FILTER_ID;
+    /**
+     * Invalid AV Sync ID.
+     */
+    public static final int INVALID_AV_SYNC_ID = Constants.Constant.INVALID_AV_SYNC_ID;
+    /**
+     * Invalid timestamp.
+     *
+     * <p>Returned by {@link android.media.tv.tuner.filter.TimeFilter#getSourceTime()},
+     * {@link android.media.tv.tuner.filter.TimeFilter#getTimeStamp()}, or
+     * {@link Tuner#getAvSyncTime(int)} when the requested timestamp is not available.
+     *
+     * @see android.media.tv.tuner.filter.TimeFilter#getSourceTime()
+     * @see android.media.tv.tuner.filter.TimeFilter#getTimeStamp()
+     * @see Tuner#getAvSyncTime(int)
+     */
+    public static final long INVALID_TIMESTAMP = -1L;
+
+
+    /** @hide */
+    @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScanType {}
+    /**
+     * Scan type undefined.
+     */
+    public static final int SCAN_TYPE_UNDEFINED = Constants.FrontendScanType.SCAN_UNDEFINED;
+    /**
+     * Scan type auto.
+     *
+     * <p> Tuner will send {@link android.media.tv.tuner.frontend.ScanCallback#onLocked}
+     */
+    public static final int SCAN_TYPE_AUTO = Constants.FrontendScanType.SCAN_AUTO;
+    /**
+     * Blind scan.
+     *
+     * <p>Frequency range is not specified. The {@link android.media.tv.tuner.Tuner} will scan an
+     * implementation specific range.
+     */
+    public static final int SCAN_TYPE_BLIND = Constants.FrontendScanType.SCAN_BLIND;
+
+
+    /** @hide */
+    @IntDef({RESULT_SUCCESS, RESULT_UNAVAILABLE, RESULT_NOT_INITIALIZED, RESULT_INVALID_STATE,
+            RESULT_INVALID_ARGUMENT, RESULT_OUT_OF_MEMORY, RESULT_UNKNOWN_ERROR})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Result {}
+
+    /**
+     * Operation succeeded.
+     */
+    public static final int RESULT_SUCCESS = Constants.Result.SUCCESS;
+    /**
+     * Operation failed because the corresponding resources are not available.
+     */
+    public static final int RESULT_UNAVAILABLE = Constants.Result.UNAVAILABLE;
+    /**
+     * Operation failed because the corresponding resources are not initialized.
+     */
+    public static final int RESULT_NOT_INITIALIZED = Constants.Result.NOT_INITIALIZED;
+    /**
+     * Operation failed because it's not in a valid state.
+     */
+    public static final int RESULT_INVALID_STATE = Constants.Result.INVALID_STATE;
+    /**
+     * Operation failed because there are invalid arguments.
+     */
+    public static final int RESULT_INVALID_ARGUMENT = Constants.Result.INVALID_ARGUMENT;
+    /**
+     * Memory allocation failed.
+     */
+    public static final int RESULT_OUT_OF_MEMORY = Constants.Result.OUT_OF_MEMORY;
+    /**
+     * Operation failed due to unknown errors.
+     */
+    public static final int RESULT_UNKNOWN_ERROR = Constants.Result.UNKNOWN_ERROR;
+
+
+
     private static final String TAG = "MediaTvTuner";
     private static final boolean DEBUG = false;
 
@@ -93,23 +184,27 @@
     public static final int DVR_TYPE_PLAYBACK = Constants.DvrType.PLAYBACK;
 
     static {
-        System.loadLibrary("media_tv_tuner");
-        nativeInit();
+        try {
+            System.loadLibrary("media_tv_tuner");
+            nativeInit();
+        } catch (UnsatisfiedLinkError e) {
+            Log.d(TAG, "tuner JNI library not found!");
+        }
     }
 
     private final Context mContext;
     private final TunerResourceManager mTunerResourceManager;
     private final int mClientId;
 
-    private List<Integer> mFrontendIds;
     private Frontend mFrontend;
     private EventHandler mHandler;
     @Nullable
     private FrontendInfo mFrontendInfo;
+    private Integer mFrontendHandle;
+    private int mFrontendType = FrontendSettings.TYPE_UNDEFINED;
 
-    private List<Integer> mLnbIds;
     private Lnb mLnb;
-    private Integer mLnbId;
+    private Integer mLnbHandle;
     @Nullable
     private OnTuneEventListener mOnTuneEventListener;
     @Nullable
@@ -233,7 +328,7 @@
     /**
      * Native method to open frontend of the given ID.
      */
-    private native Frontend nativeOpenFrontendById(int id);
+    private native Frontend nativeOpenFrontendByHandle(int handle);
     private native int nativeTune(int type, FrontendSettings settings);
     private native int nativeStopTune();
     private native int nativeScan(int settingsType, FrontendSettings settings, int scanType);
@@ -250,7 +345,7 @@
     private native TimeFilter nativeOpenTimeFilter();
 
     private native List<Integer> nativeGetLnbIds();
-    private native Lnb nativeOpenLnbById(int id);
+    private native Lnb nativeOpenLnbByHandle(int handle);
     private native Lnb nativeOpenLnbByName(String name);
 
     private native Descrambler nativeOpenDescrambler();
@@ -359,6 +454,10 @@
     /**
      * Tunes the frontend to using the settings given.
      *
+     * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+     * to get frontend resource. If the client can't get the resource, this call returns {@link
+     * Result#RESULT_UNAVAILABLE}.
+     *
      * <p>
      * This locks the frontend to a frequency by providing signal
      * delivery information. If previous tuning isn't completed, this stop the previous tuning, and
@@ -378,7 +477,8 @@
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @Result
     public int tune(@NonNull FrontendSettings settings) {
-        TunerUtils.checkTunerPermission(mContext);
+        mFrontendType = settings.getType();
+        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
         mFrontendInfo = null;
         return nativeTune(settings.getType(), settings);
     }
@@ -411,14 +511,15 @@
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     @Result
-    public int scan(@NonNull FrontendSettings settings, @TunerConstants.ScanType int scanType,
+    public int scan(@NonNull FrontendSettings settings, @ScanType int scanType,
             @NonNull @CallbackExecutor Executor executor, @NonNull ScanCallback scanCallback) {
-        TunerUtils.checkTunerPermission(mContext);
         if (mScanCallback != null || mScanCallbackExecutor != null) {
             throw new IllegalStateException(
                     "Scan already in progress.  stopScan must be called before a new scan can be "
                             + "started.");
         }
+        mFrontendType = settings.getType();
+        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
         mScanCallback = scanCallback;
         mScanCallbackExecutor = executor;
         mFrontendInfo = null;
@@ -446,6 +547,16 @@
         return retVal;
     }
 
+    private boolean requestFrontend() {
+        int[] feId = new int[1];
+        TunerFrontendRequest request = new TunerFrontendRequest(mClientId, mFrontendType);
+        boolean granted = mTunerResourceManager.requestFrontend(request, feId);
+        if (granted) {
+            mFrontendHandle = feId[0];
+        }
+        return granted;
+    }
+
     /**
      * Sets Low-Noise Block downconverter (LNB) for satellite frontend.
      *
@@ -498,7 +609,7 @@
     public int getAvSyncHwId(@NonNull Filter filter) {
         TunerUtils.checkTunerPermission(mContext);
         Integer id = nativeGetAvSyncHwId(filter);
-        return id == null ? TunerConstants.INVALID_AV_SYNC_ID : id;
+        return id == null ? INVALID_AV_SYNC_ID : id;
     }
 
     /**
@@ -514,7 +625,7 @@
     public long getAvSyncTime(int avSyncHwId) {
         TunerUtils.checkTunerPermission(mContext);
         Long time = nativeGetAvSyncTime(avSyncHwId);
-        return time == null ? TunerConstants.TIMESTAMP_UNAVAILABLE : time;
+        return time == null ? INVALID_TIMESTAMP : time;
     }
 
     /**
@@ -579,22 +690,6 @@
         return nativeGetDemuxCapabilities();
     }
 
-    private List<Integer> getFrontendIds() {
-        mFrontendIds = nativeGetFrontendIds();
-        return mFrontendIds;
-    }
-
-    private Frontend openFrontendById(int id) {
-        if (mFrontendIds == null) {
-            mFrontendIds = getFrontendIds();
-        }
-        if (!mFrontendIds.contains(id)) {
-            return null;
-        }
-        mFrontend = nativeOpenFrontendById(id);
-        return mFrontend;
-    }
-
     private void onFrontendEvent(int eventType) {
         if (mOnTunerEventExecutor != null && mOnTuneEventListener != null) {
             mOnTunerEventExecutor.execute(() -> mOnTuneEventListener.onTuneEvent(eventType));
@@ -731,11 +826,9 @@
     public Lnb openLnb(@CallbackExecutor @NonNull Executor executor, @NonNull LnbCallback cb) {
         Objects.requireNonNull(executor, "executor must not be null");
         Objects.requireNonNull(cb, "LnbCallback must not be null");
-        TunerUtils.checkTunerPermission(mContext);
-        if (mLnbId == null && !requestLnb()) {
-            return null;
-        }
-        return nativeOpenLnbById(mLnbId);
+        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB);
+        // TODO: update JNI code for LNB handle,
+        return nativeOpenLnbByHandle(mLnbHandle);
     }
 
     /**
@@ -763,7 +856,7 @@
         TunerLnbRequest request = new TunerLnbRequest(mClientId);
         boolean granted = mTunerResourceManager.requestLnb(request, lnbId);
         if (granted) {
-            mLnbId = lnbId[0];
+            mLnbHandle = lnbId[0];
         }
         return granted;
     }
@@ -778,22 +871,6 @@
         return nativeOpenTimeFilter();
     }
 
-    private List<Integer> getLnbIds() {
-        mLnbIds = nativeGetLnbIds();
-        return mLnbIds;
-    }
-
-    private Lnb openLnbById(int id) {
-        if (mLnbIds == null) {
-            mLnbIds = getLnbIds();
-        }
-        if (!mLnbIds.contains(id)) {
-            return null;
-        }
-        mLnb = nativeOpenLnbById(id);
-        return mLnb;
-    }
-
     private void onLnbEvent(int eventType) {
         if (mHandler != null) {
             mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_LNB_EVENT, eventType, 0));
@@ -857,4 +934,23 @@
         DvrPlayback dvr = nativeOpenDvrPlayback(bufferSize);
         return dvr;
     }
+
+    private boolean checkResource(int resourceType)  {
+        // TODO: demux and descrambler
+        switch (resourceType) {
+            case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND: {
+                if (mFrontendHandle == null && !requestFrontend()) {
+                    return false;
+                }
+                break;
+            }
+            case TunerResourceManager.TUNER_RESOURCE_TYPE_LNB: {
+                if (mLnbHandle == null && !requestLnb()) {
+                    return false;
+                }
+                break;
+            }
+        }
+        return true;
+    }
 }
diff --git a/media/java/android/media/tv/tuner/TunerConstants.java b/media/java/android/media/tv/tuner/TunerConstants.java
deleted file mode 100644
index 6d89962..0000000
--- a/media/java/android/media/tv/tuner/TunerConstants.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 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.media.tv.tuner;
-
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.hardware.tv.tuner.V1_0.Constants;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Constants for tuner framework.
- *
- * @hide
- */
-@SystemApi
-public final class TunerConstants {
-    /**
-     * Invalid TS packet ID.
-     */
-    public static final int INVALID_TS_PID = Constants.Constant.INVALID_TS_PID;
-    /**
-     * Invalid stream ID.
-     */
-    public static final int INVALID_STREAM_ID = Constants.Constant.INVALID_STREAM_ID;
-    /**
-     * Invalid filter ID.
-     */
-    public static final int INVALID_FILTER_ID = Constants.Constant.INVALID_FILTER_ID;
-    /**
-     * Invalid AV Sync ID.
-     */
-    public static final int INVALID_AV_SYNC_ID = Constants.Constant.INVALID_AV_SYNC_ID;
-    /**
-     * Timestamp is unavailable.
-     *
-     * <p>Returned by {@link android.media.tv.tuner.filter.TimeFilter#getSourceTime()},
-     * {@link android.media.tv.tuner.filter.TimeFilter#getTimeStamp()}, or
-     * {@link Tuner#getAvSyncTime(int)} when the requested timestamp is not available.
-     *
-     * @see android.media.tv.tuner.filter.TimeFilter#getSourceTime()
-     * @see android.media.tv.tuner.filter.TimeFilter#getTimeStamp()
-     * @see Tuner#getAvSyncTime(int)
-     * @hide
-     */
-    public static final long TIMESTAMP_UNAVAILABLE = -1L;
-
-    /** @hide */
-    @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ScanType {}
-    /**
-     * Scan type undefined.
-     */
-    public static final int SCAN_TYPE_UNDEFINED = Constants.FrontendScanType.SCAN_UNDEFINED;
-    /**
-     * Scan type auto.
-     *
-     * <p> Tuner will send {@link android.media.tv.tuner.frontend.ScanCallback#onLocked}
-     */
-    public static final int SCAN_TYPE_AUTO = Constants.FrontendScanType.SCAN_AUTO;
-    /**
-     * Blind scan.
-     *
-     * <p>Frequency range is not specified. The {@link android.media.tv.tuner.Tuner} will scan an
-     * implementation specific range.
-     */
-    public static final int SCAN_TYPE_BLIND = Constants.FrontendScanType.SCAN_BLIND;
-
-    /** @hide */
-    @IntDef({RESULT_SUCCESS, RESULT_UNAVAILABLE, RESULT_NOT_INITIALIZED, RESULT_INVALID_STATE,
-            RESULT_INVALID_ARGUMENT, RESULT_OUT_OF_MEMORY, RESULT_UNKNOWN_ERROR})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Result {}
-
-    /**
-     * Operation succeeded.
-     */
-    public static final int RESULT_SUCCESS = Constants.Result.SUCCESS;
-    /**
-     * Operation failed because the corresponding resources are not available.
-     */
-    public static final int RESULT_UNAVAILABLE = Constants.Result.UNAVAILABLE;
-    /**
-     * Operation failed because the corresponding resources are not initialized.
-     */
-    public static final int RESULT_NOT_INITIALIZED = Constants.Result.NOT_INITIALIZED;
-    /**
-     * Operation failed because it's not in a valid state.
-     */
-    public static final int RESULT_INVALID_STATE = Constants.Result.INVALID_STATE;
-    /**
-     * Operation failed because there are invalid arguments.
-     */
-    public static final int RESULT_INVALID_ARGUMENT = Constants.Result.INVALID_ARGUMENT;
-    /**
-     * Memory allocation failed.
-     */
-    public static final int RESULT_OUT_OF_MEMORY = Constants.Result.OUT_OF_MEMORY;
-    /**
-     * Operation failed due to unknown errors.
-     */
-    public static final int RESULT_UNKNOWN_ERROR = Constants.Result.UNKNOWN_ERROR;
-
-    private TunerConstants() {
-    }
-}
diff --git a/media/java/android/media/tv/tuner/TunerUtils.java b/media/java/android/media/tv/tuner/TunerUtils.java
index 2258ee5..c3be12a 100644
--- a/media/java/android/media/tv/tuner/TunerUtils.java
+++ b/media/java/android/media/tv/tuner/TunerUtils.java
@@ -171,22 +171,22 @@
      */
     @Nullable
     public static void throwExceptionForResult(
-            @TunerConstants.Result int r, @Nullable String msg) {
+            @Tuner.Result int r, @Nullable String msg) {
         if (msg == null) {
             msg = "";
         }
         switch (r) {
-            case TunerConstants.RESULT_INVALID_ARGUMENT:
+            case Tuner.RESULT_INVALID_ARGUMENT:
                 throw new IllegalArgumentException(msg);
-            case TunerConstants.RESULT_INVALID_STATE:
+            case Tuner.RESULT_INVALID_STATE:
                 throw new IllegalStateException(msg);
-            case TunerConstants.RESULT_NOT_INITIALIZED:
+            case Tuner.RESULT_NOT_INITIALIZED:
                 throw new IllegalStateException("Invalid state: not initialized. " + msg);
-            case TunerConstants.RESULT_OUT_OF_MEMORY:
+            case Tuner.RESULT_OUT_OF_MEMORY:
                 throw new OutOfMemoryError(msg);
-            case TunerConstants.RESULT_UNAVAILABLE:
+            case Tuner.RESULT_UNAVAILABLE:
                 throw new IllegalStateException("Invalid state: resource unavailable. " + msg);
-            case TunerConstants.RESULT_UNKNOWN_ERROR:
+            case Tuner.RESULT_UNKNOWN_ERROR:
                 throw new RuntimeException("Unknown error" + msg);
             default:
                 break;
diff --git a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
index 37a016e..0d10d94 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
@@ -21,7 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
 import android.media.tv.tuner.filter.Filter;
 import android.os.ParcelFileDescriptor;
 
diff --git a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
index d06356c..dbda7bb 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
@@ -19,7 +19,7 @@
 import android.annotation.BytesLong;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
 import android.media.tv.tuner.filter.Filter;
 import android.os.ParcelFileDescriptor;
 
diff --git a/media/java/android/media/tv/tuner/filter/AlpFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/AlpFilterConfiguration.java
index 8a29442..e40b080 100644
--- a/media/java/android/media/tv/tuner/filter/AlpFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/AlpFilterConfiguration.java
@@ -125,8 +125,8 @@
      * Builder for {@link AlpFilterConfiguration}.
      */
     public static final class Builder {
-        private int mPacketType;
-        private int mLengthType;
+        private int mPacketType = PACKET_TYPE_IPV4;
+        private int mLengthType = LENGTH_TYPE_UNDEFINED;
         private Settings mSettings;
 
         private Builder() {
@@ -136,6 +136,7 @@
          * Sets packet type.
          *
          * <p>The meaning of each packet type value is shown in ATSC A/330:2019 table 5.2.
+         * <p>Default value is {@link #PACKET_TYPE_IPV4}.
          */
         @NonNull
         public Builder setPacketType(int packetType) {
@@ -144,6 +145,8 @@
         }
         /**
          * Sets length type.
+         *
+         * <p>Default value is {@link #LENGTH_TYPE_UNDEFINED}.
          */
         @NonNull
         public Builder setLengthType(@LengthType int lengthType) {
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index 4777fe8..8dc0622 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -22,7 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
 import android.media.tv.tuner.TunerUtils;
 
 import java.lang.annotation.Retention;
diff --git a/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java
index 04f3410..de75a4f 100644
--- a/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java
@@ -106,11 +106,11 @@
      * Builder for {@link IpFilterConfiguration}.
      */
     public static final class Builder {
-        private byte[] mSrcIpAddress;
-        private byte[] mDstIpAddress;
-        private int mSrcPort;
-        private int mDstPort;
-        private boolean mPassthrough;
+        private byte[] mSrcIpAddress = {0, 0, 0, 0};
+        private byte[] mDstIpAddress = {0, 0, 0, 0};;
+        private int mSrcPort = 0;
+        private int mDstPort = 0;
+        private boolean mPassthrough = false;
         private Settings mSettings;
 
         private Builder() {
@@ -118,6 +118,8 @@
 
         /**
          * Sets source IP address.
+         *
+         * <p>Default value is 0.0.0.0, an invalid IP address.
          */
         @NonNull
         public Builder setSrcIpAddress(@NonNull byte[] srcIpAddress) {
@@ -126,6 +128,8 @@
         }
         /**
          * Sets destination IP address.
+         *
+         * <p>Default value is 0.0.0.0, an invalid IP address.
          */
         @NonNull
         public Builder setDstIpAddress(@NonNull byte[] dstIpAddress) {
@@ -134,6 +138,8 @@
         }
         /**
          * Sets source port.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         public Builder setSrcPort(int srcPort) {
@@ -142,6 +148,8 @@
         }
         /**
          * Sets destination port.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         public Builder setDstPort(int dstPort) {
@@ -150,6 +158,8 @@
         }
         /**
          * Sets passthrough.
+         *
+         * <p>Default value is {@code false}.
          */
         @NonNull
         public Builder setPassthrough(boolean passthrough) {
diff --git a/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java
index c0453b4..f19edc9 100644
--- a/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java
@@ -21,6 +21,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.content.Context;
+import android.media.tv.tuner.Tuner;
 import android.media.tv.tuner.TunerUtils;
 
 /**
@@ -67,7 +68,7 @@
      * Builder for {@link IpFilterConfiguration}.
      */
     public static final class Builder {
-        private int mMmtpPid;
+        private int mMmtpPid = Tuner.INVALID_TS_PID;
         private Settings mSettings;
 
         private Builder() {
@@ -75,6 +76,8 @@
 
         /**
          * Sets MMTP Packet ID.
+         *
+         * <p>Default value is {@link Tuner#INVALID_TS_PID}.
          */
         @NonNull
         public Builder setMmtpPacketId(int mmtpPid) {
diff --git a/media/java/android/media/tv/tuner/filter/TimeFilter.java b/media/java/android/media/tv/tuner/filter/TimeFilter.java
index 371ccc4..be0a055 100644
--- a/media/java/android/media/tv/tuner/filter/TimeFilter.java
+++ b/media/java/android/media/tv/tuner/filter/TimeFilter.java
@@ -17,8 +17,8 @@
 package android.media.tv.tuner.filter;
 
 import android.annotation.SystemApi;
-import android.media.tv.tuner.TunerConstants;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner;
+import android.media.tv.tuner.Tuner.Result;
 import android.media.tv.tuner.TunerUtils;
 
 /**
@@ -35,17 +35,6 @@
 @SystemApi
 public class TimeFilter implements AutoCloseable {
 
-    /**
-     * Timestamp is unavailable.
-     *
-     * <p>Returned by {@link #getSourceTime()} or {@link #getTimeStamp()} when the requested
-     * timestamp is not available.
-     *
-     * @see #getSourceTime()
-     * @see #getTimeStamp()
-     */
-    public static final long TIMESTAMP_UNAVAILABLE = -1L;
-
 
     private native int nativeSetTimestamp(long timestamp);
     private native int nativeClearTimestamp();
@@ -108,12 +97,12 @@
      *
      * @return current timestamp in the time filter. It's based on the 90KHz counter, and it's
      * the same format as PTS (Presentation Time Stamp) defined in ISO/IEC 13818-1:2019. The
-     * timestamps may or may not be related to PTS or DTS. Returns {@link #TIMESTAMP_UNAVAILABLE}
-     * if the timestamp is never set.
+     * timestamps may or may not be related to PTS or DTS. Returns
+     * {@link Tuner#INVALID_TIMESTAMP} if the timestamp is never set.
      */
     public long getTimeStamp() {
         if (!mEnable) {
-            return TIMESTAMP_UNAVAILABLE;
+            return Tuner.INVALID_TIMESTAMP;
         }
         return nativeGetTimestamp();
     }
@@ -126,11 +115,11 @@
      * @return first timestamp of incoming data stream. It's based on the 90KHz counter, and
      * it's the same format as PTS (Presentation Time Stamp) defined in ISO/IEC 13818-1:2019.
      * The timestamps may or may not be related to PTS or DTS. Returns
-     * {@link #TIMESTAMP_UNAVAILABLE} if the timestamp is not available.
+     * {@link Tuner#INVALID_TIMESTAMP} if the timestamp is not available.
      */
     public long getSourceTime() {
         if (!mEnable) {
-            return TIMESTAMP_UNAVAILABLE;
+            return Tuner.INVALID_TIMESTAMP;
         }
         return nativeGetSourceTime();
     }
@@ -144,7 +133,7 @@
     @Override
     public void close() {
         int res = nativeClose();
-        if (res != TunerConstants.RESULT_SUCCESS) {
+        if (res != Tuner.RESULT_SUCCESS) {
             TunerUtils.throwExceptionForResult(res, "Failed to close time filter.");
         }
     }
diff --git a/media/java/android/media/tv/tuner/filter/TlvFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/TlvFilterConfiguration.java
index c5191bf..eb1de52 100644
--- a/media/java/android/media/tv/tuner/filter/TlvFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/TlvFilterConfiguration.java
@@ -110,9 +110,9 @@
      * Builder for {@link TlvFilterConfiguration}.
      */
     public static final class Builder {
-        private int mPacketType;
-        private boolean mIsCompressedIpPacket;
-        private boolean mPassthrough;
+        private int mPacketType = PACKET_TYPE_NULL;
+        private boolean mIsCompressedIpPacket = false;
+        private boolean mPassthrough = false;
         private Settings mSettings;
 
         private Builder() {
@@ -122,6 +122,7 @@
          * Sets packet type.
          *
          * <p>The description of each packet type value is shown in ITU-R BT.1869 table 2.
+         * <p>Default value is {@link #PACKET_TYPE_NULL}.
          */
         @NonNull
         public Builder setPacketType(int packetType) {
@@ -130,6 +131,8 @@
         }
         /**
          * Sets whether the data is compressed IP packet.
+         *
+         * <p>Default value is {@code false}.
          */
         @NonNull
         public Builder setCompressedIpPacket(boolean isCompressedIpPacket) {
@@ -138,6 +141,8 @@
         }
         /**
          * Sets whether it's passthrough.
+         *
+         * <p>Default value is {@code false}.
          */
         @NonNull
         public Builder setPassthrough(boolean passthrough) {
diff --git a/media/java/android/media/tv/tuner/filter/TsFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/TsFilterConfiguration.java
index a7140eb..0579269 100644
--- a/media/java/android/media/tv/tuner/filter/TsFilterConfiguration.java
+++ b/media/java/android/media/tv/tuner/filter/TsFilterConfiguration.java
@@ -65,7 +65,7 @@
      * Builder for {@link TsFilterConfiguration}.
      */
     public static final class Builder {
-        private int mTpid;
+        private int mTpid = 0;
         private Settings mSettings;
 
         private Builder() {
@@ -74,6 +74,8 @@
         /**
          * Sets Tag Protocol ID.
          *
+         * <p>Default value is 0.
+         *
          * @param tpid the Tag Protocol ID.
          */
         @NonNull
diff --git a/media/java/android/media/tv/tuner/frontend/AnalogFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/AnalogFrontendSettings.java
index 382cc85..e68585d 100644
--- a/media/java/android/media/tv/tuner/frontend/AnalogFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/AnalogFrontendSettings.java
@@ -215,14 +215,16 @@
      * Builder for {@link AnalogFrontendSettings}.
      */
     public static class Builder {
-        private int mFrequency;
-        private int mSignalType;
-        private int mSifStandard;
+        private int mFrequency = 0;
+        private int mSignalType = SIGNAL_TYPE_UNDEFINED;
+        private int mSifStandard = SIF_UNDEFINED;
 
         private Builder() {}
 
         /**
          * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         @IntRange(from = 1)
@@ -233,6 +235,8 @@
 
         /**
          * Sets analog signal type.
+         *
+         * <p>Default value is {@link #SIGNAL_TYPE_UNDEFINED}.
          */
         @NonNull
         public Builder setSignalType(@SignalType int signalType) {
@@ -242,6 +246,8 @@
 
         /**
          * Sets Standard Interchange Format (SIF).
+         *
+         * <p>Default value is {@link #SIF_UNDEFINED}.
          */
         @NonNull
         public Builder setSifStandard(@SifStandard int sifStandard) {
diff --git a/media/java/android/media/tv/tuner/frontend/Atsc3FrontendSettings.java b/media/java/android/media/tv/tuner/frontend/Atsc3FrontendSettings.java
index 1394716..bf4f3b2 100644
--- a/media/java/android/media/tv/tuner/frontend/Atsc3FrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/Atsc3FrontendSettings.java
@@ -327,16 +327,18 @@
      * Builder for {@link Atsc3FrontendSettings}.
      */
     public static class Builder {
-        private int mFrequency;
-        private int mBandwidth;
-        private int mDemodOutputFormat;
-        private Atsc3PlpSettings[] mPlpSettings;
+        private int mFrequency = 0;
+        private int mBandwidth = BANDWIDTH_UNDEFINED;
+        private int mDemodOutputFormat = DEMOD_OUTPUT_FORMAT_UNDEFINED;
+        private Atsc3PlpSettings[] mPlpSettings = {};
 
         private Builder() {
         }
 
         /**
          * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         @IntRange(from = 1)
@@ -347,6 +349,8 @@
 
         /**
          * Sets bandwidth.
+         *
+         * <p>Default value is {@link #BANDWIDTH_UNDEFINED}.
          */
         @NonNull
         public Builder setBandwidth(int bandwidth) {
@@ -355,6 +359,8 @@
         }
         /**
          * Sets Demod Output Format.
+         *
+         * <p>Default value is {@link #DEMOD_OUTPUT_FORMAT_UNDEFINED}.
          */
         @NonNull
         public Builder setDemodOutputFormat(@DemodOutputFormat int demodOutputFormat) {
@@ -363,6 +369,8 @@
         }
         /**
          * Sets PLP Settings.
+         *
+         * <p>Default value an empty array.
          */
         @NonNull
         public Builder setPlpSettings(@NonNull Atsc3PlpSettings[] plpSettings) {
diff --git a/media/java/android/media/tv/tuner/frontend/AtscFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/AtscFrontendSettings.java
index 53352f0..0674f6e 100644
--- a/media/java/android/media/tv/tuner/frontend/AtscFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/AtscFrontendSettings.java
@@ -93,14 +93,16 @@
      * Builder for {@link AtscFrontendSettings}.
      */
     public static class Builder {
-        private int mFrequency;
-        private int mModulation;
+        private int mFrequency = 0;
+        private int mModulation = MODULATION_UNDEFINED;
 
         private Builder() {
         }
 
         /**
          * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         @IntRange(from = 1)
@@ -111,6 +113,8 @@
 
         /**
          * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
          */
         @NonNull
         public Builder setModulation(@Modulation int modulation) {
diff --git a/media/java/android/media/tv/tuner/frontend/DvbcFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/DvbcFrontendSettings.java
index 6d58570..121de5d 100644
--- a/media/java/android/media/tv/tuner/frontend/DvbcFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/DvbcFrontendSettings.java
@@ -220,19 +220,21 @@
      * Builder for {@link DvbcFrontendSettings}.
      */
     public static class Builder {
-        private int mFrequency;
-        private int mModulation;
-        private long mInnerFec;
-        private int mSymbolRate;
-        private int mOuterFec;
-        private int mAnnex;
-        private int mSpectralInversion;
+        private int mFrequency = 0;
+        private int mModulation = MODULATION_UNDEFINED;
+        private long mInnerFec = FEC_UNDEFINED;
+        private int mSymbolRate = 0;
+        private int mOuterFec = OUTER_FEC_UNDEFINED;
+        private int mAnnex = ANNEX_UNDEFINED;
+        private int mSpectralInversion = SPECTRAL_INVERSION_UNDEFINED;
 
         private Builder() {
         }
 
         /**
          * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         @IntRange(from = 1)
@@ -243,6 +245,8 @@
 
         /**
          * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
          */
         @NonNull
         public Builder setModulation(@Modulation int modulation) {
@@ -251,6 +255,8 @@
         }
         /**
          * Sets Inner Forward Error Correction.
+         *
+         * <p>Default value is {@link #FEC_UNDEFINED}.
          */
         @NonNull
         public Builder setInnerFec(@InnerFec long fec) {
@@ -259,6 +265,8 @@
         }
         /**
          * Sets Symbol Rate in symbols per second.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         public Builder setSymbolRate(int symbolRate) {
@@ -267,6 +275,8 @@
         }
         /**
          * Sets Outer Forward Error Correction.
+         *
+         * <p>Default value is {@link #OUTER_FEC_UNDEFINED}.
          */
         @NonNull
         public Builder setOuterFec(@OuterFec int outerFec) {
@@ -275,6 +285,8 @@
         }
         /**
          * Sets Annex.
+         *
+         * <p>Default value is {@link #ANNEX_UNDEFINED}.
          */
         @NonNull
         public Builder setAnnex(@Annex int annex) {
@@ -283,6 +295,8 @@
         }
         /**
          * Sets Spectral Inversion.
+         *
+         * <p>Default value is {@link #SPECTRAL_INVERSION_UNDEFINED}.
          */
         @NonNull
         public Builder setSpectralInversion(@SpectralInversion int spectralInversion) {
diff --git a/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
index 9c45dd1..afc79ab 100644
--- a/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
@@ -24,6 +24,7 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
 import android.media.tv.tuner.TunerUtils;
 
 import java.lang.annotation.Retention;
@@ -305,21 +306,23 @@
      * Builder for {@link DvbsFrontendSettings}.
      */
     public static class Builder {
-        private int mFrequency;
-        private int mModulation;
-        private DvbsCodeRate mCodeRate;
-        private int mSymbolRate;
-        private int mRolloff;
-        private int mPilot;
-        private int mInputStreamId;
-        private int mStandard;
-        private int mVcmMode;
+        private int mFrequency = 0;
+        private int mModulation = MODULATION_UNDEFINED;
+        private DvbsCodeRate mCodeRate = null;
+        private int mSymbolRate = 0;
+        private int mRolloff = ROLLOFF_UNDEFINED;
+        private int mPilot = PILOT_UNDEFINED;
+        private int mInputStreamId = Tuner.INVALID_STREAM_ID;
+        private int mStandard = STANDARD_AUTO;
+        private int mVcmMode = VCM_MODE_UNDEFINED;
 
         private Builder() {
         }
 
         /**
          * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         @IntRange(from = 1)
@@ -330,6 +333,8 @@
 
         /**
          * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
          */
         @NonNull
         public Builder setModulation(@Modulation int modulation) {
@@ -338,6 +343,8 @@
         }
         /**
          * Sets Code rate.
+         *
+         * <p>Default value is {@code null}.
          */
         @NonNull
         public Builder setCodeRate(@Nullable DvbsCodeRate codeRate) {
@@ -346,6 +353,8 @@
         }
         /**
          * Sets Symbol Rate.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         public Builder setSymbolRate(int symbolRate) {
@@ -354,6 +363,8 @@
         }
         /**
          * Sets Rolloff.
+         *
+         * <p>Default value is {@link #ROLLOFF_UNDEFINED}.
          */
         @NonNull
         public Builder setRolloff(@Rolloff int rolloff) {
@@ -362,6 +373,8 @@
         }
         /**
          * Sets Pilot mode.
+         *
+         * <p>Default value is {@link #PILOT_UNDEFINED}.
          */
         @NonNull
         public Builder setPilot(@Pilot int pilot) {
@@ -370,6 +383,8 @@
         }
         /**
          * Sets Input Stream ID.
+         *
+         * <p>Default value is {@link Tuner#INVALID_STREAM_ID}.
          */
         @NonNull
         public Builder setInputStreamId(int inputStreamId) {
@@ -378,6 +393,8 @@
         }
         /**
          * Sets Standard.
+         *
+         * <p>Default value is {@link #STANDARD_AUTO}.
          */
         @NonNull
         public Builder setStandard(@Standard int standard) {
@@ -386,6 +403,8 @@
         }
         /**
          * Sets VCM mode.
+         *
+         * <p>Default value is {@link #VCM_MODE_UNDEFINED}.
          */
         @NonNull
         public Builder setVcmMode(@VcmMode int vcm) {
diff --git a/media/java/android/media/tv/tuner/frontend/DvbtFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/DvbtFrontendSettings.java
index 4accabb..67a9fdc 100644
--- a/media/java/android/media/tv/tuner/frontend/DvbtFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/DvbtFrontendSettings.java
@@ -508,26 +508,28 @@
      * Builder for {@link DvbtFrontendSettings}.
      */
     public static class Builder {
-        private int mFrequency;
-        private int mTransmissionMode;
-        private int mBandwidth;
-        private int mConstellation;
-        private int mHierarchy;
-        private int mHpCodeRate;
-        private int mLpCodeRate;
-        private int mGuardInterval;
-        private boolean mIsHighPriority;
-        private int mStandard;
-        private boolean mIsMiso;
-        private int mPlpMode;
-        private int mPlpId;
-        private int mPlpGroupId;
+        private int mFrequency = 0;
+        private int mTransmissionMode = TRANSMISSION_MODE_UNDEFINED;
+        private int mBandwidth = BANDWIDTH_UNDEFINED;
+        private int mConstellation = CONSTELLATION_UNDEFINED;
+        private int mHierarchy = HIERARCHY_UNDEFINED;
+        private int mHpCodeRate = CODERATE_UNDEFINED;
+        private int mLpCodeRate = CODERATE_UNDEFINED;
+        private int mGuardInterval = GUARD_INTERVAL_UNDEFINED;
+        private boolean mIsHighPriority = false;
+        private int mStandard = STANDARD_AUTO;
+        private boolean mIsMiso = false;
+        private int mPlpMode = PLP_MODE_UNDEFINED;
+        private int mPlpId = 0;
+        private int mPlpGroupId = 0;
 
         private Builder() {
         }
 
         /**
          * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         @IntRange(from = 1)
@@ -538,6 +540,8 @@
 
         /**
          * Sets Transmission Mode.
+         *
+         * <p>Default value is {@link #TRANSMISSION_MODE_UNDEFINED}.
          */
         @NonNull
         public Builder setTransmissionMode(@TransmissionMode int transmissionMode) {
@@ -546,6 +550,8 @@
         }
         /**
          * Sets Bandwidth.
+         *
+         * <p>Default value is {@link #BANDWIDTH_UNDEFINED}.
          */
         @NonNull
         public Builder setBandwidth(@Bandwidth int bandwidth) {
@@ -554,6 +560,8 @@
         }
         /**
          * Sets Constellation.
+         *
+         * <p>Default value is {@link #CONSTELLATION_UNDEFINED}.
          */
         @NonNull
         public Builder setConstellation(@Constellation int constellation) {
@@ -562,6 +570,8 @@
         }
         /**
          * Sets Hierarchy.
+         *
+         * <p>Default value is {@link #HIERARCHY_UNDEFINED}.
          */
         @NonNull
         public Builder setHierarchy(@Hierarchy int hierarchy) {
@@ -570,6 +580,8 @@
         }
         /**
          * Sets Code Rate for High Priority level.
+         *
+         * <p>Default value is {@link #CODERATE_UNDEFINED}.
          */
         @NonNull
         public Builder setHighPriorityCodeRate(@CodeRate int hpCodeRate) {
@@ -578,6 +590,8 @@
         }
         /**
          * Sets Code Rate for Low Priority level.
+         *
+         * <p>Default value is {@link #CODERATE_UNDEFINED}.
          */
         @NonNull
         public Builder setLowPriorityCodeRate(@CodeRate int lpCodeRate) {
@@ -586,6 +600,8 @@
         }
         /**
          * Sets Guard Interval.
+         *
+         * <p>Default value is {@link #GUARD_INTERVAL_UNDEFINED}.
          */
         @NonNull
         public Builder setGuardInterval(@GuardInterval int guardInterval) {
@@ -594,6 +610,8 @@
         }
         /**
          * Sets whether it's high priority.
+         *
+         * <p>Default value is {@code false}.
          */
         @NonNull
         public Builder setHighPriority(boolean isHighPriority) {
@@ -602,6 +620,8 @@
         }
         /**
          * Sets Standard.
+         *
+         * <p>Default value is {@link #STANDARD_AUTO}.
          */
         @NonNull
         public Builder setStandard(@Standard int standard) {
@@ -610,6 +630,8 @@
         }
         /**
          * Sets whether it's MISO.
+         *
+         * <p>Default value is {@code false}.
          */
         @NonNull
         public Builder setMiso(boolean isMiso) {
@@ -618,6 +640,8 @@
         }
         /**
          * Sets Physical Layer Pipe (PLP) Mode.
+         *
+         * <p>Default value is {@link #PLP_MODE_UNDEFINED}.
          */
         @NonNull
         public Builder setPlpMode(@PlpMode int plpMode) {
@@ -626,6 +650,8 @@
         }
         /**
          * Sets Physical Layer Pipe (PLP) ID.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         public Builder setPlpId(int plpId) {
@@ -634,6 +660,8 @@
         }
         /**
          * Sets Physical Layer Pipe (PLP) group ID.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         public Builder setPlpGroupId(int plpGroupId) {
diff --git a/media/java/android/media/tv/tuner/frontend/Isdbs3FrontendSettings.java b/media/java/android/media/tv/tuner/frontend/Isdbs3FrontendSettings.java
index f385379..e0077ca 100644
--- a/media/java/android/media/tv/tuner/frontend/Isdbs3FrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/Isdbs3FrontendSettings.java
@@ -23,6 +23,7 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
 import android.media.tv.tuner.TunerUtils;
 
 import java.lang.annotation.Retention;
@@ -226,19 +227,21 @@
      * Builder for {@link Isdbs3FrontendSettings}.
      */
     public static class Builder {
-        private int mFrequency;
-        private int mStreamId;
-        private int mStreamIdType;
-        private int mModulation;
-        private int mCodeRate;
-        private int mSymbolRate;
-        private int mRolloff;
+        private int mFrequency = 0;
+        private int mStreamId = Tuner.INVALID_STREAM_ID;
+        private int mStreamIdType = IsdbsFrontendSettings.STREAM_ID_TYPE_ID;
+        private int mModulation = MODULATION_UNDEFINED;
+        private int mCodeRate = CODERATE_UNDEFINED;
+        private int mSymbolRate = 0;
+        private int mRolloff = ROLLOFF_UNDEFINED;
 
         private Builder() {
         }
 
         /**
          * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         @IntRange(from = 1)
@@ -249,6 +252,8 @@
 
         /**
          * Sets Stream ID.
+         *
+         * <p>Default value is {@link Tuner#INVALID_STREAM_ID}.
          */
         @NonNull
         public Builder setStreamId(int streamId) {
@@ -257,6 +262,8 @@
         }
         /**
          * Sets StreamIdType.
+         *
+         * <p>Default value is {@link IsdbsFrontendSettings#STREAM_ID_TYPE_ID}.
          */
         @NonNull
         public Builder setStreamIdType(@IsdbsFrontendSettings.StreamIdType int streamIdType) {
@@ -265,6 +272,8 @@
         }
         /**
          * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
          */
         @NonNull
         public Builder setModulation(@Modulation int modulation) {
@@ -273,6 +282,8 @@
         }
         /**
          * Sets Code rate.
+         *
+         * <p>Default value is {@link #CODERATE_UNDEFINED}.
          */
         @NonNull
         public Builder setCodeRate(@CodeRate int codeRate) {
@@ -281,6 +292,8 @@
         }
         /**
          * Sets Symbol Rate in symbols per second.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         public Builder setSymbolRate(int symbolRate) {
@@ -289,6 +302,8 @@
         }
         /**
          * Sets Roll off type.
+         *
+         * <p>Default value is {@link #ROLLOFF_UNDEFINED}.
          */
         @NonNull
         public Builder setRolloff(@Rolloff int rolloff) {
diff --git a/media/java/android/media/tv/tuner/frontend/IsdbsFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/IsdbsFrontendSettings.java
index 4667b9b..8dc591b 100644
--- a/media/java/android/media/tv/tuner/frontend/IsdbsFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/IsdbsFrontendSettings.java
@@ -23,6 +23,7 @@
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
 import android.media.tv.tuner.TunerUtils;
 
 import java.lang.annotation.Retention;
@@ -210,19 +211,21 @@
      * Builder for {@link IsdbsFrontendSettings}.
      */
     public static class Builder {
-        private int mFrequency;
-        private int mStreamId;
-        private int mStreamIdType;
-        private int mModulation;
-        private int mCodeRate;
-        private int mSymbolRate;
-        private int mRolloff;
+        private int mFrequency = 0;
+        private int mStreamId = Tuner.INVALID_STREAM_ID;
+        private int mStreamIdType = STREAM_ID_TYPE_ID;
+        private int mModulation = MODULATION_UNDEFINED;
+        private int mCodeRate = CODERATE_UNDEFINED;
+        private int mSymbolRate = 0;
+        private int mRolloff = ROLLOFF_UNDEFINED;
 
         private Builder() {
         }
 
         /**
          * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         @IntRange(from = 1)
@@ -233,6 +236,8 @@
 
         /**
          * Sets Stream ID.
+         *
+         * <p>Default value is {@link Tuner#INVALID_STREAM_ID}.
          */
         @NonNull
         public Builder setStreamId(int streamId) {
@@ -241,6 +246,8 @@
         }
         /**
          * Sets StreamIdType.
+         *
+         * <p>Default value is {@link #STREAM_ID_TYPE_ID}.
          */
         @NonNull
         public Builder setStreamIdType(@StreamIdType int streamIdType) {
@@ -249,6 +256,8 @@
         }
         /**
          * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
          */
         @NonNull
         public Builder setModulation(@Modulation int modulation) {
@@ -257,6 +266,8 @@
         }
         /**
          * Sets Code rate.
+         *
+         * <p>Default value is {@link #CODERATE_UNDEFINED}.
          */
         @NonNull
         public Builder setCodeRate(@CodeRate int codeRate) {
@@ -265,6 +276,8 @@
         }
         /**
          * Sets Symbol Rate in symbols per second.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         public Builder setSymbolRate(int symbolRate) {
@@ -273,6 +286,8 @@
         }
         /**
          * Sets Roll off type.
+         *
+         * <p>Default value is {@link #ROLLOFF_UNDEFINED}.
          */
         @NonNull
         public Builder setRolloff(@Rolloff int rolloff) {
diff --git a/media/java/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java
index b607623..915380e 100644
--- a/media/java/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java
@@ -204,19 +204,21 @@
      * Builder for {@link IsdbtFrontendSettings}.
      */
     public static class Builder {
-        private int mFrequency;
-        private int mModulation;
-        private int mBandwidth;
-        private int mMode;
-        private int mCodeRate;
-        private int mGuardInterval;
-        private int mServiceAreaId;
+        private int mFrequency = 0;
+        private int mModulation = MODULATION_UNDEFINED;
+        private int mBandwidth = BANDWIDTH_UNDEFINED;
+        private int mMode = MODE_UNDEFINED;
+        private int mCodeRate = DvbtFrontendSettings.CODERATE_UNDEFINED;
+        private int mGuardInterval = DvbtFrontendSettings.GUARD_INTERVAL_UNDEFINED;
+        private int mServiceAreaId = 0;
 
         private Builder() {
         }
 
         /**
          * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         @IntRange(from = 1)
@@ -227,6 +229,8 @@
 
         /**
          * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
          */
         @NonNull
         public Builder setModulation(@Modulation int modulation) {
@@ -235,6 +239,8 @@
         }
         /**
          * Sets Bandwidth.
+         *
+         * <p>Default value is {@link #BANDWIDTH_UNDEFINED}.
          */
         @NonNull
         public Builder setBandwidth(@Bandwidth int bandwidth) {
@@ -243,6 +249,8 @@
         }
         /**
          * Sets ISDBT mode.
+         *
+         * <p>Default value is {@link #MODE_UNDEFINED}.
          */
         @NonNull
         public Builder setMode(@Mode int mode) {
@@ -251,14 +259,18 @@
         }
         /**
          * Sets Code rate.
+         *
+         * <p>Default value is {@link DvbtFrontendSettings#CODERATE_UNDEFINED}.
          */
         @NonNull
-        public Builder setCodeRate(@CodeRate int codeRate) {
+        public Builder setCodeRate(@DvbtFrontendSettings.CodeRate int codeRate) {
             mCodeRate = codeRate;
             return this;
         }
         /**
          * Sets Guard Interval.
+         *
+         * <p>Default value is {@link DvbtFrontendSettings#GUARD_INTERVAL_UNDEFINED}.
          */
         @NonNull
         public Builder setGuardInterval(@DvbtFrontendSettings.GuardInterval int guardInterval) {
@@ -267,6 +279,8 @@
         }
         /**
          * Sets Service Area ID.
+         *
+         * <p>Default value is 0.
          */
         @NonNull
         public Builder setServiceAreaId(int serviceAreaId) {
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
index 9dddcd4..63a71e2 100644
--- a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
@@ -17,6 +17,7 @@
 package android.media.tv.tunerresourcemanager;
 
 import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresFeature;
@@ -27,6 +28,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.concurrent.Executor;
 
 /**
@@ -61,6 +64,24 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     public static final int INVALID_RESOURCE_HANDLE = -1;
+    /**
+     * Tuner resource type to help generate resource handle
+     */
+    @IntDef({
+        TUNER_RESOURCE_TYPE_FRONTEND,
+        TUNER_RESOURCE_TYPE_DEMUX,
+        TUNER_RESOURCE_TYPE_DESCRAMBLER,
+        TUNER_RESOURCE_TYPE_LNB,
+        TUNER_RESOURCE_TYPE_CAS_SESSION,
+     })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TunerResourceType {}
+
+    public static final int TUNER_RESOURCE_TYPE_FRONTEND = 0;
+    public static final int TUNER_RESOURCE_TYPE_DEMUX = 1;
+    public static final int TUNER_RESOURCE_TYPE_DESCRAMBLER = 2;
+    public static final int TUNER_RESOURCE_TYPE_LNB = 3;
+    public static final int TUNER_RESOURCE_TYPE_CAS_SESSION = 4;
 
     private final ITunerResourceManager mService;
     private final int mUserId;
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index a37c9e5..bbeb451 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -1410,6 +1410,10 @@
     return (IDescrambler *)env->GetLongField(descrambler, gFields.descramblerContext);
 }
 
+static uint32_t getResourceIdFromHandle(jint handle) {
+    return (handle & 0x00ff0000) >> 16;
+}
+
 static DemuxPid getDemuxPid(int pidType, int pid) {
     DemuxPid demuxPid;
     if ((int)pidType == 1) {
@@ -1968,8 +1972,10 @@
     return tuner->getFrontendIds();
 }
 
-static jobject android_media_tv_Tuner_open_frontend_by_id(JNIEnv *env, jobject thiz, jint id) {
+static jobject android_media_tv_Tuner_open_frontend_by_handle(
+        JNIEnv *env, jobject thiz, jint handle) {
     sp<JTuner> tuner = getTuner(env, thiz);
+    uint32_t id = getResourceIdFromHandle(handle);
     return tuner->openFrontendById(id);
 }
 
@@ -2045,8 +2051,9 @@
     return tuner->getLnbIds();
 }
 
-static jobject android_media_tv_Tuner_open_lnb_by_id(JNIEnv *env, jobject thiz, jint id) {
+static jobject android_media_tv_Tuner_open_lnb_by_handle(JNIEnv *env, jobject thiz, jint handle) {
     sp<JTuner> tuner = getTuner(env, thiz);
+    uint32_t id = getResourceIdFromHandle(handle);
     return tuner->openLnbById(id);
 }
 
@@ -2924,8 +2931,8 @@
     { "nativeSetup", "()V", (void *)android_media_tv_Tuner_native_setup },
     { "nativeGetFrontendIds", "()Ljava/util/List;",
             (void *)android_media_tv_Tuner_get_frontend_ids },
-    { "nativeOpenFrontendById", "(I)Landroid/media/tv/tuner/Tuner$Frontend;",
-            (void *)android_media_tv_Tuner_open_frontend_by_id },
+    { "nativeOpenFrontendByHandle", "(I)Landroid/media/tv/tuner/Tuner$Frontend;",
+            (void *)android_media_tv_Tuner_open_frontend_by_handle },
     { "nativeTune", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;)I",
             (void *)android_media_tv_Tuner_tune },
     { "nativeStopTune", "()I", (void *)android_media_tv_Tuner_stop_tune },
@@ -2950,8 +2957,8 @@
             (void *)android_media_tv_Tuner_open_time_filter },
     { "nativeGetLnbIds", "()Ljava/util/List;",
             (void *)android_media_tv_Tuner_get_lnb_ids },
-    { "nativeOpenLnbById", "(I)Landroid/media/tv/tuner/Lnb;",
-            (void *)android_media_tv_Tuner_open_lnb_by_id },
+    { "nativeOpenLnbByHandle", "(I)Landroid/media/tv/tuner/Lnb;",
+            (void *)android_media_tv_Tuner_open_lnb_by_handle },
     { "nativeOpenLnbByName", "(Ljava/lang/String;)Landroid/media/tv/tuner/Lnb;",
             (void *)android_media_tv_Tuner_open_lnb_by_name },
     { "nativeOpenDescrambler", "()Landroid/media/tv/tuner/Descrambler;",
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 1362433..f9a77f4 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -196,7 +196,6 @@
                 callbackInfo->visualizer_ref,
                 NATIVE_EVENT_PCM_CAPTURE,
                 samplingrate,
-                0,
                 jArray);
         }
     }
@@ -217,7 +216,6 @@
                 callbackInfo->visualizer_ref,
                 NATIVE_EVENT_FFT_CAPTURE,
                 samplingrate,
-                0,
                 jArray);
         }
     }
@@ -286,7 +284,7 @@
     // Get the postEvent method
     fields.midPostNativeEvent = env->GetStaticMethodID(
             fields.clazzEffect,
-            "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+            "postEventFromNative", "(Ljava/lang/Object;II[B)V");
     if (fields.midPostNativeEvent == NULL) {
         ALOGE("Can't find Visualizer.%s", "postEventFromNative");
         return;
@@ -343,7 +341,7 @@
             fields.midPostNativeEvent,
             callbackInfo->visualizer_ref,
             NATIVE_EVENT_SERVER_DIED,
-            0, 0, NULL);
+            0, NULL);
     }
 }
 
diff --git a/packages/CarSystemUI/proguard.flags b/packages/CarSystemUI/proguard.flags
index a81c7e0..66cbf26 100644
--- a/packages/CarSystemUI/proguard.flags
+++ b/packages/CarSystemUI/proguard.flags
@@ -1,3 +1,4 @@
 -keep class com.android.systemui.CarSystemUIFactory
+-keep class com.android.car.notification.headsup.animationhelper.**
 
 -include ../SystemUI/proguard.flags
diff --git a/packages/CarSystemUI/res/drawable/headsup_scrim_bottom.xml b/packages/CarSystemUI/res/drawable/headsup_scrim_bottom.xml
new file mode 100644
index 0000000..1724ef0
--- /dev/null
+++ b/packages/CarSystemUI/res/drawable/headsup_scrim_bottom.xml
@@ -0,0 +1,24 @@
+<?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.
+  -->
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <gradient
+        android:startColor="@android:color/black"
+        android:endColor="@android:color/transparent"
+        android:angle="90" />
+</shape>
diff --git a/packages/CarSystemUI/res/layout/headsup_container_bottom.xml b/packages/CarSystemUI/res/layout/headsup_container_bottom.xml
new file mode 100644
index 0000000..caf1677
--- /dev/null
+++ b/packages/CarSystemUI/res/layout/headsup_container_bottom.xml
@@ -0,0 +1,50 @@
+<?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.
+  -->
+
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/notification_headsup"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/gradient_edge"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        app:layout_constraintGuide_begin="@dimen/headsup_scrim_height"/>
+
+    <View
+        android:id="@+id/scrim"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:background="@drawable/headsup_scrim_bottom"
+        app:layout_constraintBottom_toBottomOf="@+id/gradient_edge"
+        app:layout_constraintTop_toTopOf="parent"/>
+
+    <FrameLayout
+        android:id="@+id/headsup_content"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/headsup_notification_top_margin"
+        app:layout_constraintEnd_toStartOf="parent"
+        app:layout_constraintStart_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+    />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index aaa65de..2077e77 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -34,6 +34,13 @@
 
     <!-- Whether heads-up notifications should be shown when shade is open. -->
     <bool name="config_enableHeadsUpNotificationWhenNotificationShadeOpen">true</bool>
+    <!-- Whether heads-up notifications should be shown on the bottom. If false, heads-up
+         notifications will be shown pushed to the top of their parent container. If true, they will
+         be shown pushed to the bottom of their parent container. If true, then should override
+         config_headsUpNotificationAnimationHelper to use a different AnimationHelper, such as
+         com.android.car.notification.headsup.animationhelper.
+         CarHeadsUpNotificationBottomAnimationHelper. -->
+    <bool name="config_showHeadsUpNotificationOnBottom">false</bool>
 
     <bool name="config_hideNavWhenKeyguardBouncerShown">true</bool>
     <bool name="config_enablePersistentDockedActivity">false</bool>
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java
index 689d2d5..53e5d9f 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/CarHeadsUpNotificationSystemContainer.java
@@ -60,6 +60,8 @@
         mCarDeviceProvisionedController = deviceProvisionedController;
         mCarStatusBarLazy = carStatusBarLazy;
 
+        boolean showOnBottom = resources.getBoolean(R.bool.config_showHeadsUpNotificationOnBottom);
+
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 WindowManager.LayoutParams.WRAP_CONTENT,
@@ -68,11 +70,13 @@
                         | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                 PixelFormat.TRANSLUCENT);
 
-        lp.gravity = Gravity.TOP;
+        lp.gravity = showOnBottom ? Gravity.BOTTOM : Gravity.TOP;
         lp.setTitle("HeadsUpNotification");
 
-        mWindow = (ViewGroup) LayoutInflater.from(context)
-                .inflate(R.layout.headsup_container, null, false);
+        int layoutId = showOnBottom
+                ? R.layout.headsup_container_bottom
+                : R.layout.headsup_container;
+        mWindow = (ViewGroup) LayoutInflater.from(context).inflate(layoutId, null, false);
         windowManager.addView(mWindow, lp);
         mWindow.setVisibility(View.INVISIBLE);
         mHeadsUpContentFrame = mWindow.findViewById(R.id.headsup_content);
diff --git a/packages/SettingsLib/res/drawable/ic_media_group_device.xml b/packages/SettingsLib/res/drawable/ic_media_group_device.xml
new file mode 100644
index 0000000..ba5e651
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_media_group_device.xml
@@ -0,0 +1,32 @@
+<!--
+  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
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z"
+        android:fillColor="#000000"/>
+    <path
+        android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"
+        android:fillColor="#000000"/>
+    <path
+        android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z"
+        android:fillColor="#000000"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 00f6bcb..a797066 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1039,7 +1039,7 @@
     <!-- Title for the accessibility preference to configure display color space correction. [CHAR LIMIT=NONE] -->
     <string name="accessibility_display_daltonizer_preference_title">Color correction</string>
     <!-- Subtitle for the accessibility preference to configure display color space correction. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_display_daltonizer_preference_subtitle">Color correction helps the device display more accurate colors. Color correction may be helpful for people with colorblindness.</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle"><![CDATA[Color correction allows you to adjust how colors are displayed on your device]]></string>
     <!-- Summary shown for color space correction preference when its value is overridden by another preference [CHAR LIMIT=35] -->
     <string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
index b725ba5..85fa988 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
@@ -15,11 +15,17 @@
  */
 package com.android.settingslib.media;
 
+import static android.media.MediaRoute2Info.TYPE_GROUP;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
+
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2Manager;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.settingslib.R;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 
@@ -51,7 +57,23 @@
     public Drawable getIcon() {
         //TODO(b/120669861): Return remote device icon uri once api is ready.
         return BluetoothUtils.buildBtRainbowDrawable(mContext,
-                mContext.getDrawable(R.drawable.ic_media_device), getId().hashCode());
+                mContext.getDrawable(getDrawableResId()), getId().hashCode());
+    }
+
+    @VisibleForTesting
+    int getDrawableResId() {
+        int resId;
+        switch (mRouteInfo.getType()) {
+            case TYPE_GROUP:
+                resId = R.drawable.ic_media_group_device;
+                break;
+            case TYPE_REMOTE_TV:
+            case TYPE_REMOTE_SPEAKER:
+            default:
+                resId = R.drawable.ic_media_device;
+                break;
+        }
+        return resId;
     }
 
     @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index 166fbaa..af88723 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -15,11 +15,17 @@
  */
 package com.android.settingslib.media;
 
+import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
+
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2Manager;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.settingslib.R;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 
@@ -43,7 +49,18 @@
 
     @Override
     public String getName() {
-        return mContext.getString(R.string.media_transfer_this_device_name);
+        CharSequence name;
+        switch (mRouteInfo.getType()) {
+            case TYPE_WIRED_HEADSET:
+            case TYPE_WIRED_HEADPHONES:
+                name = mRouteInfo.getName();
+                break;
+            case TYPE_BUILTIN_SPEAKER:
+            default:
+                name = mContext.getString(R.string.media_transfer_this_device_name);
+                break;
+        }
+        return name.toString();
     }
 
     @Override
@@ -54,7 +71,23 @@
     @Override
     public Drawable getIcon() {
         return BluetoothUtils.buildBtRainbowDrawable(mContext,
-                mContext.getDrawable(R.drawable.ic_smartphone), getId().hashCode());
+                mContext.getDrawable(getDrawableResId()), getId().hashCode());
+    }
+
+    @VisibleForTesting
+    int getDrawableResId() {
+        int resId;
+        switch (mRouteInfo.getType()) {
+            case TYPE_WIRED_HEADSET:
+            case TYPE_WIRED_HEADPHONES:
+                resId = com.android.internal.R.drawable.ic_bt_headphones_a2dp;
+                break;
+            case TYPE_BUILTIN_SPEAKER:
+            default:
+                resId = R.drawable.ic_smartphone;
+                break;
+        }
+        return resId;
     }
 
     @Override
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
index 77a67c2..685c834 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
@@ -16,6 +16,10 @@
 
 package com.android.settingslib.media;
 
+import static android.media.MediaRoute2Info.TYPE_GROUP;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.when;
@@ -86,4 +90,19 @@
 
         assertThat(mInfoMediaDevice.getId()).isEqualTo(TEST_ID);
     }
+
+    @Test
+    public void getDrawableResId_returnCorrectResId() {
+        when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_TV);
+
+        assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_media_device);
+
+        when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_SPEAKER);
+
+        assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_media_device);
+
+        when(mRouteInfo.getType()).thenReturn(TYPE_GROUP);
+
+        assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_media_group_device);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
index db984fb..4c5cd96 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
@@ -16,15 +16,23 @@
 
 package com.android.settingslib.media;
 
+import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
+import android.media.MediaRoute2Info;
 
 import com.android.settingslib.R;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
@@ -32,6 +40,9 @@
 @RunWith(RobolectricTestRunner.class)
 public class PhoneMediaDeviceTest {
 
+    @Mock
+    private MediaRoute2Info mInfo;
+
     private Context mContext;
     private PhoneMediaDevice mPhoneMediaDevice;
 
@@ -41,7 +52,7 @@
         mContext = RuntimeEnvironment.application;
 
         mPhoneMediaDevice =
-                new PhoneMediaDevice(mContext, null, null, null);
+                new PhoneMediaDevice(mContext, null, mInfo, null);
     }
 
     @Test
@@ -58,4 +69,42 @@
 
         assertThat(mPhoneMediaDevice.getSummary()).isEmpty();
     }
+
+    @Test
+    public void getDrawableResId_returnCorrectResId() {
+        when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADPHONES);
+
+        assertThat(mPhoneMediaDevice.getDrawableResId())
+                .isEqualTo(com.android.internal.R.drawable.ic_bt_headphones_a2dp);
+
+        when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADSET);
+
+        assertThat(mPhoneMediaDevice.getDrawableResId())
+                .isEqualTo(com.android.internal.R.drawable.ic_bt_headphones_a2dp);
+
+        when(mInfo.getType()).thenReturn(TYPE_BUILTIN_SPEAKER);
+
+        assertThat(mPhoneMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_smartphone);
+    }
+
+    @Test
+    public void getName_returnCorrectName() {
+        final String deviceName = "test_name";
+
+        when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADPHONES);
+        when(mInfo.getName()).thenReturn(deviceName);
+
+        assertThat(mPhoneMediaDevice.getName())
+                .isEqualTo(deviceName);
+
+        when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADSET);
+
+        assertThat(mPhoneMediaDevice.getName())
+                .isEqualTo(deviceName);
+
+        when(mInfo.getType()).thenReturn(TYPE_BUILTIN_SPEAKER);
+
+        assertThat(mPhoneMediaDevice.getName())
+                .isEqualTo(mContext.getString(R.string.media_transfer_this_device_name));
+    }
 }
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 610165a..dab0505 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -199,7 +199,6 @@
                     Settings.Global.CERT_PIN_UPDATE_CONTENT_URL,
                     Settings.Global.CERT_PIN_UPDATE_METADATA_URL,
                     Settings.Global.COMPATIBILITY_MODE,
-                    Settings.Global.COMMON_CRITERIA_MODE,
                     Settings.Global.CONNECTIVITY_CHANGE_DELAY,
                     Settings.Global.CONNECTIVITY_METRICS_BUFFER_SIZE,
                     Settings.Global.CONNECTIVITY_SAMPLING_INTERVAL_IN_SECONDS,
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index a76f961..d506e7e 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -58,13 +58,15 @@
         android:elevation="@dimen/screenshot_preview_elevation"
         android:visibility="gone"
         android:background="@drawable/screenshot_rounded_corners"
-        android:adjustViewBounds="true"/>
+        android:adjustViewBounds="true"
+        android:contentDescription="@string/screenshot_preview_description"/>
     <FrameLayout
         android:id="@+id/global_screenshot_dismiss_button"
         android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
         android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
         android:elevation="7dp"
-        android:visibility="gone">
+        android:visibility="gone"
+        android:contentDescription="@string/screenshot_dismiss_ui_description">
         <ImageView
             android:layout_width="match_parent"
             android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 3543073..93bafdb 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -233,6 +233,10 @@
     <!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] -->
     <string name="screenshot_failed_to_capture_text">Taking screenshots isn\'t allowed by the app or
         your organization</string>
+    <!-- Content description indicating that tapping a button will dismiss the screenshots UI [CHAR LIMIT=NONE] -->
+    <string name="screenshot_dismiss_ui_description">Dismiss screenshot</string>
+    <!-- Content description indicating that tapping will open an app to view/edit the screenshot. [CHAR LIMIT=NONE] -->
+    <string name="screenshot_preview_description">Open screenshot</string>
 
     <!-- Notification title displayed for screen recording [CHAR LIMIT=50]-->
     <string name="screenrecord_name">Screen Recorder</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 431c451..90df124 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2740,6 +2740,8 @@
 
         mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
         mBroadcastDispatcher.unregisterReceiver(mBroadcastAllReceiver);
+
+        mHandler.removeCallbacksAndMessages(null);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index a8a3cae..5f004a6 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -122,7 +122,7 @@
     protected int mRoundedDefaultBottom;
     @VisibleForTesting
     protected View[] mOverlays;
-    private DisplayCutoutView[] mCutoutViews;
+    private DisplayCutoutView[] mCutoutViews = new DisplayCutoutView[BOUNDS_POSITION_LENGTH];
     private float mDensity;
     private WindowManager mWindowManager;
     private int mRotation;
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index a161d03..e208ee2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -33,7 +33,6 @@
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.PlaybackState;
-import android.os.Handler;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -64,6 +63,7 @@
 public class MediaControlPanel implements NotificationMediaManager.MediaListener {
     private static final String TAG = "MediaControlPanel";
     private final NotificationMediaManager mMediaManager;
+    private final Executor mForegroundExecutor;
     private final Executor mBackgroundExecutor;
 
     private Context mContext;
@@ -102,15 +102,18 @@
      * @param manager
      * @param layoutId layout resource to use for this control panel
      * @param actionIds resource IDs for action buttons in the layout
+     * @param foregroundExecutor foreground executor
      * @param backgroundExecutor background executor, used for processing artwork
      */
     public MediaControlPanel(Context context, ViewGroup parent, NotificationMediaManager manager,
-            @LayoutRes int layoutId, int[] actionIds, Executor backgroundExecutor) {
+            @LayoutRes int layoutId, int[] actionIds, Executor foregroundExecutor,
+            Executor backgroundExecutor) {
         mContext = context;
         LayoutInflater inflater = LayoutInflater.from(mContext);
         mMediaNotifView = (LinearLayout) inflater.inflate(layoutId, parent, false);
         mMediaManager = manager;
         mActionIds = actionIds;
+        mForegroundExecutor = foregroundExecutor;
         mBackgroundExecutor = backgroundExecutor;
     }
 
@@ -176,15 +179,17 @@
         mMediaNotifView.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
 
         // Click action
-        mMediaNotifView.setOnClickListener(v -> {
-            try {
-                contentIntent.send();
-                // Also close shade
-                mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
-            } catch (PendingIntent.CanceledException e) {
-                Log.e(TAG, "Pending intent was canceled", e);
-            }
-        });
+        if (contentIntent != null) {
+            mMediaNotifView.setOnClickListener(v -> {
+                try {
+                    contentIntent.send();
+                    // Also close shade
+                    mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+                } catch (PendingIntent.CanceledException e) {
+                    Log.e(TAG, "Pending intent was canceled", e);
+                }
+            });
+        }
 
         // App icon
         ImageView appIcon = mMediaNotifView.findViewById(R.id.icon);
@@ -316,7 +321,7 @@
 
         // Now that it's resized, update the UI
         final RoundedBitmapDrawable result = roundedDrawable;
-        albumView.getHandler().post(() -> {
+        mForegroundExecutor.execute(() -> {
             if (result != null) {
                 albumView.setImageDrawable(result);
                 albumView.setVisibility(View.VISIBLE);
@@ -335,8 +340,7 @@
         if (mSeamless == null) {
             return;
         }
-        Handler handler = mSeamless.getHandler();
-        handler.post(() -> {
+        mForegroundExecutor.execute(() -> {
             updateChipInternal(device);
         });
     }
@@ -401,12 +405,15 @@
                         new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
                 mContext.sendBroadcast(intent);
             } else {
-                Log.d(TAG, "No receiver to restart");
                 // If we don't have a receiver, try relaunching the activity instead
-                try {
-                    mController.getSessionActivity().send();
-                } catch (PendingIntent.CanceledException e) {
-                    Log.e(TAG, "Pending intent was canceled", e);
+                if (mController.getSessionActivity() != null) {
+                    try {
+                        mController.getSessionActivity().send();
+                    } catch (PendingIntent.CanceledException e) {
+                        Log.e(TAG, "Pending intent was canceled", e);
+                    }
+                } else {
+                    Log.e(TAG, "No receiver or activity to restart");
                 }
             }
         });
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index 88491b7..8be2502 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -229,8 +229,8 @@
      */
     Rect getDestinationBounds(float aspectRatio, Rect bounds, Size minimalSize) {
         final Rect destinationBounds;
-        final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
         if (bounds == null) {
+            final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
             destinationBounds = new Rect(defaultBounds);
             if (mReentrySnapFraction == INVALID_SNAP_FRACTION && mReentrySize == null) {
                 mOverrideMinimalSize = minimalSize;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
index 8fff419..25acce6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
@@ -65,6 +65,7 @@
     private final PointF mDownPoint = new PointF();
     private final Point mMaxSize = new Point();
     private final Point mMinSize = new Point();
+    private final Rect mLastResizeBounds = new Rect();
     private final Rect mTmpBounds = new Rect();
     private final int mDelta;
 
@@ -187,17 +188,13 @@
     private void onMotionEvent(MotionEvent ev) {
         int action = ev.getActionMasked();
         if (action == MotionEvent.ACTION_DOWN) {
+            mLastResizeBounds.setEmpty();
             mAllowGesture = isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
             if (mAllowGesture) {
                 mDownPoint.set(ev.getX(), ev.getY());
             }
 
         } else if (mAllowGesture) {
-            final Rect currentPipBounds = mMotionHelper.getBounds();
-            Rect newSize = TaskResizingAlgorithm.resizeDrag(ev.getX(), ev.getY(), mDownPoint.x,
-                    mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x, mMinSize.y, mMaxSize,
-                    true, true);
-            mPipBoundsHandler.transformBoundsToAspectRatio(newSize);
             switch (action) {
                 case MotionEvent.ACTION_POINTER_DOWN:
                     // We do not support multi touch for resizing via drag
@@ -206,11 +203,16 @@
                 case MotionEvent.ACTION_MOVE:
                     // Capture inputs
                     mInputMonitor.pilferPointers();
-                    //TODO: Actually do resize here.
+                    final Rect currentPipBounds = mMotionHelper.getBounds();
+                    mLastResizeBounds.set(TaskResizingAlgorithm.resizeDrag(ev.getX(), ev.getY(),
+                            mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x,
+                            mMinSize.y, mMaxSize, true, true));
+                    mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds);
+                    mPipTaskOrganizer.scheduleResizePip(mLastResizeBounds, null);
                     break;
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL:
-                    //TODO: Finish resize operation here.
+                    mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds);
                     mMotionHelper.synchronizePinnedStackBounds();
                     mCtrlType = CTRL_NONE;
                     mAllowGesture = false;
@@ -223,7 +225,7 @@
         mMaxSize.set(maxX, maxY);
     }
 
-    void updateMiniSize(int minX, int minY) {
+    void updateMinSize(int minX, int minY) {
         mMinSize.set(minX, minY);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index b5fb1a9..9b67d80 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -42,6 +42,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityWindowInfo;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.logging.MetricsLoggerWrapper;
 import com.android.systemui.R;
 import com.android.systemui.pip.PipBoundsHandler;
@@ -74,7 +75,7 @@
     private final Context mContext;
     private final IActivityManager mActivityManager;
     private final PipBoundsHandler mPipBoundsHandler;
-    private final PipResizeGestureHandler mPipResizeGestureHandler;
+    private PipResizeGestureHandler mPipResizeGestureHandler;
     private IPinnedStackController mPinnedStackController;
 
     private final PipMenuActivityController mMenuController;
@@ -85,14 +86,17 @@
 
     // The current movement bounds
     private Rect mMovementBounds = new Rect();
+    // The current resized bounds, changed by user resize.
+    // This is used during expand/un-expand to save/restore the user's resized size.
+    @VisibleForTesting Rect mResizedBounds = new Rect();
 
     // The reference inset bounds, used to determine the dismiss fraction
     private Rect mInsetBounds = new Rect();
     // The reference bounds used to calculate the normal/expanded target bounds
     private Rect mNormalBounds = new Rect();
-    private Rect mNormalMovementBounds = new Rect();
+    @VisibleForTesting Rect mNormalMovementBounds = new Rect();
     private Rect mExpandedBounds = new Rect();
-    private Rect mExpandedMovementBounds = new Rect();
+    @VisibleForTesting Rect mExpandedMovementBounds = new Rect();
     private int mExpandedShortestEdgeSize;
 
     // Used to workaround an issue where the WM rotation happens before we are notified, allowing
@@ -127,7 +131,7 @@
     private final PipTouchState mTouchState;
     private final FlingAnimationUtils mFlingAnimationUtils;
     private final FloatingContentCoordinator mFloatingContentCoordinator;
-    private final PipMotionHelper mMotionHelper;
+    private PipMotionHelper mMotionHelper;
     private PipTouchGesture mGesture;
 
     // Temp vars
@@ -240,14 +244,15 @@
 
             mFloatingContentCoordinator.onContentRemoved(mMotionHelper);
         }
+        mResizedBounds.setEmpty();
         mPipResizeGestureHandler.onActivityUnpinned();
     }
 
     public void onPinnedStackAnimationEnded() {
         // Always synchronize the motion helper bounds once PiP animations finish
         mMotionHelper.synchronizePinnedStackBounds();
-        mPipResizeGestureHandler.updateMiniSize(mMotionHelper.getBounds().width(),
-                mMotionHelper.getBounds().height());
+        updateMovementBounds();
+        mResizedBounds.set(mMotionHelper.getBounds());
 
         if (mShowPipMenuOnAnimationEnd) {
             mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(),
@@ -292,11 +297,13 @@
         Size expandedSize = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio,
                 mExpandedShortestEdgeSize, displaySize.x, displaySize.y);
         mExpandedBounds.set(0, 0, expandedSize.getWidth(), expandedSize.getHeight());
-        mPipResizeGestureHandler.updateMaxSize(expandedSize.getWidth(), expandedSize.getHeight());
         Rect expandedMovementBounds = new Rect();
         mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds, expandedMovementBounds,
                 bottomOffset);
 
+        mPipResizeGestureHandler.updateMinSize(mNormalBounds.width(), mNormalBounds.height());
+        mPipResizeGestureHandler.updateMaxSize(mExpandedBounds.width(), mExpandedBounds.height());
+
         // The extra offset does not really affect the movement bounds, but are applied based on the
         // current state (ime showing, or shelf offset) when we need to actually shift
         int extraOffset = Math.max(
@@ -332,7 +339,7 @@
         mExpandedMovementBounds = expandedMovementBounds;
         mDisplayRotation = displayRotation;
         mInsetBounds.set(insetBounds);
-        updateMovementBounds(mMenuState);
+        updateMovementBounds();
         mMovementBoundsExtraOffsets = extraOffset;
 
         // If we have a deferred resize, apply it now
@@ -392,7 +399,7 @@
             case MotionEvent.ACTION_UP: {
                 // Update the movement bounds again if the state has changed since the user started
                 // dragging (ie. when the IME shows)
-                updateMovementBounds(mMenuState);
+                updateMovementBounds();
 
                 if (mGesture.onUp(mTouchState)) {
                     break;
@@ -490,9 +497,11 @@
         if (menuState == MENU_STATE_FULL && mMenuState != MENU_STATE_FULL) {
             // Save the current snap fraction and if we do not drag or move the PiP, then
             // we store back to this snap fraction.  Otherwise, we'll reset the snap
-            // fraction and snap to the closest edge
-            Rect expandedBounds = new Rect(mExpandedBounds);
+            // fraction and snap to the closest edge.
+            // Also save the current resized bounds so when the menu disappears, we can restore it.
             if (resize) {
+                mResizedBounds.set(mMotionHelper.getBounds());
+                Rect expandedBounds = new Rect(mExpandedBounds);
                 mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds,
                         mMovementBounds, mExpandedMovementBounds);
             }
@@ -520,9 +529,12 @@
                 }
 
                 if (mDeferResizeToNormalBoundsUntilRotation == -1) {
-                    Rect normalBounds = new Rect(mNormalBounds);
-                    mMotionHelper.animateToUnexpandedState(normalBounds, mSavedSnapFraction,
-                            mNormalMovementBounds, mMovementBounds, false /* immediate */);
+                    Rect restoreBounds = new Rect(mResizedBounds);
+                    Rect restoredMovementBounds = new Rect();
+                    mSnapAlgorithm.getMovementBounds(restoreBounds, mInsetBounds,
+                            restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
+                    mMotionHelper.animateToUnexpandedState(restoreBounds, mSavedSnapFraction,
+                            restoredMovementBounds, mMovementBounds, false /* immediate */);
                     mSavedSnapFraction = -1f;
                 }
             } else {
@@ -533,7 +545,7 @@
             }
         }
         mMenuState = menuState;
-        updateMovementBounds(menuState);
+        updateMovementBounds();
         // If pip menu has dismissed, we should register the A11y ActionReplacingConnection for pip
         // as well, or it can't handle a11y focus and pip menu can't perform any action.
         onRegistrationChanged(menuState == MENU_STATE_NONE);
@@ -549,6 +561,21 @@
         return mMotionHelper;
     }
 
+    @VisibleForTesting
+    PipResizeGestureHandler getPipResizeGestureHandler() {
+        return mPipResizeGestureHandler;
+    }
+
+    @VisibleForTesting
+    void setPipResizeGestureHandler(PipResizeGestureHandler pipResizeGestureHandler) {
+        mPipResizeGestureHandler = pipResizeGestureHandler;
+    }
+
+    @VisibleForTesting
+    void setPipMotionHelper(PipMotionHelper pipMotionHelper) {
+        mMotionHelper = pipMotionHelper;
+    }
+
     /**
      * @return the unexpanded bounds.
      */
@@ -709,14 +736,14 @@
      * Updates the current movement bounds based on whether the menu is currently visible and
      * resized.
      */
-    private void updateMovementBounds(int menuState) {
-        boolean isMenuExpanded = menuState == MENU_STATE_FULL;
-        mMovementBounds = isMenuExpanded && willResizeMenu()
-                ? mExpandedMovementBounds
-                : mNormalMovementBounds;
-        mPipBoundsHandler.setMinEdgeSize(
-                isMenuExpanded ? mExpandedShortestEdgeSize : 0);
+    private void updateMovementBounds() {
+        mSnapAlgorithm.getMovementBounds(mMotionHelper.getBounds(), mInsetBounds,
+                mMovementBounds, mIsImeShowing ? mImeHeight : 0);
         mMotionHelper.setCurrentMovementBounds(mMovementBounds);
+
+        boolean isMenuExpanded = mMenuState == MENU_STATE_FULL;
+        mPipBoundsHandler.setMinEdgeSize(
+                isMenuExpanded  && willResizeMenu() ? mExpandedShortestEdgeSize : 0);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
index 837256b..d5e5b10 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
@@ -55,11 +55,13 @@
      * @param context
      * @param parent
      * @param manager
+     * @param foregroundExecutor
      * @param backgroundExecutor
      */
     public QSMediaPlayer(Context context, ViewGroup parent, NotificationMediaManager manager,
-            Executor backgroundExecutor) {
-        super(context, parent, manager, R.layout.qs_media_panel, QS_ACTION_IDS, backgroundExecutor);
+            Executor foregroundExecutor, Executor backgroundExecutor) {
+        super(context, parent, manager, R.layout.qs_media_panel, QS_ACTION_IDS, foregroundExecutor,
+                backgroundExecutor);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index bf72b33..5ccf8c7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -53,6 +53,7 @@
 import com.android.systemui.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSTile;
@@ -101,6 +102,7 @@
     private final ArrayList<QSMediaPlayer> mMediaPlayers = new ArrayList<>();
     private final NotificationMediaManager mNotificationMediaManager;
     private final LocalBluetoothManager mLocalBluetoothManager;
+    private final Executor mForegroundExecutor;
     private final Executor mBackgroundExecutor;
     private LocalMediaManager mLocalMediaManager;
     private MediaDevice mDevice;
@@ -160,6 +162,7 @@
             BroadcastDispatcher broadcastDispatcher,
             QSLogger qsLogger,
             NotificationMediaManager notificationMediaManager,
+            @Main Executor foregroundExecutor,
             @Background Executor backgroundExecutor,
             @Nullable LocalBluetoothManager localBluetoothManager
     ) {
@@ -168,6 +171,7 @@
         mQSLogger = qsLogger;
         mDumpManager = dumpManager;
         mNotificationMediaManager = notificationMediaManager;
+        mForegroundExecutor = foregroundExecutor;
         mBackgroundExecutor = backgroundExecutor;
         mLocalBluetoothManager = localBluetoothManager;
 
@@ -270,7 +274,7 @@
         if (player == null) {
             Log.d(TAG, "creating new player");
             player = new QSMediaPlayer(mContext, this, mNotificationMediaManager,
-                    mBackgroundExecutor);
+                    mForegroundExecutor, mBackgroundExecutor);
 
             if (player.isPlaying()) {
                 mMediaCarousel.addView(player.getView(), 0, lp); // add in front
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java
index 4512afb..0c50194 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java
@@ -48,12 +48,13 @@
      * @param context
      * @param parent
      * @param manager
+     * @param foregroundExecutor
      * @param backgroundExecutor
      */
     public QuickQSMediaPlayer(Context context, ViewGroup parent, NotificationMediaManager manager,
-            Executor backgroundExecutor) {
+            Executor foregroundExecutor, Executor backgroundExecutor) {
         super(context, parent, manager, R.layout.qqs_media_panel, QQS_ACTION_IDS,
-                backgroundExecutor);
+                foregroundExecutor, backgroundExecutor);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 6654b7a..be01d75 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -32,6 +32,7 @@
 import com.android.systemui.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTile.SignalState;
@@ -79,11 +80,12 @@
             BroadcastDispatcher broadcastDispatcher,
             QSLogger qsLogger,
             NotificationMediaManager notificationMediaManager,
+            @Main Executor foregroundExecutor,
             @Background Executor backgroundExecutor,
             @Nullable LocalBluetoothManager localBluetoothManager
     ) {
         super(context, attrs, dumpManager, broadcastDispatcher, qsLogger, notificationMediaManager,
-                backgroundExecutor, localBluetoothManager);
+                foregroundExecutor, backgroundExecutor, localBluetoothManager);
         if (mFooter != null) {
             removeView(mFooter.getView());
         }
@@ -103,7 +105,7 @@
 
             int marginSize = (int) mContext.getResources().getDimension(R.dimen.qqs_media_spacing);
             mMediaPlayer = new QuickQSMediaPlayer(mContext, mHorizontalLinearLayout,
-                    notificationMediaManager, backgroundExecutor);
+                    notificationMediaManager, foregroundExecutor, backgroundExecutor);
             LayoutParams lp2 = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
             lp2.setMarginEnd(marginSize);
             lp2.setMarginStart(0);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index d422dd7..11b625f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -436,6 +436,10 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        // Handle padding of QuickStatusBarHeader
+        setPadding(mRoundedCornerPadding, getPaddingTop(), mRoundedCornerPadding,
+                getPaddingBottom());
+
         // Handle padding of SystemIconsView
         DisplayCutout cutout = insets.getDisplayCutout();
         Pair<Integer, Integer> cornerCutoutPadding = StatusBarWindowView.cornerCutoutMargins(
@@ -450,8 +454,11 @@
         int statusBarPaddingRight = isLayoutRtl()
                 ? getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start)
                 : getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end);
-        mSystemIconsView.setPadding(padding.first + statusBarPaddingLeft, waterfallTopInset,
-                padding.second + statusBarPaddingRight, 0);
+        mSystemIconsView.setPadding(
+                Math.max(padding.first + statusBarPaddingLeft - mRoundedCornerPadding, 0),
+                waterfallTopInset,
+                Math.max(padding.second + statusBarPaddingRight - mRoundedCornerPadding, 0),
+                0);
 
         return super.onApplyWindowInsets(insets);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
index fabe3a7..b357ada 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
@@ -45,7 +45,6 @@
     private final ArrayList<Callback> mCallbacks =  new ArrayList<>();
     private final Handler mHandler;
 
-    private NotificationPresenter mPresenter;
     private boolean mPanelExpanded;
     private boolean mScreenOn;
     private boolean mReorderingAllowed;
@@ -80,7 +79,6 @@
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter) {
-        mPresenter = presenter;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java
index b960b42..2c747bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.collection;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -51,6 +52,7 @@
         return mSummary;
     }
 
+    @NonNull
     public List<NotificationEntry> getChildren() {
         return mUnmodifiableChildren;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewBarn.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewBarn.kt
new file mode 100644
index 0000000..e7948cd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewBarn.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.statusbar.notification.collection
+
+import android.view.textclassifier.Log
+import com.android.systemui.statusbar.notification.stack.NotificationListItem
+import java.lang.IllegalStateException
+
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * The ViewBarn is just a map from [ListEntry] to an instance of [NotificationListItem] which is
+ * usually just an [ExpandableNotificationRow]
+ */
+@Singleton
+class NotifViewBarn @Inject constructor() {
+    private val DEBUG = false
+
+    private val rowMap = mutableMapOf<String, NotificationListItem>()
+
+    fun requireView(forEntry: ListEntry): NotificationListItem {
+        if (DEBUG) {
+            Log.d(TAG, "requireView: $forEntry.key")
+        }
+        val li = rowMap[forEntry.key]
+        if (li == null) {
+            throw IllegalStateException("No view has been registered for entry: $forEntry")
+        }
+
+        return li
+    }
+
+    fun registerViewForEntry(entry: ListEntry, view: NotificationListItem) {
+        if (DEBUG) {
+            Log.d(TAG, "registerViewForEntry: $entry.key")
+        }
+        rowMap[entry.key] = view
+    }
+
+    fun removeViewForEntry(entry: ListEntry) {
+        if (DEBUG) {
+            Log.d(TAG, "removeViewForEntry: $entry.key")
+        }
+        rowMap.remove(entry.key)
+    }
+}
+
+private const val TAG = "NotifViewBarn"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt
new file mode 100644
index 0000000..0437877
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt
@@ -0,0 +1,200 @@
+/*
+ * 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 com.android.systemui.statusbar.notification.collection
+
+import android.annotation.MainThread
+import android.view.ViewGroup
+
+import com.android.systemui.statusbar.FeatureFlags
+import com.android.systemui.statusbar.notification.VisualStabilityManager
+import com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY
+import com.android.systemui.statusbar.notification.stack.NotificationListItem
+import com.android.systemui.util.Assert
+
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import java.lang.IllegalStateException
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * A consumer of a Notification tree built by [ShadeListBuilder] which will update the notification
+ * presenter with the minimum operations required to make the old tree match the new one
+ */
+@MainThread
+@Singleton
+class NotifViewManager @Inject constructor(
+    private val rowRegistry: NotifViewBarn,
+    private val stabilityManager: VisualStabilityManager,
+    private val featureFlags: FeatureFlags
+) {
+    var currentNotifs = listOf<ListEntry>()
+
+    private lateinit var listContainer: SimpleNotificationListContainer
+
+    fun attach(listBuilder: ShadeListBuilder) {
+        if (featureFlags.isNewNotifPipelineRenderingEnabled) {
+            listBuilder.setOnRenderListListener { entries: List<ListEntry> ->
+                this.onNotifTreeBuilt(entries)
+            }
+        }
+    }
+
+    fun setViewConsumer(consumer: SimpleNotificationListContainer) {
+        listContainer = consumer
+    }
+
+    /**
+     * Callback for when the tree is rebuilt
+     */
+    fun onNotifTreeBuilt(notifList: List<ListEntry>) {
+        Assert.isMainThread()
+
+        /*
+         * The assumption here is that anything from the old NotificationViewHierarchyManager that
+         * is responsible for filtering is done via the NotifFilter logic. This tree we get should
+         * be *the stuff to display* +/- redacted stuff
+         */
+
+        detachRows(notifList)
+        attachRows(notifList)
+
+        currentNotifs = notifList
+    }
+
+    private fun detachRows(entries: List<ListEntry>) {
+        // To properly detach rows, we are looking to remove any view in the consumer that is not
+        // present in the incoming list.
+        //
+        // Every listItem was top-level, so it's entry's parent was ROOT_ENTRY, but now
+        // there are two possibilities:
+        //
+        //      1. It is not present in the entry list
+        //          1a. It has moved to be a child in the entry list - transfer it
+        //          1b. It is gone completely - remove it
+        //      2. It is present in the entry list - diff the children
+        getListItems(listContainer)
+                .filter {
+                    // Ignore things that are showing the blocking helper
+                    !it.isBlockingHelperShowing
+                }
+                .forEach { listItem ->
+                    val noLongerTopLevel = listItem.entry.parent != ROOT_ENTRY
+                    val becameChild = noLongerTopLevel && listItem.entry.parent != null
+
+                    val idx = entries.indexOf(listItem.entry)
+
+                    if (noLongerTopLevel) {
+                        // Summaries won't become children; remove the whole group
+                        if (listItem.isSummaryWithChildren) {
+                            listItem.removeAllChildren()
+                        }
+
+                        if (becameChild) {
+                            // Top-level element is becoming a child, don't generate an animation
+                            listContainer.setChildTransferInProgress(true)
+                        }
+                        listContainer.removeListItem(listItem)
+                        listContainer.setChildTransferInProgress(false)
+                    } else if (entries[idx] is GroupEntry) {
+                        // A top-level entry exists. If it's a group, diff the children
+                        val groupChildren = (entries[idx] as GroupEntry).children
+                        listItem.notificationChildren?.forEach { listChild ->
+                            if (!groupChildren.contains(listChild.entry)) {
+                                listItem.removeChildNotification(listChild)
+
+                                // TODO: the old code only calls this if the notif is gone from
+                                // NEM.getActiveNotificationUnfiltered(). Do we care?
+                                listContainer.notifyGroupChildRemoved(
+                                        listChild.view, listChild.view.parent as ViewGroup)
+                            }
+                        }
+                    }
+                }
+    }
+
+    /** Convenience method for getting a sequence of [NotificationListItem]s */
+    private fun getListItems(container: SimpleNotificationListContainer):
+            Sequence<NotificationListItem> {
+        return (0 until container.getContainerChildCount()).asSequence()
+                .map { container.getContainerChildAt(it) }
+                .filterIsInstance<NotificationListItem>()
+    }
+
+    private fun attachRows(entries: List<ListEntry>) {
+
+        var orderChanged = false
+
+        // To attach rows we can use _this one weird trick_: if the intended view to add does not
+        // have a parent, then simply add it (and its children).
+        entries.forEach { entry ->
+            val listItem = rowRegistry.requireView(entry)
+
+            if (listItem.view.parent != null) {
+                listContainer.addListItem(listItem)
+                stabilityManager.notifyViewAddition(listItem.view)
+            }
+
+            if (entry is GroupEntry) {
+                for ((idx, childEntry) in entry.children.withIndex()) {
+                    val childListItem = rowRegistry.requireView(childEntry)
+                    // Child hasn't been added yet. add it!
+                    if (!listItem.notificationChildren.contains(childListItem)) {
+                        // TODO: old code here just Log.wtf()'d here. This might wreak havoc
+                        if (childListItem.view.parent != null) {
+                            throw IllegalStateException("trying to add a notification child that " +
+                                    "already has a parent. class: " +
+                                    "${childListItem.view.parent?.javaClass} " +
+                                    "\n child: ${childListItem.view}"
+                            )
+                        }
+
+                        listItem.addChildNotification(childListItem, idx)
+                        stabilityManager.notifyViewAddition(childListItem.view)
+                        listContainer.notifyGroupChildAdded(childListItem.view)
+                    }
+                }
+
+                // finally after removing and adding has been performed we can apply the order
+                orderChanged = orderChanged ||
+                        listItem.applyChildOrder(
+                                getChildListFromParent(entry),
+                                stabilityManager,
+                                null /*TODO: stability callback */
+                        )
+            }
+        }
+
+        if (orderChanged) {
+            listContainer.generateChildOrderChangedEvent()
+        }
+    }
+
+    private fun getChildListFromParent(parent: ListEntry): List<NotificationListItem> {
+        if (parent is GroupEntry) {
+            return parent.children.map { child -> rowRegistry.requireView(child) }
+                    .toList()
+        }
+
+        return emptyList()
+    }
+
+    fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
+    }
+}
+
+private const val TAG = "NotifViewDataSource"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 5b73b1a..f7d6cef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -319,7 +319,7 @@
         logParentingChanges();
         freeEmptyGroups();
 
-        // Step 6: Dispatch the new list, first to any listeners and then to the view layer
+        // Step 8: Dispatch the new list, first to any listeners and then to the view layer
         if (mIterationCount % 10 == 0) {
             mLogger.logFinalList(mNotifList);
         }
@@ -328,7 +328,7 @@
             mOnRenderListListener.onRenderList(mReadOnlyNotifList);
         }
 
-        // Step 7: We're done!
+        // Step 9: We're done!
         mLogger.logEndBuildList(mIterationCount);
         mPipelineState.setState(STATE_IDLE);
         mIterationCount++;
@@ -816,7 +816,7 @@
          * @param entries A read-only view into the current notif list. Note that this list is
          *                backed by the live list and will change in response to new pipeline runs.
          */
-        void onRenderList(List<ListEntry> entries);
+        void onRenderList(@NonNull List<ListEntry> entries);
     }
 
     private static final NotifSection sDefaultSection =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt
new file mode 100644
index 0000000..2dbe555
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.statusbar.notification.collection
+
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.statusbar.notification.stack.NotificationListItem
+
+/**
+ * Minimal interface of what [NotifViewManager] needs from [NotificationListContainer]
+ */
+interface SimpleNotificationListContainer {
+    /** Called to signify that a top-level element is becoming a child in the shade */
+    fun setChildTransferInProgress(b: Boolean)
+    /** Used to generate a list of [NotificationListItem] */
+    fun getContainerChildAt(i: Int): View
+    /** Similar to above */
+    fun getContainerChildCount(): Int
+    /** Remove a [NotificationListItem] from the container */
+    fun removeListItem(li: NotificationListItem)
+    /** Add a [NotificationListItem] to the container */
+    fun addListItem(li: NotificationListItem)
+    /** Allows [NotifViewManager] to notify the container about a group child removal */
+    fun notifyGroupChildRemoved(row: View, parent: ViewGroup)
+    /** Allows [NotifViewManager] to notify the container about a group child addition */
+    fun notifyGroupChildAdded(row: View)
+    /** [NotifViewManager] calls this when the order of the children changes */
+    fun generateChildOrderChangedEvent()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
new file mode 100644
index 0000000..573c129
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
@@ -0,0 +1,171 @@
+/*
+ * 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.statusbar.notification.collection.coordinator;
+
+import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
+
+import android.annotation.Nullable;
+
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.notification.collection.ListEntry;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Coordinates heads up notification (HUN) interactions with the notification pipeline based on
+ * the HUN state reported by the {@link HeadsUpManager}. In this class we only consider one
+ * notification, in particular the {@link HeadsUpManager#getTopEntry()}, to be HeadsUpping at a
+ * time even though other notifications may be queued to heads up next.
+ *
+ * The current HUN, but not HUNs that are queued to heads up, will be:
+ * - Lifetime extended until it's no longer heads upping.
+ * - Promoted out of its group if it's a child of a group.
+ * - In the HeadsUpCoordinatorSection. Ordering is configured in {@link NotifCoordinators}.
+ * - Removed from HeadsUpManager if it's removed from the NotificationCollection.
+ *
+ * Note: The inflation callback in {@link PreparationCoordinator} handles showing HUNs.
+ */
+@Singleton
+public class HeadsUpCoordinator implements Coordinator {
+    private static final String TAG = "HeadsUpCoordinator";
+
+    private final HeadsUpManager mHeadsUpManager;
+    private final NotificationRemoteInputManager mRemoteInputManager;
+
+    // tracks the current HeadUpNotification reported by HeadsUpManager
+    private @Nullable NotificationEntry mCurrentHun;
+
+    private NotifLifetimeExtender.OnEndLifetimeExtensionCallback mEndLifetimeExtension;
+    private NotificationEntry mNotifExtendingLifetime; // notif we've extended the lifetime for
+
+    @Inject
+    public HeadsUpCoordinator(
+            HeadsUpManager headsUpManager,
+            NotificationRemoteInputManager remoteInputManager) {
+        mHeadsUpManager = headsUpManager;
+        mRemoteInputManager = remoteInputManager;
+    }
+
+    @Override
+    public void attach(NotifPipeline pipeline) {
+        mHeadsUpManager.addListener(mOnHeadsUpChangedListener);
+        pipeline.addCollectionListener(mNotifCollectionListener);
+        pipeline.addPromoter(mNotifPromoter);
+        pipeline.addNotificationLifetimeExtender(mLifetimeExtender);
+    }
+
+    @Override
+    public NotifSection getSection() {
+        return mNotifSection;
+    }
+
+    private final NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() {
+        /**
+         * Stop alerting HUNs that are removed from the notification collection
+         */
+        @Override
+        public void onEntryRemoved(NotificationEntry entry, int reason) {
+            final String entryKey = entry.getKey();
+            if (mHeadsUpManager.isAlerting(entryKey)) {
+                boolean removeImmediatelyForRemoteInput =
+                        mRemoteInputManager.getController().isSpinning(entryKey)
+                                && !FORCE_REMOTE_INPUT_HISTORY;
+                mHeadsUpManager.removeNotification(entry.getKey(), removeImmediatelyForRemoteInput);
+            }
+        }
+    };
+
+    private final NotifLifetimeExtender mLifetimeExtender = new NotifLifetimeExtender() {
+        @Override
+        public String getName() {
+            return TAG;
+        }
+
+        @Override
+        public void setCallback(OnEndLifetimeExtensionCallback callback) {
+            mEndLifetimeExtension = callback;
+        }
+
+        @Override
+        public boolean shouldExtendLifetime(NotificationEntry entry, int reason) {
+            boolean isShowingHun = isCurrentlyShowingHun(entry);
+            if (isShowingHun) {
+                mNotifExtendingLifetime = entry;
+            }
+            return isShowingHun;
+        }
+
+        @Override
+        public void cancelLifetimeExtension(NotificationEntry entry) {
+            if (Objects.equals(mNotifExtendingLifetime, entry)) {
+                mNotifExtendingLifetime = null;
+            }
+        }
+    };
+
+    private final NotifPromoter mNotifPromoter = new NotifPromoter(TAG) {
+        @Override
+        public boolean shouldPromoteToTopLevel(NotificationEntry entry) {
+            return isCurrentlyShowingHun(entry);
+        }
+    };
+
+    private final NotifSection mNotifSection = new NotifSection(TAG) {
+        @Override
+        public boolean isInSection(ListEntry entry) {
+            return isCurrentlyShowingHun(entry);
+        }
+    };
+
+    private final OnHeadsUpChangedListener mOnHeadsUpChangedListener =
+            new OnHeadsUpChangedListener() {
+        @Override
+        public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
+            NotificationEntry newHUN = mHeadsUpManager.getTopEntry();
+            if (!Objects.equals(mCurrentHun, newHUN)) {
+                endNotifLifetimeExtension();
+                mCurrentHun = newHUN;
+                mNotifPromoter.invalidateList();
+                mNotifSection.invalidateList();
+            }
+        }
+    };
+
+    private boolean isCurrentlyShowingHun(ListEntry entry) {
+        return mCurrentHun == entry.getRepresentativeEntry();
+    }
+
+    private void endNotifLifetimeExtension() {
+        if (mNotifExtendingLifetime != null) {
+            mEndLifetimeExtension.onEndLifetimeExtension(
+                    mLifetimeExtender,
+                    mNotifExtendingLifetime);
+            mNotifExtendingLifetime = null;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
index 7a22d75..98104f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
@@ -49,6 +49,7 @@
     public NotifCoordinators(
             DumpManager dumpManager,
             FeatureFlags featureFlags,
+            HeadsUpCoordinator headsUpCoordinator,
             KeyguardCoordinator keyguardCoordinator,
             RankingCoordinator rankingCoordinator,
             ForegroundCoordinator foregroundCoordinator,
@@ -56,7 +57,6 @@
             BubbleCoordinator bubbleCoordinator,
             PreparationCoordinator preparationCoordinator) {
         dumpManager.registerDumpable(TAG, this);
-
         mCoordinators.add(new HideLocallyDismissedNotifsCoordinator());
         mCoordinators.add(keyguardCoordinator);
         mCoordinators.add(rankingCoordinator);
@@ -64,9 +64,10 @@
         mCoordinators.add(deviceProvisionedCoordinator);
         mCoordinators.add(bubbleCoordinator);
         if (featureFlags.isNewNotifPipelineRenderingEnabled()) {
+            mCoordinators.add(headsUpCoordinator);
             mCoordinators.add(preparationCoordinator);
         }
-        // TODO: add new Coordinators here! (b/145134683, b/112656837)
+        // TODO: add new Coordinators here! (b/112656837)
 
         // TODO: add the sections in a particular ORDER (HeadsUp < People < Alerting)
         for (Coordinator c : mCoordinators) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index ebecf18..742615c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -26,13 +26,16 @@
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotifViewBarn;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
 import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -57,21 +60,31 @@
     private final PreparationCoordinatorLogger mLogger;
     private final NotifInflater mNotifInflater;
     private final NotifInflationErrorManager mNotifErrorManager;
+    private final NotifViewBarn mViewBarn;
     private final Map<NotificationEntry, Integer> mInflationStates = new ArrayMap<>();
     private final IStatusBarService mStatusBarService;
+    private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
+    private final HeadsUpManager mHeadsUpManager;
 
     @Inject
     public PreparationCoordinator(
             PreparationCoordinatorLogger logger,
             NotifInflaterImpl notifInflater,
             NotifInflationErrorManager errorManager,
-            IStatusBarService service) {
+            NotifViewBarn viewBarn,
+            IStatusBarService service,
+            NotificationInterruptStateProvider notificationInterruptStateProvider,
+            HeadsUpManager headsUpManager
+    ) {
         mLogger = logger;
         mNotifInflater = notifInflater;
         mNotifInflater.setInflationCallback(mInflationCallback);
         mNotifErrorManager = errorManager;
         mNotifErrorManager.addInflationErrorListener(mInflationErrorListener);
+        mViewBarn = viewBarn;
         mStatusBarService = service;
+        mNotificationInterruptStateProvider = notificationInterruptStateProvider;
+        mHeadsUpManager = headsUpManager;
     }
 
     @Override
@@ -109,6 +122,7 @@
         @Override
         public void onEntryCleanUp(NotificationEntry entry) {
             mInflationStates.remove(entry);
+            mViewBarn.removeViewForEntry(entry);
         }
     };
 
@@ -142,7 +156,13 @@
         @Override
         public void onInflationFinished(NotificationEntry entry) {
             mLogger.logNotifInflated(entry.getKey());
+            mViewBarn.registerViewForEntry(entry, entry.getRow());
             mInflationStates.put(entry, STATE_INFLATED);
+
+            // TODO: should eventually be moved to HeadsUpCoordinator
+            if (mNotificationInterruptStateProvider.shouldHeadsUp(entry)) {
+                mHeadsUpManager.showNotification(entry);
+            }
             mNotifInflatingFilter.invalidateList();
         }
     };
@@ -151,6 +171,7 @@
             new NotifInflationErrorManager.NotifInflationErrorListener() {
         @Override
         public void onNotifInflationError(NotificationEntry entry, Exception e) {
+            mViewBarn.removeViewForEntry(entry);
             mInflationStates.put(entry, STATE_ERROR);
             try {
                 final StatusBarNotification sbn = entry.getSbn();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/FakePipelineConsumer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/FakePipelineConsumer.java
deleted file mode 100644
index 15f312d..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/FakePipelineConsumer.java
+++ /dev/null
@@ -1,85 +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 com.android.systemui.statusbar.notification.collection.init;
-
-import com.android.systemui.Dumpable;
-import com.android.systemui.statusbar.notification.collection.GroupEntry;
-import com.android.systemui.statusbar.notification.collection.ListEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Temporary class that tracks the result of the list builder and dumps it to text when requested.
- *
- * Eventually, this will be something that hands off the result of the pipeline to the View layer.
- */
-public class FakePipelineConsumer implements Dumpable {
-    private List<ListEntry> mEntries = Collections.emptyList();
-
-    /** Attach the consumer to the pipeline. */
-    public void attach(ShadeListBuilder listBuilder) {
-        listBuilder.setOnRenderListListener(this::onBuildComplete);
-    }
-
-    private void onBuildComplete(List<ListEntry> entries) {
-        mEntries = entries;
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println();
-        pw.println("Active notif tree:");
-        for (int i = 0; i < mEntries.size(); i++) {
-            ListEntry entry = mEntries.get(i);
-            if (entry instanceof GroupEntry) {
-                GroupEntry ge = (GroupEntry) entry;
-                pw.println(dumpGroup(ge, "", i));
-
-                pw.println(dumpEntry(ge.getSummary(), INDENT, -1));
-                for (int j = 0; j < ge.getChildren().size(); j++) {
-                    pw.println(dumpEntry(ge.getChildren().get(j), INDENT, j));
-                }
-            } else {
-                pw.println(dumpEntry(entry.getRepresentativeEntry(), "", i));
-            }
-        }
-    }
-
-    private String dumpGroup(GroupEntry entry, String indent, int index) {
-        return String.format(
-                "%s[%d] %s (group)",
-                indent,
-                index,
-                entry.getKey());
-    }
-
-    private String dumpEntry(NotificationEntry entry, String indent, int index) {
-        return String.format(
-                "%s[%s] %s (channel=%s)",
-                indent,
-                index == -1 ? "*" : Integer.toString(index),
-                entry.getKey(),
-                entry.getChannel() != null ? entry.getChannel().getId() : "");
-    }
-
-    private static final String INDENT = "   ";
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
index 258f6d0..f150257 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
@@ -25,10 +25,12 @@
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
 import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotifViewManager;
 import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
 import com.android.systemui.statusbar.notification.collection.coalescer.GroupCoalescer;
 import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -50,7 +52,7 @@
     private final DumpManager mDumpManager;
     private final FeatureFlags mFeatureFlags;
 
-    private final FakePipelineConsumer mFakePipelineConsumer = new FakePipelineConsumer();
+    private final NotifViewManager mNotifViewManager;
 
     @Inject
     public NotifPipelineInitializer(
@@ -61,7 +63,8 @@
             NotifCoordinators notifCoordinators,
             NotifInflaterImpl notifInflater,
             DumpManager dumpManager,
-            FeatureFlags featureFlags) {
+            FeatureFlags featureFlags,
+            NotifViewManager notifViewManager) {
         mPipelineWrapper = pipelineWrapper;
         mGroupCoalescer = groupCoalescer;
         mNotifCollection = notifCollection;
@@ -70,12 +73,14 @@
         mDumpManager = dumpManager;
         mNotifInflater = notifInflater;
         mFeatureFlags = featureFlags;
+        mNotifViewManager = notifViewManager;
     }
 
     /** Hooks the new pipeline up to NotificationManager */
     public void initialize(
             NotificationListener notificationService,
-            NotificationRowBinderImpl rowBinder) {
+            NotificationRowBinderImpl rowBinder,
+            NotificationListContainer listContainer) {
 
         mDumpManager.registerDumpable("NotifPipeline", this);
 
@@ -88,7 +93,8 @@
         mNotifPluggableCoordinators.attach(mPipelineWrapper);
 
         // Wire up pipeline
-        mFakePipelineConsumer.attach(mListBuilder);
+        mNotifViewManager.setViewConsumer(listContainer);
+        mNotifViewManager.attach(mListBuilder);
         mListBuilder.attach(mNotifCollection);
         mNotifCollection.attach(mGroupCoalescer);
         mGroupCoalescer.attach(notificationService);
@@ -98,7 +104,7 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        mFakePipelineConsumer.dump(fd, pw, args);
+        mNotifViewManager.dump(fd, pw, args);
         mNotifPluggableCoordinators.dump(fd, pw, args);
         mGroupCoalescer.dump(fd, pw, args);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 8a6d5c7..7a7178c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -94,7 +94,10 @@
         notifBindPipelineInitializer.initialize()
 
         if (featureFlags.isNewNotifPipelineEnabled) {
-            newNotifPipeline.get().initialize(notificationListener, notificationRowBinder)
+            newNotifPipeline.get().initialize(
+                    notificationListener,
+                    notificationRowBinder,
+                    listContainer)
         }
 
         if (featureFlags.isNewNotifPipelineRenderingEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index ea1bdd6..b9dd974 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -271,6 +271,10 @@
         }
     }
 
+    public boolean isActive() {
+        return mActivated;
+    }
+
     private void startActivateAnimation(final boolean reverse) {
         if (!isAttachedToWindow()) {
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
index 2643ec9..2f0e433 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
@@ -111,7 +111,7 @@
             if (mNeedsDimming && ev.getActionMasked() == MotionEvent.ACTION_DOWN
                     && mView.disallowSingleClick(ev)
                     && !mAccessibilityManager.isTouchExplorationEnabled()) {
-                if (!mView.isActivated()) {
+                if (!mView.isActive()) {
                     return true;
                 } else if (!mDoubleTapHelper.isWithinDoubleTapSlop(ev)) {
                     mBlockNextTouch = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index b1db5b5..5f2b256 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -94,6 +94,7 @@
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationListItem;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.SwipeableView;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -115,7 +116,8 @@
  * the group summary (which contains 1 or more child notifications).
  */
 public class ExpandableNotificationRow extends ActivatableNotificationView
-        implements PluginListener<NotificationMenuRowPlugin>, SwipeableView {
+        implements PluginListener<NotificationMenuRowPlugin>, SwipeableView,
+        NotificationListItem {
 
     private static final boolean DEBUG = false;
     private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
@@ -666,6 +668,7 @@
         layout.setHeights(minHeight, headsUpHeight, mNotificationMaxHeight);
     }
 
+    @NonNull
     public NotificationEntry getEntry() {
         return mEntry;
     }
@@ -767,6 +770,17 @@
         row.setIsChildInGroup(true, this);
     }
 
+    /**
+     * Same as {@link #addChildNotification(ExpandableNotificationRow, int)}, but takes a
+     * {@link NotificationListItem} instead
+     *
+     * @param childItem item
+     * @param childIndex index
+     */
+    public void addChildNotification(NotificationListItem childItem, int childIndex) {
+        addChildNotification((ExpandableNotificationRow) childItem.getView(), childIndex);
+    }
+
     public void removeChildNotification(ExpandableNotificationRow row) {
         if (mChildrenContainer != null) {
             mChildrenContainer.removeNotification(row);
@@ -777,6 +791,11 @@
     }
 
     @Override
+    public void removeChildNotification(NotificationListItem child) {
+        removeChildNotification((ExpandableNotificationRow) child.getView());
+    }
+
+    @Override
     public boolean isChildInGroup() {
         return mNotificationParent != null;
     }
@@ -879,7 +898,7 @@
      * @param callback the callback to invoked in case it is not allowed
      * @return whether the list order has changed
      */
-    public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
+    public boolean applyChildOrder(List<? extends NotificationListItem> childOrder,
             VisualStabilityManager visualStabilityManager,
             VisualStabilityManager.Callback callback) {
         return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder,
@@ -1274,6 +1293,11 @@
         onChildrenCountChanged();
     }
 
+    @Override
+    public View getView() {
+        return this;
+    }
+
     public void setForceUnlocked(boolean forceUnlocked) {
         mForceUnlocked = forceUnlocked;
         if (mIsSummaryWithChildren) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
index 1e2571b5..162786c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
@@ -40,6 +40,7 @@
     private var conversationIcon: View? = null
     private var conversationBadge: View? = null
     private var expandButton: View? = null
+    private lateinit var expandButtonContainer: View
     private var messagingLinearLayout: MessagingLinearLayout? = null
 
     init {
@@ -56,6 +57,8 @@
                 com.android.internal.R.id.conversation_icon_badge)
         expandButton = conversationLayout.requireViewById(
                 com.android.internal.R.id.expand_button)
+        expandButtonContainer = conversationLayout.requireViewById(
+                com.android.internal.R.id.expand_button_container)
     }
 
     override fun onContentUpdated(row: ExpandableNotificationRow) {
@@ -90,6 +93,14 @@
         conversationLayout.updateExpandability(expandable, onClickListener)
     }
 
+    override fun disallowSingleClick(x: Float, y: Float): Boolean {
+        if (expandButtonContainer.visibility == View.VISIBLE
+                && isOnView(expandButtonContainer, x, y)) {
+            return true
+        }
+        return super.disallowSingleClick(x, y)
+    }
+
     override fun getMinLayoutHeight(): Int {
         if (mActionsContainer != null && mActionsContainer.visibility != View.GONE) {
             return minHeightWithActions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index d41f5af..2d99ab1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -58,7 +58,6 @@
     private TextView mText;
     protected View mActionsContainer;
     private ImageView mReplyAction;
-    private Rect mTmpRect = new Rect();
 
     private int mContentHeight;
     private int mMinHeightHint;
@@ -271,18 +270,6 @@
         return super.disallowSingleClick(x, y);
     }
 
-    private boolean isOnView(View view, float x, float y) {
-        View searchView = (View) view.getParent();
-        while (searchView != null && !(searchView instanceof ExpandableNotificationRow)) {
-            searchView.getHitRect(mTmpRect);
-            x -= mTmpRect.left;
-            y -= mTmpRect.top;
-            searchView = (View) searchView.getParent();
-        }
-        view.getHitRect(mTmpRect);
-        return mTmpRect.contains((int) x,(int) y);
-    }
-
     @Override
     public void onContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index c834e4b..46d7d93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -24,6 +24,7 @@
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
+import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
@@ -49,6 +50,7 @@
 
     protected final View mView;
     protected final ExpandableNotificationRow mRow;
+    private final Rect mTmpRect = new Rect();
 
     protected int mBackgroundColor = 0;
 
@@ -305,6 +307,26 @@
         return false;
     }
 
+    /**
+     * Is a given x and y coordinate on a view.
+     *
+     * @param view the view to be checked
+     * @param x the x coordinate, relative to the ExpandableNotificationRow
+     * @param y the y coordinate, relative to the ExpandableNotificationRow
+     * @return {@code true} if it is on the view
+     */
+    protected boolean isOnView(View view, float x, float y) {
+        View searchView = (View) view.getParent();
+        while (searchView != null && !(searchView instanceof ExpandableNotificationRow)) {
+            searchView.getHitRect(mTmpRect);
+            x -= mTmpRect.left;
+            y -= mTmpRect.top;
+            searchView = (View) searchView.getParent();
+        }
+        view.getHitRect(mTmpRect);
+        return mTmpRect.contains((int) x,(int) y);
+    }
+
     public int getMinLayoutHeight() {
         return 0;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index d7c88e3..2c17764 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -412,7 +412,7 @@
      * @param callback
      * @return whether the list order has changed
      */
-    public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
+    public boolean applyChildOrder(List<? extends NotificationListItem> childOrder,
             VisualStabilityManager visualStabilityManager,
             VisualStabilityManager.Callback callback) {
         if (childOrder == null) {
@@ -421,7 +421,7 @@
         boolean result = false;
         for (int i = 0; i < mChildren.size() && i < childOrder.size(); i++) {
             ExpandableNotificationRow child = mChildren.get(i);
-            ExpandableNotificationRow desiredChild = childOrder.get(i);
+            ExpandableNotificationRow desiredChild = (ExpandableNotificationRow) childOrder.get(i);
             if (child != desiredChild) {
                 if (visualStabilityManager.canReorderNotification(desiredChild)) {
                     mChildren.remove(desiredChild);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index 15cc72c..c4a720c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -18,12 +18,14 @@
 
 import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
 
+import android.annotation.NonNull;
 import android.view.View;
 import android.view.ViewGroup;
 
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.SimpleNotificationListContainer;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -33,7 +35,7 @@
  * notification views added and removed from it, and will manage displaying them to the user.
  */
 public interface NotificationListContainer extends ExpandableView.OnHeightChangedListener,
-        VisibilityLocationProvider {
+        VisibilityLocationProvider, SimpleNotificationListContainer {
 
     /**
      * Called when a child is being transferred.
@@ -186,4 +188,10 @@
     }
 
     default void setWillExpand(boolean willExpand) {};
+
+    /**
+     * Remove a list item from the container
+     * @param v the item to remove
+     */
+    void removeListItem(@NonNull NotificationListItem v);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java
new file mode 100644
index 0000000..8991abe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java
@@ -0,0 +1,66 @@
+/*
+ * 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.statusbar.notification.stack;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.view.View;
+
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import java.util.List;
+
+/**
+* A NotificationListItem is a child view of the notification list that can yield a
+* NotificationEntry when asked. I.e., it's an ExpandableNotificationRow but doesn't require us
+* to strictly rely on ExpandableNotificationRow as our consumed type
+ */
+public interface NotificationListItem {
+    /** @return entry for this item */
+    @NonNull
+    NotificationEntry getEntry();
+
+    /** @return true if the blocking helper is showing */
+    boolean isBlockingHelperShowing();
+
+    /** @return true if this list item is a summary with children */
+    boolean isSummaryWithChildren();
+
+    // This generic is kind of ugly - we should change this once the old VHM is gone
+    /** @return list of the children of this item */
+    List<? extends NotificationListItem> getNotificationChildren();
+
+    /** remove all children from this list item */
+    void removeAllChildren();
+
+    /** remove particular child */
+    void removeChildNotification(NotificationListItem child);
+
+    /** add an item as a child */
+    void addChildNotification(NotificationListItem child, int childIndex);
+
+    /** Update the order of the children with the new list */
+    boolean applyChildOrder(
+            List<? extends NotificationListItem> childOrderList,
+            VisualStabilityManager vsm,
+            @Nullable VisualStabilityManager.Callback callback);
+
+    /** return the associated view for this list item */
+    @NonNull
+    View getView();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index cfcbd88..4d4a2ded 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -3323,11 +3323,21 @@
     }
 
     @Override
+    public void notifyGroupChildRemoved(View child, ViewGroup parent) {
+        notifyGroupChildRemoved((ExpandableView) child, parent);
+    }
+
+    @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void notifyGroupChildAdded(ExpandableView row) {
         onViewAddedInternal(row);
     }
 
+    @Override
+    public void notifyGroupChildAdded(View view) {
+        notifyGroupChildAdded((ExpandableView) view);
+    }
+
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     public void setAnimationsEnabled(boolean animationsEnabled) {
         mAnimationsEnabled = animationsEnabled;
@@ -5137,11 +5147,22 @@
 
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    public void removeListItem(NotificationListItem v) {
+        removeContainerView(v.getView());
+    }
+
+    @Override
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void addContainerView(View v) {
         Assert.isMainThread();
         addView(v);
     }
 
+    @Override
+    public void addListItem(NotificationListItem v) {
+        addContainerView(v.getView());
+    }
+
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void runAfterAnimationFinished(Runnable runnable) {
         mAnimationFinishedRunnables.add(runnable);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index c282cb8..0b747f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -114,8 +114,9 @@
                     mInitialTouchY = y;
                     int startHeight = (int) (mPickedChild.getActualHeight()
                                                 + mPickedChild.getTranslationY());
-                    mPanel.setPanelScrimMinFraction((float) startHeight
-                            / mPanel.getMaxPanelHeight());
+                    float maxPanelHeight = mPanel.getMaxPanelHeight();
+                    mPanel.setPanelScrimMinFraction(maxPanelHeight > 0f
+                            ? (float) startHeight / maxPanelHeight : 0f);
                     mPanel.startExpandMotion(x, y, true /* startTracking */, startHeight);
                     mPanel.startExpandingFromPeek();
                     // This call needs to be after the expansion start otherwise we will get a
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 77337e9..ccf6707 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -398,8 +398,7 @@
         NotificationGroup group = mGroupMap.get(groupKey);
         //TODO: see if this can become an Entry
         return group == null ? null
-                : group.summary == null ? null
-                        : group.summary;
+                : group.summary;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index c61d7bb..f9726d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1844,7 +1844,14 @@
         } else {
             maxHeight = calculatePanelHeightShade();
         }
-        maxHeight = Math.max(maxHeight, min);
+        maxHeight = Math.max(min, maxHeight);
+        if (maxHeight == 0) {
+            Log.wtf(TAG, "maxPanelHeight is 0. getOverExpansionAmount(): "
+                    + getOverExpansionAmount() + ", calculatePanelHeightQsExpanded: "
+                    + calculatePanelHeightQsExpanded() + ", calculatePanelHeightShade: "
+                    + calculatePanelHeightShade() + ", mStatusBarMinHeight = "
+                    + mStatusBarMinHeight + ", mQsMinExpansionHeight = " + mQsMinExpansionHeight);
+        }
         return maxHeight;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 8d8c8da..c106518 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static java.lang.Float.isNaN;
+
 import android.content.Context;
 import android.os.Bundle;
 import android.os.Parcelable;
@@ -161,6 +163,9 @@
      *                 fraction as the panel also might be expanded if the fraction is 0
      */
     public void panelExpansionChanged(float frac, boolean expanded) {
+        if (isNaN(frac)) {
+            throw new IllegalArgumentException("frac cannot be NaN");
+        }
         boolean fullyClosed = true;
         boolean fullyOpened = false;
         if (SPEW) LOG("panelExpansionChanged: start state=%d", mState);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index e25c14c..1c1e7c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -18,6 +18,8 @@
 
 import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
 
+import static java.lang.Float.isNaN;
+
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -254,6 +256,9 @@
 
     @Override
     public void panelScrimMinFractionChanged(float minFraction) {
+        if (isNaN(minFraction)) {
+            throw new IllegalArgumentException("minFraction cannot be NaN");
+        }
         if (mMinFraction != minFraction) {
             mMinFraction = minFraction;
             updateScrimFraction();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index 7d532a8..38c165b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -65,7 +65,6 @@
             new TetheringManager.TetheringEventCallback() {
                 @Override
                 public void onTetheringSupported(boolean supported) {
-                    super.onTetheringSupported(supported);
                     if (mIsTetheringSupported != supported) {
                         mIsTetheringSupported = supported;
                         fireHotspotAvailabilityChanged();
@@ -75,7 +74,6 @@
                 @Override
                 public void onTetherableInterfaceRegexpsChanged(
                         TetheringManager.TetheringInterfaceRegexps reg) {
-                    super.onTetherableInterfaceRegexpsChanged(reg);
                     final boolean newValue = reg.getTetherableWifiRegexs().size() != 0;
                     if (mHasTetherableWifiRegexs != newValue) {
                         mHasTetherableWifiRegexs = newValue;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index a36f2c7..bb2eea9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -31,6 +31,7 @@
 import androidx.test.InstrumentationRegistry;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.FalsingManager;
 
@@ -80,6 +81,9 @@
         // None of them actually need it.
         mDependency.injectTestDependency(FalsingManager.class, new FalsingManagerFake());
         mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
+
+        // TODO: b/151614195 investigate root cause of needing this mock dependency
+        mDependency.injectMockDependency(LocalBluetoothManager.class);
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
new file mode 100644
index 0000000..4d7e6ae
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.pip.phone;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.util.Size;
+import android.view.DisplayInfo;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.pip.PipBoundsHandler;
+import com.android.systemui.pip.PipSnapAlgorithm;
+import com.android.systemui.pip.PipTaskOrganizer;
+import com.android.systemui.shared.system.InputConsumerController;
+import com.android.systemui.util.DeviceConfigProxy;
+import com.android.systemui.util.FloatingContentCoordinator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests against {@link PipTouchHandler}, including but not limited to:
+ * - Update movement bounds based on new bounds
+ * - Update movement bounds based on IME/shelf
+ * - Update movement bounds to PipResizeHandler
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class PipTouchHandlerTest extends SysuiTestCase {
+    private static final int ROUNDING_ERROR_MARGIN = 10;
+    private static final float DEFAULT_ASPECT_RATIO = 1f;
+    private static final Rect EMPTY_CURRENT_BOUNDS = null;
+
+    private PipTouchHandler mPipTouchHandler;
+    private DisplayInfo mDefaultDisplayInfo;
+
+    @Mock
+    private IActivityManager mActivityManager;
+
+    @Mock
+    private IActivityTaskManager mIActivityTaskManager;
+
+    @Mock
+    private PipMenuActivityController mPipMenuActivityController;
+
+    @Mock
+    private InputConsumerController mInputConsumerController;
+
+    @Mock
+    private PipBoundsHandler mPipBoundsHandler;
+
+    @Mock
+    private PipTaskOrganizer mPipTaskOrganizer;
+
+    @Mock
+    private FloatingContentCoordinator mFloatingContentCoordinator;
+
+    @Mock
+    private DeviceConfigProxy mDeviceConfigProxy;
+
+
+    private PipSnapAlgorithm mPipSnapAlgorithm;
+    private PipMotionHelper mMotionHelper;
+    private PipResizeGestureHandler mPipResizeGestureHandler;
+
+    Rect mInsetBounds;
+    Rect mMinBounds;
+    Rect mCurBounds;
+    boolean mFromImeAdjustment;
+    boolean mFromShelfAdjustment;
+    int mDisplayRotation;
+
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mPipSnapAlgorithm = new PipSnapAlgorithm(mContext);
+        mPipTouchHandler = new PipTouchHandler(mContext, mActivityManager, mIActivityTaskManager,
+                mPipMenuActivityController, mInputConsumerController, mPipBoundsHandler,
+                mPipTaskOrganizer, mFloatingContentCoordinator, mDeviceConfigProxy,
+                mPipSnapAlgorithm);
+        mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper());
+        mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler());
+        mPipTouchHandler.setPipMotionHelper(mMotionHelper);
+        mPipTouchHandler.setPipResizeGestureHandler(mPipResizeGestureHandler);
+
+        // Assume a display of 1000 x 1000
+        // inset of 10
+        mInsetBounds = new Rect(10, 10, 990, 990);
+        // minBounds of 100x100 bottom right corner
+        mMinBounds = new Rect(890, 890, 990, 990);
+        mCurBounds = new Rect();
+        mFromImeAdjustment = false;
+        mFromShelfAdjustment = false;
+        mDisplayRotation = 0;
+    }
+
+    @Test
+    public void updateMovementBounds_minBounds() {
+        Rect expectedMinMovementBounds = new Rect();
+        mPipSnapAlgorithm.getMovementBounds(mMinBounds, mInsetBounds, expectedMinMovementBounds, 0);
+
+        mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
+                mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
+
+        assertEquals(expectedMinMovementBounds, mPipTouchHandler.mNormalMovementBounds);
+        verify(mPipResizeGestureHandler, times(1))
+                .updateMinSize(mMinBounds.width(), mMinBounds.height());
+    }
+
+    @Test
+    public void updateMovementBounds_maxBounds() {
+        Point displaySize = new Point();
+        mContext.getDisplay().getRealSize(displaySize);
+        Size maxSize = mPipSnapAlgorithm.getSizeForAspectRatio(1,
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.pip_expanded_shortest_edge_size), displaySize.x, displaySize.y);
+        Rect maxBounds = new Rect(0, 0, maxSize.getWidth(), maxSize.getHeight());
+        Rect expectedMaxMovementBounds = new Rect();
+        mPipSnapAlgorithm.getMovementBounds(maxBounds, mInsetBounds, expectedMaxMovementBounds, 0);
+
+        mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
+                mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
+
+        assertEquals(expectedMaxMovementBounds, mPipTouchHandler.mExpandedMovementBounds);
+        verify(mPipResizeGestureHandler, times(1))
+                .updateMaxSize(maxBounds.width(), maxBounds.height());
+    }
+
+    @Test
+    public void updateMovementBounds_withImeAdjustment_movesPip() {
+        mFromImeAdjustment = true;
+        mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
+                mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
+
+        verify(mMotionHelper, times(1)).animateToOffset(any(), anyInt());
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index ac30421..dbbbaac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -85,6 +85,8 @@
     @Mock
     private NotificationMediaManager mNotificationMediaManager;
     @Mock
+    private Executor mForegroundExecutor;
+    @Mock
     private Executor mBackgroundExecutor;
     @Mock
     private LocalBluetoothManager mLocalBluetoothManager;
@@ -97,7 +99,7 @@
         mTestableLooper.runWithLooper(() -> {
             mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
             mQsPanel = new QSPanel(mContext, null, mDumpManager, mBroadcastDispatcher,
-                    mQSLogger, mNotificationMediaManager, mBackgroundExecutor,
+                    mQSLogger, mNotificationMediaManager, mForegroundExecutor, mBackgroundExecutor,
                     mLocalBluetoothManager);
             // Provides a parent with non-zero size for QSPanel
             mParentView = new FrameLayout(mContext);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index cc5f149..83877f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -52,6 +52,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationListItem;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 
@@ -285,9 +286,15 @@
         public void notifyGroupChildAdded(ExpandableView row) {}
 
         @Override
+        public void notifyGroupChildAdded(View v) {}
+
+        @Override
         public void notifyGroupChildRemoved(ExpandableView row, ViewGroup childrenContainer) {}
 
         @Override
+        public void notifyGroupChildRemoved(View v, ViewGroup childrenContainer) {}
+
+        @Override
         public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {}
 
         @Override
@@ -313,12 +320,22 @@
         }
 
         @Override
+        public void removeListItem(NotificationListItem li) {
+            removeContainerView(li.getView());
+        }
+
+        @Override
         public void addContainerView(View v) {
             mLayout.addView(v);
             mRows.add(v);
         }
 
         @Override
+        public void addListItem(NotificationListItem li) {
+            addContainerView(li.getView());
+        }
+
+        @Override
         public void setMaxDisplayedNotifications(int maxNotifications) {
             if (mMakeReentrantCallDuringSetMaxDisplayedNotifications) {
                 mViewHierarchyManager.onDynamicPrivacyChanged();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java
new file mode 100644
index 0000000..0c109c4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java
@@ -0,0 +1,191 @@
+/*
+ * 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.statusbar.notification.collection.coordinator;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.RemoteInputController;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class HeadsUpCoordinatorTest extends SysuiTestCase {
+
+    private HeadsUpCoordinator mCoordinator;
+
+    // captured listeners and pluggables:
+    private NotifCollectionListener mCollectionListener;
+    private NotifPromoter mNotifPromoter;
+    private NotifLifetimeExtender mNotifLifetimeExtender;
+    private OnHeadsUpChangedListener mOnHeadsUpChangedListener;
+    private NotifSection mNotifSection;
+
+    @Mock private NotifPipeline mNotifPipeline;
+    @Mock private HeadsUpManager mHeadsUpManager;
+    @Mock private NotificationRemoteInputManager mRemoteInputManager;
+    @Mock private RemoteInputController mRemoteInputController;
+    @Mock private NotifLifetimeExtender.OnEndLifetimeExtensionCallback mEndLifetimeExtension;
+
+    private NotificationEntry mEntry;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
+
+        mCoordinator = new HeadsUpCoordinator(
+                mHeadsUpManager,
+                mRemoteInputManager
+        );
+
+        mCoordinator.attach(mNotifPipeline);
+
+        // capture arguments:
+        ArgumentCaptor<NotifCollectionListener> notifCollectionCaptor =
+                ArgumentCaptor.forClass(NotifCollectionListener.class);
+        ArgumentCaptor<NotifPromoter> notifPromoterCaptor =
+                ArgumentCaptor.forClass(NotifPromoter.class);
+        ArgumentCaptor<NotifLifetimeExtender> notifLifetimeExtenderCaptor =
+                ArgumentCaptor.forClass(NotifLifetimeExtender.class);
+        ArgumentCaptor<OnHeadsUpChangedListener> headsUpChangedListenerCaptor =
+                ArgumentCaptor.forClass(OnHeadsUpChangedListener.class);
+
+        verify(mNotifPipeline).addCollectionListener(notifCollectionCaptor.capture());
+        verify(mNotifPipeline).addPromoter(notifPromoterCaptor.capture());
+        verify(mNotifPipeline).addNotificationLifetimeExtender(
+                notifLifetimeExtenderCaptor.capture());
+        verify(mHeadsUpManager).addListener(headsUpChangedListenerCaptor.capture());
+
+        mCollectionListener = notifCollectionCaptor.getValue();
+        mNotifPromoter = notifPromoterCaptor.getValue();
+        mNotifLifetimeExtender = notifLifetimeExtenderCaptor.getValue();
+        mOnHeadsUpChangedListener = headsUpChangedListenerCaptor.getValue();
+
+        mNotifSection = mCoordinator.getSection();
+        mNotifLifetimeExtender.setCallback(mEndLifetimeExtension);
+        mEntry = new NotificationEntryBuilder().build();
+    }
+
+    @Test
+    public void testPromotesCurrentHUN() {
+        // GIVEN the current HUN is set to mEntry
+        setCurrentHUN(mEntry);
+
+        // THEN only promote the current HUN, mEntry
+        assertTrue(mNotifPromoter.shouldPromoteToTopLevel(mEntry));
+        assertFalse(mNotifPromoter.shouldPromoteToTopLevel(new NotificationEntryBuilder().build()));
+    }
+
+    @Test
+    public void testIncludeInSectionCurrentHUN() {
+        // GIVEN the current HUN is set to mEntry
+        setCurrentHUN(mEntry);
+
+        // THEN only section the current HUN, mEntry
+        assertTrue(mNotifSection.isInSection(mEntry));
+        assertFalse(mNotifSection.isInSection(new NotificationEntryBuilder().build()));
+    }
+
+    @Test
+    public void testLifetimeExtendsCurrentHUN() {
+        // GIVEN there is a HUN, mEntry
+        setCurrentHUN(mEntry);
+
+        // THEN only the current HUN, mEntry, should be lifetimeExtended
+        assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(mEntry, /* cancellationReason */ 0));
+        assertFalse(mNotifLifetimeExtender.shouldExtendLifetime(
+                new NotificationEntryBuilder().build(), /* cancellationReason */ 0));
+    }
+
+    @Test
+    public void testLifetimeExtensionEndsOnNewHUN() {
+        // GIVEN there was a HUN that was lifetime extended
+        setCurrentHUN(mEntry);
+        assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(
+                mEntry, /* cancellation reason */ 0));
+
+        // WHEN there's a new HUN
+        NotificationEntry newHUN = new NotificationEntryBuilder().build();
+        setCurrentHUN(newHUN);
+
+        // THEN the old entry's lifetime extension should be cancelled
+        verify(mEndLifetimeExtension).onEndLifetimeExtension(mNotifLifetimeExtender, mEntry);
+    }
+
+    @Test
+    public void testLifetimeExtensionEndsOnNoHUNs() {
+        // GIVEN there was a HUN that was lifetime extended
+        setCurrentHUN(mEntry);
+        assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(
+                mEntry, /* cancellation reason */ 0));
+
+        // WHEN there's no longer a HUN
+        setCurrentHUN(null);
+
+        // THEN the old entry's lifetime extension should be cancelled
+        verify(mEndLifetimeExtension).onEndLifetimeExtension(mNotifLifetimeExtender, mEntry);
+    }
+
+    @Test
+    public void testOnEntryRemovedRemovesHeadsUpNotification() {
+        // GIVEN the current HUN is mEntry
+        setCurrentHUN(mEntry);
+
+        // WHEN mEntry is removed from the notification collection
+        mCollectionListener.onEntryRemoved(mEntry, /* cancellation reason */ 0);
+        when(mRemoteInputController.isSpinning(any())).thenReturn(false);
+
+        // THEN heads up manager should remove the entry
+        verify(mHeadsUpManager).removeNotification(mEntry.getKey(), false);
+    }
+
+    private void setCurrentHUN(NotificationEntry entry) {
+        when(mHeadsUpManager.getTopEntry()).thenReturn(entry);
+        when(mHeadsUpManager.isAlerting(any())).thenReturn(false);
+        if (entry != null) {
+            when(mHeadsUpManager.isAlerting(entry.getKey())).thenReturn(true);
+        }
+        mOnHeadsUpChangedListener.onHeadsUpStateChanged(entry, entry != null);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index 792b4d5..8143cf5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -20,8 +20,10 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.os.RemoteException;
 import android.testing.AndroidTestingRunner;
@@ -33,12 +35,15 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotifViewBarn;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -73,6 +78,8 @@
     @Mock private NotifPipeline mNotifPipeline;
     @Mock private IStatusBarService mService;
     @Mock private NotifInflaterImpl mNotifInflater;
+    @Mock private NotificationInterruptStateProvider mNotificationInterruptStateProvider;
+    @Mock private HeadsUpManager mHeadsUpManager;
 
     @Before
     public void setUp() {
@@ -86,7 +93,10 @@
                 mock(PreparationCoordinatorLogger.class),
                 mNotifInflater,
                 mErrorManager,
-                mService);
+                mock(NotifViewBarn.class),
+                mService,
+                mNotificationInterruptStateProvider,
+                mHeadsUpManager);
 
         ArgumentCaptor<NotifFilter> filterCaptor = ArgumentCaptor.forClass(NotifFilter.class);
         mCoordinator.attach(mNotifPipeline);
@@ -170,4 +180,24 @@
         // THEN it isn't filtered from shade list
         assertFalse(mUninflatedFilter.shouldFilterOut(mEntry, 0));
     }
+
+    @Test
+    public void testShowHUNOnInflationFinished() {
+        // WHEN a notification should HUN and its inflation is finished
+        when(mNotificationInterruptStateProvider.shouldHeadsUp(mEntry)).thenReturn(true);
+        mCallback.onInflationFinished(mEntry);
+
+        // THEN we tell the HeadsUpManager to show the notification
+        verify(mHeadsUpManager).showNotification(mEntry);
+    }
+
+    @Test
+    public void testNoHUNOnInflationFinished() {
+        // WHEN a notification shouldn't HUN and its inflation is finished
+        when(mNotificationInterruptStateProvider.shouldHeadsUp(mEntry)).thenReturn(false);
+        mCallback.onInflationFinished(mEntry);
+
+        // THEN we never tell the HeadsUpManager to show the notification
+        verify(mHeadsUpManager, never()).showNotification(mEntry);
+    }
 }
diff --git a/packages/Tethering/common/TetheringLib/api/current.txt b/packages/Tethering/common/TetheringLib/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/api/module-lib-current.txt b/packages/Tethering/common/TetheringLib/api/module-lib-current.txt
new file mode 100644
index 0000000..e25d77d
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/module-lib-current.txt
@@ -0,0 +1,126 @@
+// Signature format: 2.0
+package android.net {
+
+  public final class TetheredClient implements android.os.Parcelable {
+    ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
+    method public int describeContents();
+    method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
+    method @NonNull public android.net.MacAddress getMacAddress();
+    method public int getTetheringType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
+  }
+
+  public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.LinkAddress getAddress();
+    method @Nullable public String getHostname();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
+  }
+
+  public final class TetheringConstants {
+    field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
+    field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
+    field public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
+    field public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
+    field public static final String EXTRA_SET_ALARM = "extraSetAlarm";
+  }
+
+  public class TetheringManager {
+    ctor public TetheringManager(@NonNull android.content.Context, @NonNull java.util.function.Supplier<android.os.IBinder>);
+    method public int getLastTetherError(@NonNull String);
+    method @NonNull public String[] getTetherableBluetoothRegexs();
+    method @NonNull public String[] getTetherableIfaces();
+    method @NonNull public String[] getTetherableUsbRegexs();
+    method @NonNull public String[] getTetherableWifiRegexs();
+    method @NonNull public String[] getTetheredIfaces();
+    method @NonNull public String[] getTetheringErroredIfaces();
+    method public boolean isTetheringSupported();
+    method public boolean isTetheringSupported(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
+    method public void requestLatestTetheringEntitlementResult(int, @NonNull android.os.ResultReceiver, boolean);
+    method @Deprecated public int setUsbTethering(boolean);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
+    method @Deprecated public int tether(@NonNull String);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
+    method @Deprecated public int untether(@NonNull String);
+    field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
+    field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
+    field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
+    field public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
+    field public static final String EXTRA_ERRORED_TETHER = "erroredArray";
+    field public static final int TETHERING_BLUETOOTH = 2; // 0x2
+    field public static final int TETHERING_ETHERNET = 5; // 0x5
+    field public static final int TETHERING_INVALID = -1; // 0xffffffff
+    field public static final int TETHERING_NCM = 4; // 0x4
+    field public static final int TETHERING_USB = 1; // 0x1
+    field public static final int TETHERING_WIFI = 0; // 0x0
+    field public static final int TETHERING_WIFI_P2P = 3; // 0x3
+    field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
+    field public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; // 0x9
+    field public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; // 0x8
+    field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
+    field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
+    field public static final int TETHER_ERROR_MASTER_ERROR = 5; // 0x5
+    field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
+    field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
+    field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
+    field public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
+    field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
+    field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
+    field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
+    field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
+    field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
+    field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
+    field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
+    field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1
+    field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0
+  }
+
+  public static interface TetheringManager.OnTetheringEntitlementResultListener {
+    method public void onTetheringEntitlementResult(int);
+  }
+
+  public abstract static class TetheringManager.StartTetheringCallback {
+    ctor public TetheringManager.StartTetheringCallback();
+    method public void onTetheringFailed(int);
+    method public void onTetheringStarted();
+  }
+
+  public abstract static class TetheringManager.TetheringEventCallback {
+    ctor public TetheringManager.TetheringEventCallback();
+    method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
+    method public void onError(@NonNull String, int);
+    method public void onOffloadStatusChanged(int);
+    method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
+    method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public void onTetheringSupported(boolean);
+    method public void onUpstreamChanged(@Nullable android.net.Network);
+  }
+
+  @Deprecated public static class TetheringManager.TetheringInterfaceRegexps {
+    ctor @Deprecated public TetheringManager.TetheringInterfaceRegexps(@NonNull String[], @NonNull String[], @NonNull String[]);
+    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
+    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
+    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
+  }
+
+  public static class TetheringManager.TetheringRequest {
+  }
+
+  public static class TetheringManager.TetheringRequest.Builder {
+    ctor public TetheringManager.TetheringRequest.Builder(int);
+    method @NonNull public android.net.TetheringManager.TetheringRequest build();
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress);
+  }
+
+}
+
diff --git a/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt b/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/api/removed.txt b/packages/Tethering/common/TetheringLib/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/api/system-current.txt b/packages/Tethering/common/TetheringLib/api/system-current.txt
new file mode 100644
index 0000000..d6fcb62
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/system-current.txt
@@ -0,0 +1,104 @@
+// Signature format: 2.0
+package android.net {
+
+  public final class TetheredClient implements android.os.Parcelable {
+    ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
+    method public int describeContents();
+    method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
+    method @NonNull public android.net.MacAddress getMacAddress();
+    method public int getTetheringType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
+  }
+
+  public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.LinkAddress getAddress();
+    method @Nullable public String getHostname();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
+  }
+
+  public class TetheringManager {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
+    field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
+    field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
+    field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
+    field public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
+    field public static final String EXTRA_ERRORED_TETHER = "erroredArray";
+    field public static final int TETHERING_BLUETOOTH = 2; // 0x2
+    field public static final int TETHERING_ETHERNET = 5; // 0x5
+    field public static final int TETHERING_INVALID = -1; // 0xffffffff
+    field public static final int TETHERING_NCM = 4; // 0x4
+    field public static final int TETHERING_USB = 1; // 0x1
+    field public static final int TETHERING_WIFI = 0; // 0x0
+    field public static final int TETHERING_WIFI_P2P = 3; // 0x3
+    field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
+    field public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; // 0x9
+    field public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; // 0x8
+    field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
+    field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
+    field public static final int TETHER_ERROR_MASTER_ERROR = 5; // 0x5
+    field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
+    field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
+    field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
+    field public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
+    field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
+    field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
+    field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
+    field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
+    field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
+    field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
+    field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
+    field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1
+    field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0
+  }
+
+  public static interface TetheringManager.OnTetheringEntitlementResultListener {
+    method public void onTetheringEntitlementResult(int);
+  }
+
+  public abstract static class TetheringManager.StartTetheringCallback {
+    ctor public TetheringManager.StartTetheringCallback();
+    method public void onTetheringFailed(int);
+    method public void onTetheringStarted();
+  }
+
+  public abstract static class TetheringManager.TetheringEventCallback {
+    ctor public TetheringManager.TetheringEventCallback();
+    method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
+    method public void onError(@NonNull String, int);
+    method public void onOffloadStatusChanged(int);
+    method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
+    method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public void onTetheringSupported(boolean);
+    method public void onUpstreamChanged(@Nullable android.net.Network);
+  }
+
+  @Deprecated public static class TetheringManager.TetheringInterfaceRegexps {
+    ctor @Deprecated public TetheringManager.TetheringInterfaceRegexps(@NonNull String[], @NonNull String[], @NonNull String[]);
+    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
+    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
+    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
+  }
+
+  public static class TetheringManager.TetheringRequest {
+  }
+
+  public static class TetheringManager.TetheringRequest.Builder {
+    ctor public TetheringManager.TetheringRequest.Builder(int);
+    method @NonNull public android.net.TetheringManager.TetheringRequest build();
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress);
+  }
+
+}
+
diff --git a/packages/Tethering/common/TetheringLib/api/system-removed.txt b/packages/Tethering/common/TetheringLib/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java
index a402ffa..15cdb6a 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java
@@ -39,8 +39,7 @@
 import android.net.netlink.ConntrackMessage;
 import android.net.netlink.NetlinkConstants;
 import android.net.netlink.NetlinkSocket;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
 import android.net.util.SharedLog;
 import android.os.Handler;
 import android.provider.Settings;
@@ -89,8 +88,8 @@
     private final Handler mHandler;
     private final OffloadHardwareInterface mHwInterface;
     private final ContentResolver mContentResolver;
-    private final @NonNull OffloadTetheringStatsProvider mStatsProvider;
-    private final @Nullable NetworkStatsProviderCallback mStatsProviderCb;
+    @Nullable
+    private final OffloadTetheringStatsProvider mStatsProvider;
     private final SharedLog mLog;
     private final HashMap<String, LinkProperties> mDownstreams;
     private boolean mConfigInitialized;
@@ -124,19 +123,18 @@
         mHandler = h;
         mHwInterface = hwi;
         mContentResolver = contentResolver;
-        mStatsProvider = new OffloadTetheringStatsProvider();
         mLog = log.forSubComponent(TAG);
         mDownstreams = new HashMap<>();
         mExemptPrefixes = new HashSet<>();
         mLastLocalPrefixStrs = new HashSet<>();
-        NetworkStatsProviderCallback providerCallback = null;
+        OffloadTetheringStatsProvider provider = new OffloadTetheringStatsProvider();
         try {
-            providerCallback = nsm.registerNetworkStatsProvider(
-                    getClass().getSimpleName(), mStatsProvider);
+            nsm.registerNetworkStatsProvider(getClass().getSimpleName(), provider);
         } catch (RuntimeException e) {
             Log.wtf(TAG, "Cannot register offload stats provider: " + e);
+            provider = null;
         }
-        mStatsProviderCb = providerCallback;
+        mStatsProvider = provider;
     }
 
     /** Start hardware offload. */
@@ -185,7 +183,7 @@
                         // and we need to synchronize stats and limits between
                         // software and hardware forwarding.
                         updateStatsForAllUpstreams();
-                        mStatsProvider.pushTetherStats();
+                        if (mStatsProvider != null) mStatsProvider.pushTetherStats();
                     }
 
                     @Override
@@ -198,7 +196,7 @@
                         // limits set take into account any software tethering
                         // traffic that has been happening in the meantime.
                         updateStatsForAllUpstreams();
-                        mStatsProvider.pushTetherStats();
+                        if (mStatsProvider != null) mStatsProvider.pushTetherStats();
                         // [2] (Re)Push all state.
                         computeAndPushLocalPrefixes(UpdateType.FORCE);
                         pushAllDownstreamState();
@@ -217,10 +215,12 @@
                         // TODO: rev the HAL so that it provides an interface name.
 
                         updateStatsForCurrentUpstream();
-                        mStatsProvider.pushTetherStats();
-                        // Push stats to service does not cause the service react to it immediately.
-                        // Inform the service about limit reached.
-                        if (mStatsProviderCb != null) mStatsProviderCb.onLimitReached();
+                        if (mStatsProvider != null) {
+                            mStatsProvider.pushTetherStats();
+                            // Push stats to service does not cause the service react to it
+                            // immediately. Inform the service about limit reached.
+                            mStatsProvider.notifyLimitReached();
+                        }
                     }
 
                     @Override
@@ -263,13 +263,17 @@
     }
 
     @VisibleForTesting
-    class OffloadTetheringStatsProvider extends AbstractNetworkStatsProvider {
+    class OffloadTetheringStatsProvider extends NetworkStatsProvider {
         // These stats must only ever be touched on the handler thread.
         @NonNull
         private NetworkStats mIfaceStats = new NetworkStats(0L, 0);
         @NonNull
         private NetworkStats mUidStats = new NetworkStats(0L, 0);
 
+        /**
+         * A helper function that collect tether stats from local hashmap. Note that this does not
+         * invoke binder call.
+         */
         @VisibleForTesting
         @NonNull
         NetworkStats getTetherStats(@NonNull StatsType how) {
@@ -280,14 +284,14 @@
                 final ForwardedStats value = kv.getValue();
                 final Entry entry = new Entry(kv.getKey(), uid, SET_DEFAULT, TAG_NONE, METERED_NO,
                         ROAMING_NO, DEFAULT_NETWORK_NO, value.rxBytes, 0L, value.txBytes, 0L, 0L);
-                stats = stats.addValues(entry);
+                stats = stats.addEntry(entry);
             }
 
             return stats;
         }
 
         @Override
-        public void setLimit(String iface, long quotaBytes) {
+        public void onSetLimit(String iface, long quotaBytes) {
             // Listen for all iface is necessary since upstream might be changed after limit
             // is set.
             mHandler.post(() -> {
@@ -315,13 +319,12 @@
          */
         public void pushTetherStats() {
             // TODO: remove the accumulated stats and report the diff from HAL directly.
-            if (null == mStatsProviderCb) return;
             final NetworkStats ifaceDiff =
                     getTetherStats(StatsType.STATS_PER_IFACE).subtract(mIfaceStats);
             final NetworkStats uidDiff =
                     getTetherStats(StatsType.STATS_PER_UID).subtract(mUidStats);
             try {
-                mStatsProviderCb.onStatsUpdated(0 /* token */, ifaceDiff, uidDiff);
+                notifyStatsUpdated(0 /* token */, ifaceDiff, uidDiff);
                 mIfaceStats = mIfaceStats.add(ifaceDiff);
                 mUidStats = mUidStats.add(uidDiff);
             } catch (RuntimeException e) {
@@ -330,7 +333,7 @@
         }
 
         @Override
-        public void requestStatsUpdate(int token) {
+        public void onRequestStatsUpdate(int token) {
             // Do not attempt to update stats by querying the offload HAL
             // synchronously from a different thread than the Handler thread. http://b/64771555.
             mHandler.post(() -> {
@@ -340,7 +343,7 @@
         }
 
         @Override
-        public void setAlert(long quotaBytes) {
+        public void onSetAlert(long quotaBytes) {
             // TODO: Ask offload HAL to notify alert without stopping traffic.
         }
     }
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java
index 7e62e5a..fe84086 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java
@@ -33,6 +33,8 @@
 import static com.android.testutils.MiscAssertsKt.assertThrows;
 import static com.android.testutils.NetworkStatsUtilsKt.orderInsensitiveEquals;
 
+import static junit.framework.Assert.assertNotNull;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -61,8 +63,7 @@
 import android.net.NetworkStats;
 import android.net.NetworkStats.Entry;
 import android.net.RouteInfo;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
 import android.net.util.SharedLog;
 import android.os.Handler;
 import android.os.Looper;
@@ -108,12 +109,10 @@
     @Mock private ApplicationInfo mApplicationInfo;
     @Mock private Context mContext;
     @Mock private NetworkStatsManager mStatsManager;
-    @Mock private NetworkStatsProviderCallback mTetherStatsProviderCb;
+    @Mock private INetworkStatsProviderCallback mTetherStatsProviderCb;
+    private OffloadController.OffloadTetheringStatsProvider mTetherStatsProvider;
     private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
             ArgumentCaptor.forClass(ArrayList.class);
-    private final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider>
-            mTetherStatsProviderCaptor =
-            ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class);
     private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor =
             ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class);
     private MockContentResolver mContentResolver;
@@ -126,8 +125,6 @@
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
         FakeSettingsProvider.clearSettingsProvider();
-        when(mStatsManager.registerNetworkStatsProvider(anyString(), any()))
-                .thenReturn(mTetherStatsProviderCb);
     }
 
     @After public void tearDown() throws Exception {
@@ -154,8 +151,14 @@
     private OffloadController makeOffloadController() throws Exception {
         OffloadController offload = new OffloadController(new Handler(Looper.getMainLooper()),
                 mHardware, mContentResolver, mStatsManager, new SharedLog("test"));
+        final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider>
+                tetherStatsProviderCaptor =
+                ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class);
         verify(mStatsManager).registerNetworkStatsProvider(anyString(),
-                mTetherStatsProviderCaptor.capture());
+                tetherStatsProviderCaptor.capture());
+        mTetherStatsProvider = tetherStatsProviderCaptor.getValue();
+        assertNotNull(mTetherStatsProvider);
+        mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb);
         return offload;
     }
 
@@ -413,9 +416,6 @@
         final OffloadController offload = makeOffloadController();
         offload.start();
 
-        final OffloadController.OffloadTetheringStatsProvider provider =
-                mTetherStatsProviderCaptor.getValue();
-
         final String ethernetIface = "eth1";
         final String mobileIface = "rmnet_data0";
 
@@ -443,15 +443,15 @@
         inOrder.verify(mHardware, times(1)).getForwardedStats(eq(mobileIface));
 
         // Verify that the fetched stats are stored.
-        final NetworkStats ifaceStats = provider.getTetherStats(STATS_PER_IFACE);
-        final NetworkStats uidStats = provider.getTetherStats(STATS_PER_UID);
+        final NetworkStats ifaceStats = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE);
+        final NetworkStats uidStats = mTetherStatsProvider.getTetherStats(STATS_PER_UID);
         final NetworkStats expectedIfaceStats = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
-                .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321));
+                .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
+                .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321));
 
         final NetworkStats expectedUidStats = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
-                .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321));
+                .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
+                .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321));
 
         assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStats));
         assertTrue(orderInsensitiveEquals(expectedUidStats, uidStats));
@@ -462,13 +462,12 @@
                 NetworkStats.class);
 
         // Force pushing stats update to verify the stats reported.
-        provider.pushTetherStats();
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(),
-                ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
+        mTetherStatsProvider.pushTetherStats();
+        verify(mTetherStatsProviderCb, times(1))
+                .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
         assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStatsCaptor.getValue()));
         assertTrue(orderInsensitiveEquals(expectedUidStats, uidStatsCaptor.getValue()));
 
-
         when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
                 new ForwardedStats(100000, 100000));
         offload.setUpstreamLinkProperties(null);
@@ -483,31 +482,31 @@
         inOrder.verifyNoMoreInteractions();
 
         // Verify that the stored stats is accumulated.
-        final NetworkStats ifaceStatsAccu = provider.getTetherStats(STATS_PER_IFACE);
-        final NetworkStats uidStatsAccu = provider.getTetherStats(STATS_PER_UID);
+        final NetworkStats ifaceStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE);
+        final NetworkStats uidStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_UID);
         final NetworkStats expectedIfaceStatsAccu = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
-                .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321));
+                .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
+                .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321));
 
         final NetworkStats expectedUidStatsAccu = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
-                .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321));
+                .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
+                .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321));
 
         assertTrue(orderInsensitiveEquals(expectedIfaceStatsAccu, ifaceStatsAccu));
         assertTrue(orderInsensitiveEquals(expectedUidStatsAccu, uidStatsAccu));
 
         // Verify that only diff of stats is reported.
         reset(mTetherStatsProviderCb);
-        provider.pushTetherStats();
+        mTetherStatsProvider.pushTetherStats();
         final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0))
-                .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000));
+                .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0))
+                .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000));
 
         final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0))
-                .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000));
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(),
-                ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
+                .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0))
+                .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000));
+        verify(mTetherStatsProviderCb, times(1))
+                .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
         assertTrue(orderInsensitiveEquals(expectedIfaceStatsDiff, ifaceStatsCaptor.getValue()));
         assertTrue(orderInsensitiveEquals(expectedUidStatsDiff, uidStatsCaptor.getValue()));
     }
@@ -529,19 +528,18 @@
         lp.setInterfaceName(ethernetIface);
         offload.setUpstreamLinkProperties(lp);
 
-        AbstractNetworkStatsProvider provider = mTetherStatsProviderCaptor.getValue();
         final InOrder inOrder = inOrder(mHardware);
         when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(true);
         when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(true);
 
         // Applying an interface quota to the current upstream immediately sends it to the hardware.
-        provider.setLimit(ethernetIface, ethernetLimit);
+        mTetherStatsProvider.onSetLimit(ethernetIface, ethernetLimit);
         waitForIdle();
         inOrder.verify(mHardware).setDataLimit(ethernetIface, ethernetLimit);
         inOrder.verifyNoMoreInteractions();
 
         // Applying an interface quota to another upstream does not take any immediate action.
-        provider.setLimit(mobileIface, mobileLimit);
+        mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
         waitForIdle();
         inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong());
 
@@ -554,7 +552,7 @@
 
         // Setting a limit of ITetheringStatsProvider.QUOTA_UNLIMITED causes the limit to be set
         // to Long.MAX_VALUE.
-        provider.setLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED);
+        mTetherStatsProvider.onSetLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED);
         waitForIdle();
         inOrder.verify(mHardware).setDataLimit(mobileIface, Long.MAX_VALUE);
 
@@ -562,7 +560,7 @@
         when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(false);
         lp.setInterfaceName(ethernetIface);
         offload.setUpstreamLinkProperties(lp);
-        provider.setLimit(mobileIface, mobileLimit);
+        mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
         waitForIdle();
         inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong());
 
@@ -571,7 +569,7 @@
         when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(false);
         lp.setInterfaceName(mobileIface);
         offload.setUpstreamLinkProperties(lp);
-        provider.setLimit(mobileIface, mobileLimit);
+        mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
         waitForIdle();
         inOrder.verify(mHardware).getForwardedStats(ethernetIface);
         inOrder.verify(mHardware).stopOffloadControl();
@@ -587,7 +585,7 @@
 
         OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
         callback.onStoppedLimitReached();
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any());
+        verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
     }
 
     @Test
@@ -691,7 +689,7 @@
         verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
         verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
         // TODO: verify the exact stats reported.
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any());
+        verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
         verifyNoMoreInteractions(mTetherStatsProviderCb);
         verifyNoMoreInteractions(mHardware);
     }
@@ -756,7 +754,7 @@
         // Verify forwarded stats behaviour.
         verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
         verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any());
+        verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
         verifyNoMoreInteractions(mTetherStatsProviderCb);
 
         // TODO: verify local prefixes and downstreams are also pushed to the HAL.
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 6247a63..69154b4 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -157,7 +157,6 @@
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Queue;
 import java.util.Random;
@@ -174,29 +173,47 @@
     public static class BackupWakeLock {
         private final PowerManager.WakeLock mPowerManagerWakeLock;
         private boolean mHasQuit = false;
+        private int mUserId;
 
-        public BackupWakeLock(PowerManager.WakeLock powerManagerWakeLock) {
+        public BackupWakeLock(PowerManager.WakeLock powerManagerWakeLock, int userId) {
             mPowerManagerWakeLock = powerManagerWakeLock;
+            mUserId = userId;
         }
 
         /** Acquires the {@link PowerManager.WakeLock} if hasn't been quit. */
         public synchronized void acquire() {
             if (mHasQuit) {
-                Slog.v(TAG, "Ignore wakelock acquire after quit: " + mPowerManagerWakeLock.getTag());
+                Slog.v(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "Ignore wakelock acquire after quit: "
+                                        + mPowerManagerWakeLock.getTag()));
                 return;
             }
             mPowerManagerWakeLock.acquire();
-            Slog.v(TAG, "Acquired wakelock:" + mPowerManagerWakeLock.getTag());
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Acquired wakelock:" + mPowerManagerWakeLock.getTag()));
         }
 
         /** Releases the {@link PowerManager.WakeLock} if hasn't been quit. */
         public synchronized void release() {
             if (mHasQuit) {
-                Slog.v(TAG, "Ignore wakelock release after quit: " + mPowerManagerWakeLock.getTag());
+                Slog.v(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "Ignore wakelock release after quit: "
+                                        + mPowerManagerWakeLock.getTag()));
                 return;
             }
             mPowerManagerWakeLock.release();
-            Slog.v(TAG, "Released wakelock:" + mPowerManagerWakeLock.getTag());
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Released wakelock:" + mPowerManagerWakeLock.getTag()));
         }
 
         /**
@@ -209,7 +226,10 @@
         /** Release the {@link PowerManager.WakeLock} till it isn't held. */
         public synchronized void quit() {
             while (mPowerManagerWakeLock.isHeld()) {
-                Slog.v(TAG, "Releasing wakelock: " + mPowerManagerWakeLock.getTag());
+                Slog.v(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Releasing wakelock: " + mPowerManagerWakeLock.getTag()));
                 mPowerManagerWakeLock.release();
             }
             mHasQuit = true;
@@ -439,7 +459,9 @@
         }
 
         if (DEBUG) {
-            Slog.v(TAG, "Starting with transport " + currentTransport);
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(userId, "Starting with transport " + currentTransport));
         }
         TransportManager transportManager =
                 new TransportManager(userId, context, transportWhitelist, currentTransport);
@@ -451,7 +473,9 @@
                 new HandlerThread("backup-" + userId, Process.THREAD_PRIORITY_BACKGROUND);
         userBackupThread.start();
         if (DEBUG) {
-            Slog.d(TAG, "Started thread " + userBackupThread.getName() + " for user " + userId);
+            Slog.d(
+                    TAG,
+                    addUserIdToLogMessage(userId, "Started thread " + userBackupThread.getName()));
         }
 
         return createAndInitializeService(
@@ -556,7 +580,10 @@
         if (userId == UserHandle.USER_SYSTEM) {
             mBaseStateDir.mkdirs();
             if (!SELinux.restorecon(mBaseStateDir)) {
-                Slog.w(TAG, "SELinux restorecon failed on " + mBaseStateDir);
+                Slog.w(
+                        TAG,
+                        addUserIdToLogMessage(
+                                userId, "SELinux restorecon failed on " + mBaseStateDir));
             }
         }
 
@@ -604,7 +631,8 @@
             addPackageParticipantsLocked(null);
         }
 
-        mTransportManager = Objects.requireNonNull(transportManager, "transportManager cannot be null");
+        mTransportManager =
+                Objects.requireNonNull(transportManager, "transportManager cannot be null");
         mTransportManager.setOnTransportRegisteredListener(this::onTransportRegistered);
         mRegisterTransportsRequestedTime = SystemClock.elapsedRealtime();
         mBackupHandler.postDelayed(
@@ -620,7 +648,7 @@
         mWakelock = new BackupWakeLock(
                 mPowerManager.newWakeLock(
                         PowerManager.PARTIAL_WAKE_LOCK,
-                        "*backup*-" + userId + "-" + userBackupThread.getThreadId()));
+                        "*backup*-" + userId + "-" + userBackupThread.getThreadId()), userId);
 
         // Set up the various sorts of package tracking we do
         mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule");
@@ -869,7 +897,7 @@
     }
 
     private void initPackageTracking() {
-        if (MORE_DEBUG) Slog.v(TAG, "` tracking");
+        if (MORE_DEBUG) Slog.v(TAG, addUserIdToLogMessage(mUserId, "` tracking"));
 
         // Remember our ancestral dataset
         mTokenFile = new File(mBaseStateDir, "ancestral");
@@ -891,9 +919,9 @@
             }
         } catch (FileNotFoundException fnf) {
             // Probably innocuous
-            Slog.v(TAG, "No ancestral data");
+            Slog.v(TAG, addUserIdToLogMessage(mUserId, "No ancestral data"));
         } catch (IOException e) {
-            Slog.w(TAG, "Unable to read token file", e);
+            Slog.w(TAG, addUserIdToLogMessage(mUserId, "Unable to read token file"), e);
         }
 
         mProcessedPackagesJournal = new ProcessedPackagesJournal(mBaseStateDir);
@@ -941,7 +969,10 @@
                  DataInputStream in = new DataInputStream(bufStream)) {
                 int version = in.readInt();
                 if (version != SCHEDULE_FILE_VERSION) {
-                    Slog.e(TAG, "Unknown backup schedule version " + version);
+                    Slog.e(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Unknown backup schedule version " + version));
                     return null;
                 }
 
@@ -966,14 +997,14 @@
                             schedule.add(new FullBackupEntry(pkgName, lastBackup));
                         } else {
                             if (DEBUG) {
-                                Slog.i(TAG, "Package " + pkgName
-                                        + " no longer eligible for full backup");
+                                Slog.i(TAG, addUserIdToLogMessage(mUserId, "Package " + pkgName
+                                        + " no longer eligible for full backup"));
                             }
                         }
                     } catch (NameNotFoundException e) {
                         if (DEBUG) {
-                            Slog.i(TAG, "Package " + pkgName
-                                    + " not installed; dropping from full backup");
+                            Slog.i(TAG, addUserIdToLogMessage(mUserId, "Package " + pkgName
+                                    + " not installed; dropping from full backup"));
                         }
                     }
                 }
@@ -986,7 +1017,13 @@
                             mUserId)) {
                         if (!foundApps.contains(app.packageName)) {
                             if (MORE_DEBUG) {
-                                Slog.i(TAG, "New full backup app " + app.packageName + " found");
+                                Slog.i(
+                                        TAG,
+                                        addUserIdToLogMessage(
+                                                mUserId,
+                                                "New full backup app "
+                                                        + app.packageName
+                                                        + " found"));
                             }
                             schedule.add(new FullBackupEntry(app.packageName, 0));
                             changed = true;
@@ -996,7 +1033,7 @@
 
                 Collections.sort(schedule);
             } catch (Exception e) {
-                Slog.e(TAG, "Unable to read backup schedule", e);
+                Slog.e(TAG, addUserIdToLogMessage(mUserId, "Unable to read backup schedule"), e);
                 mFullBackupScheduleFile.delete();
                 schedule = null;
             }
@@ -1052,7 +1089,11 @@
                     out.write(bufStream.toByteArray());
                     af.finishWrite(out);
                 } catch (Exception e) {
-                    Slog.e(TAG, "Unable to write backup schedule!", e);
+                    Slog.e(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Unable to write backup schedule!"),
+                            e);
                 }
             }
         }
@@ -1069,12 +1110,17 @@
             if (!journal.equals(mJournal)) {
                 try {
                     journal.forEach(packageName -> {
-                        Slog.i(TAG, "Found stale backup journal, scheduling");
-                        if (MORE_DEBUG) Slog.i(TAG, "  " + packageName);
+                        Slog.i(
+                                TAG,
+                                addUserIdToLogMessage(
+                                        mUserId, "Found stale backup journal, scheduling"));
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, addUserIdToLogMessage(mUserId, "  " + packageName));
+                        }
                         dataChangedImpl(packageName);
                     });
                 } catch (IOException e) {
-                    Slog.e(TAG, "Can't read " + journal, e);
+                    Slog.e(TAG, addUserIdToLogMessage(mUserId, "Can't read " + journal), e);
                 }
             }
         }
@@ -1114,7 +1160,14 @@
             boolean isPending, String transportName, String transportDirName) {
         synchronized (mQueueLock) {
             if (MORE_DEBUG) {
-                Slog.i(TAG, "recordInitPending(" + isPending + ") on transport " + transportName);
+                Slog.i(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "recordInitPending("
+                                        + isPending
+                                        + ") on transport "
+                                        + transportName));
             }
 
             File stateDir = new File(mBaseStateDir, transportDirName);
@@ -1175,8 +1228,17 @@
     private void onTransportRegistered(String transportName, String transportDirName) {
         if (DEBUG) {
             long timeMs = SystemClock.elapsedRealtime() - mRegisterTransportsRequestedTime;
-            Slog.d(TAG, "Transport " + transportName + " registered " + timeMs
-                    + "ms after first request (delay = " + INITIALIZATION_DELAY_MILLIS + "ms)");
+            Slog.d(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Transport "
+                                    + transportName
+                                    + " registered "
+                                    + timeMs
+                                    + "ms after first request (delay = "
+                                    + INITIALIZATION_DELAY_MILLIS
+                                    + "ms)"));
         }
 
         File stateDir = new File(mBaseStateDir, transportDirName);
@@ -1202,7 +1264,7 @@
     private BroadcastReceiver mPackageTrackingReceiver = new BroadcastReceiver() {
         public void onReceive(Context context, Intent intent) {
             if (MORE_DEBUG) {
-                Slog.d(TAG, "Received broadcast " + intent);
+                Slog.d(TAG, addUserIdToLogMessage(mUserId, "Received broadcast " + intent));
             }
 
             String action = intent.getAction();
@@ -1222,24 +1284,33 @@
 
                 String packageName = uri.getSchemeSpecificPart();
                 if (packageName != null) {
-                    packageList = new String[]{packageName};
+                    packageList = new String[] {packageName};
                 }
 
                 changed = Intent.ACTION_PACKAGE_CHANGED.equals(action);
                 if (changed) {
                     // Look at new transport states for package changed events.
                     String[] components =
-                            intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
+                            intent.getStringArrayExtra(
+                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
 
                     if (MORE_DEBUG) {
-                        Slog.i(TAG, "Package " + packageName + " changed");
+                        Slog.i(
+                                TAG,
+                                addUserIdToLogMessage(
+                                        mUserId, "Package " + packageName + " changed"));
                         for (int i = 0; i < components.length; i++) {
-                            Slog.i(TAG, "   * " + components[i]);
+                            Slog.i(
+                                    TAG,
+                                    addUserIdToLogMessage(
+                                            mUserId, "   * " + components[i]));
                         }
                     }
 
                     mBackupHandler.post(
-                            () -> mTransportManager.onPackageChanged(packageName, components));
+                            () ->
+                                    mTransportManager.onPackageChanged(
+                                            packageName, components));
                     return;
                 }
 
@@ -1261,7 +1332,8 @@
             if (added) {
                 synchronized (mBackupParticipants) {
                     if (replacing) {
-                        // Remove the entry under the old uid and fall through to re-add. If an app
+                        // Remove the entry under the old uid and fall through to re-add. If
+                        // an app
                         // just opted into key/value backup, add it as a known participant.
                         removePackageParticipantsLocked(packageList, uid);
                     }
@@ -1275,13 +1347,15 @@
                                 mPackageManager.getPackageInfoAsUser(
                                         packageName, /* flags */ 0, mUserId);
                         if (AppBackupUtils.appGetsFullBackup(app)
-                                && AppBackupUtils.appIsEligibleForBackup(app.applicationInfo,
-                                mUserId)) {
+                                && AppBackupUtils.appIsEligibleForBackup(
+                                        app.applicationInfo, mUserId)) {
                             enqueueFullBackup(packageName, now);
                             scheduleNextFullBackupJob(0);
                         } else {
-                            // The app might have just transitioned out of full-data into doing
-                            // key/value backups, or might have just disabled backups entirely. Make
+                            // The app might have just transitioned out of full-data into
+                            // doing
+                            // key/value backups, or might have just disabled backups
+                            // entirely. Make
                             // sure it is no longer in the full-data queue.
                             synchronized (mQueueLock) {
                                 dequeueFullBackupLocked(packageName);
@@ -1293,17 +1367,23 @@
                                 () -> mTransportManager.onPackageAdded(packageName));
                     } catch (NameNotFoundException e) {
                         if (DEBUG) {
-                            Slog.w(TAG, "Can't resolve new app " + packageName);
+                            Slog.w(
+                                    TAG,
+                                    addUserIdToLogMessage(
+                                            mUserId,
+                                            "Can't resolve new app " + packageName));
                         }
                     }
                 }
 
-                // Whenever a package is added or updated we need to update the package metadata
+                // Whenever a package is added or updated we need to update the package
+                // metadata
                 // bookkeeping.
                 dataChangedImpl(PACKAGE_MANAGER_SENTINEL);
             } else {
                 if (!replacing) {
-                    // Outright removal. In the full-data case, the app will be dropped from the
+                    // Outright removal. In the full-data case, the app will be dropped from
+                    // the
                     // queue when its (now obsolete) name comes up again for backup.
                     synchronized (mBackupParticipants) {
                         removePackageParticipantsLocked(packageList, uid);
@@ -1324,12 +1404,19 @@
         // Look for apps that define the android:backupAgent attribute
         List<PackageInfo> targetApps = allAgentPackages();
         if (packageNames != null) {
-            if (MORE_DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: #" + packageNames.length);
+            if (MORE_DEBUG) {
+                Slog.v(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "addPackageParticipantsLocked: #" + packageNames.length));
+            }
             for (String packageName : packageNames) {
                 addPackageParticipantsLockedInner(packageName, targetApps);
             }
         } else {
-            if (MORE_DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: all");
+            if (MORE_DEBUG) {
+                Slog.v(TAG, addUserIdToLogMessage(mUserId, "addPackageParticipantsLocked: all"));
+            }
             addPackageParticipantsLockedInner(null, targetApps);
         }
     }
@@ -1337,7 +1424,10 @@
     private void addPackageParticipantsLockedInner(String packageName,
             List<PackageInfo> targetPkgs) {
         if (MORE_DEBUG) {
-            Slog.v(TAG, "Examining " + packageName + " for backup agent");
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Examining " + packageName + " for backup agent"));
         }
 
         for (PackageInfo pkg : targetPkgs) {
@@ -1349,10 +1439,15 @@
                     mBackupParticipants.put(uid, set);
                 }
                 set.add(pkg.packageName);
-                if (MORE_DEBUG) Slog.v(TAG, "Agent found; added");
+                if (MORE_DEBUG) Slog.v(TAG, addUserIdToLogMessage(mUserId, "Agent found; added"));
 
                 // Schedule a backup for it on general principles
-                if (MORE_DEBUG) Slog.i(TAG, "Scheduling backup for new app " + pkg.packageName);
+                if (MORE_DEBUG) {
+                    Slog.i(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Scheduling backup for new app " + pkg.packageName));
+                }
                 Message msg = mBackupHandler
                         .obtainMessage(MSG_SCHEDULE_BACKUP_PACKAGE, pkg.packageName);
                 mBackupHandler.sendMessage(msg);
@@ -1363,13 +1458,19 @@
     // Remove the given packages' entries from our known active set.
     private void removePackageParticipantsLocked(String[] packageNames, int oldUid) {
         if (packageNames == null) {
-            Slog.w(TAG, "removePackageParticipants with null list");
+            Slog.w(TAG, addUserIdToLogMessage(mUserId, "removePackageParticipants with null list"));
             return;
         }
 
         if (MORE_DEBUG) {
-            Slog.v(TAG, "removePackageParticipantsLocked: uid=" + oldUid
-                    + " #" + packageNames.length);
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "removePackageParticipantsLocked: uid="
+                                    + oldUid
+                                    + " #"
+                                    + packageNames.length));
         }
         for (String pkg : packageNames) {
             // Known previous UID, so we know which package set to check
@@ -1377,7 +1478,12 @@
             if (set != null && set.contains(pkg)) {
                 removePackageFromSetLocked(set, pkg);
                 if (set.isEmpty()) {
-                    if (MORE_DEBUG) Slog.v(TAG, "  last one of this uid; purging set");
+                    if (MORE_DEBUG) {
+                        Slog.v(
+                                TAG,
+                                addUserIdToLogMessage(
+                                        mUserId, "  last one of this uid; purging set"));
+                    }
                     mBackupParticipants.remove(oldUid);
                 }
             }
@@ -1393,7 +1499,11 @@
             // Note that we deliberately leave it 'known' in the "ever backed up"
             // bookkeeping so that its current-dataset data will be retrieved
             // if the app is subsequently reinstalled
-            if (MORE_DEBUG) Slog.v(TAG, "  removing participant " + packageName);
+            if (MORE_DEBUG) {
+                Slog.v(
+                        TAG,
+                        addUserIdToLogMessage(mUserId, "  removing participant " + packageName));
+            }
             set.remove(packageName);
             mPendingBackups.remove(packageName);
         }
@@ -1467,14 +1577,19 @@
                 af.writeInt(-1);
             } else {
                 af.writeInt(mAncestralPackages.size());
-                if (DEBUG) Slog.v(TAG, "Ancestral packages:  " + mAncestralPackages.size());
+                if (DEBUG) {
+                    Slog.v(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Ancestral packages:  " + mAncestralPackages.size()));
+                }
                 for (String pkgName : mAncestralPackages) {
                     af.writeUTF(pkgName);
-                    if (MORE_DEBUG) Slog.v(TAG, "   " + pkgName);
+                    if (MORE_DEBUG) Slog.v(TAG, addUserIdToLogMessage(mUserId, "   " + pkgName));
                 }
             }
         } catch (IOException e) {
-            Slog.w(TAG, "Unable to write token file:", e);
+            Slog.w(TAG, addUserIdToLogMessage(mUserId, "Unable to write token file:"), e);
         }
     }
 
@@ -1487,7 +1602,7 @@
             mConnectedAgent = null;
             try {
                 if (mActivityManager.bindBackupAgent(app.packageName, mode, mUserId)) {
-                    Slog.d(TAG, "awaiting agent for " + app);
+                    Slog.d(TAG, addUserIdToLogMessage(mUserId, "awaiting agent for " + app));
 
                     // success; wait for the agent to arrive
                     // only wait 10 seconds for the bind to happen
@@ -1498,7 +1613,7 @@
                             mAgentConnectLock.wait(5000);
                         } catch (InterruptedException e) {
                             // just bail
-                            Slog.w(TAG, "Interrupted: " + e);
+                            Slog.w(TAG, addUserIdToLogMessage(mUserId, "Interrupted: " + e));
                             mConnecting = false;
                             mConnectedAgent = null;
                         }
@@ -1506,10 +1621,14 @@
 
                     // if we timed out with no connect, abort and move on
                     if (mConnecting) {
-                        Slog.w(TAG, "Timeout waiting for agent " + app);
+                        Slog.w(
+                                TAG,
+                                addUserIdToLogMessage(mUserId, "Timeout waiting for agent " + app));
                         mConnectedAgent = null;
                     }
-                    if (DEBUG) Slog.i(TAG, "got agent " + mConnectedAgent);
+                    if (DEBUG) {
+                        Slog.i(TAG, addUserIdToLogMessage(mUserId, "got agent " + mConnectedAgent));
+                    }
                     agent = mConnectedAgent;
                 }
             } catch (RemoteException e) {
@@ -1575,13 +1694,20 @@
 
             if (!shouldClearData) {
                 if (MORE_DEBUG) {
-                    Slog.i(TAG, "Clearing app data is not allowed so not wiping "
-                            + packageName);
+                    Slog.i(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId,
+                                    "Clearing app data is not allowed so not wiping "
+                                            + packageName));
                 }
                 return;
             }
         } catch (NameNotFoundException e) {
-            Slog.w(TAG, "Tried to clear data for " + packageName + " but not found");
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Tried to clear data for " + packageName + " but not found"));
             return;
         }
 
@@ -1604,13 +1730,22 @@
                 } catch (InterruptedException e) {
                     // won't happen, but still.
                     mClearingData = false;
-                    Slog.w(TAG, "Interrupted while waiting for " + packageName
-                            + " data to be cleared", e);
+                    Slog.w(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId,
+                                    "Interrupted while waiting for "
+                                            + packageName
+                                            + " data to be cleared"),
+                            e);
                 }
             }
 
             if (mClearingData) {
-                Slog.w(TAG, "Clearing app data for " + packageName + " timed out");
+                Slog.w(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Clearing app data for " + packageName + " timed out"));
             }
         }
     }
@@ -1627,12 +1762,17 @@
         synchronized (mQueueLock) {
             if (mCurrentToken != 0 && mProcessedPackagesJournal.hasBeenProcessed(packageName)) {
                 if (MORE_DEBUG) {
-                    Slog.i(TAG, "App in ever-stored, so using current token");
+                    Slog.i(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "App in ever-stored, so using current token"));
                 }
                 token = mCurrentToken;
             }
         }
-        if (MORE_DEBUG) Slog.i(TAG, "getAvailableRestoreToken() == " + token);
+        if (MORE_DEBUG) {
+            Slog.i(TAG, addUserIdToLogMessage(mUserId, "getAvailableRestoreToken() == " + token));
+        }
         return token;
     }
 
@@ -1654,7 +1794,7 @@
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup");
 
         if (packages == null || packages.length < 1) {
-            Slog.e(TAG, "No packages named for backup request");
+            Slog.e(TAG, addUserIdToLogMessage(mUserId, "No packages named for backup request"));
             BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
             monitor = BackupManagerMonitorUtils.monitorEvent(monitor,
                     BackupManagerMonitor.LOG_EVENT_ID_NO_PACKAGES,
@@ -1665,10 +1805,10 @@
         if (!mEnabled || !mSetupComplete) {
             Slog.i(
                     TAG,
-                    "Backup requested but enabled="
+                    addUserIdToLogMessage(mUserId, "Backup requested but enabled="
                             + mEnabled
                             + " setupComplete="
-                            + mSetupComplete);
+                            + mSetupComplete));
             BackupObserverUtils.sendBackupFinished(observer,
                     BackupManager.ERROR_BACKUP_NOT_ALLOWED);
             final int logTag = mSetupComplete
@@ -1726,9 +1866,17 @@
         EventLog.writeEvent(EventLogTags.BACKUP_REQUESTED, packages.length, kvBackupList.size(),
                 fullBackupList.size());
         if (MORE_DEBUG) {
-            Slog.i(TAG, "Backup requested for " + packages.length + " packages, of them: "
-                    + fullBackupList.size() + " full backups, " + kvBackupList.size()
-                    + " k/v backups");
+            Slog.i(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Backup requested for "
+                                    + packages.length
+                                    + " packages, of them: "
+                                    + fullBackupList.size()
+                                    + " full backups, "
+                                    + kvBackupList.size()
+                                    + " k/v backups"));
         }
 
         boolean nonIncrementalBackup = (flags & BackupManager.FLAG_NON_INCREMENTAL_BACKUP) != 0;
@@ -1744,7 +1892,7 @@
     public void cancelBackups() {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "cancelBackups");
         if (MORE_DEBUG) {
-            Slog.i(TAG, "cancelBackups() called.");
+            Slog.i(TAG, addUserIdToLogMessage(mUserId, "cancelBackups() called."));
         }
         final long oldToken = Binder.clearCallingIdentity();
         try {
@@ -1774,13 +1922,27 @@
     public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
             int operationType) {
         if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
-            Slog.wtf(TAG, "prepareOperationTimeout() doesn't support operation "
-                    + Integer.toHexString(token) + " of type " + operationType);
+            Slog.wtf(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "prepareOperationTimeout() doesn't support operation "
+                                    + Integer.toHexString(token)
+                                    + " of type "
+                                    + operationType));
             return;
         }
         if (MORE_DEBUG) {
-            Slog.v(TAG, "starting timeout: token=" + Integer.toHexString(token)
-                    + " interval=" + interval + " callback=" + callback);
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "starting timeout: token="
+                                    + Integer.toHexString(token)
+                                    + " interval="
+                                    + interval
+                                    + " callback="
+                                    + callback));
         }
 
         synchronized (mCurrentOpLock) {
@@ -1798,8 +1960,12 @@
             case OP_TYPE_RESTORE_WAIT:
                 return MSG_RESTORE_OPERATION_TIMEOUT;
             default:
-                Slog.wtf(TAG, "getMessageIdForOperationType called on invalid operation type: "
-                        + operationType);
+                Slog.wtf(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "getMessageIdForOperationType called on invalid operation type: "
+                                        + operationType));
                 return -1;
         }
     }
@@ -1810,8 +1976,14 @@
      */
     public void putOperation(int token, Operation operation) {
         if (MORE_DEBUG) {
-            Slog.d(TAG, "Adding operation token=" + Integer.toHexString(token) + ", operation type="
-                    + operation.type);
+            Slog.d(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Adding operation token="
+                                    + Integer.toHexString(token)
+                                    + ", operation type="
+                                    + operation.type));
         }
         synchronized (mCurrentOpLock) {
             mCurrentOperations.put(token, operation);
@@ -1824,12 +1996,15 @@
      */
     public void removeOperation(int token) {
         if (MORE_DEBUG) {
-            Slog.d(TAG, "Removing operation token=" + Integer.toHexString(token));
+            Slog.d(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Removing operation token=" + Integer.toHexString(token)));
         }
         synchronized (mCurrentOpLock) {
             if (mCurrentOperations.get(token) == null) {
-                Slog.w(TAG, "Duplicate remove for operation. token="
-                        + Integer.toHexString(token));
+                Slog.w(TAG, addUserIdToLogMessage(mUserId, "Duplicate remove for operation. token="
+                        + Integer.toHexString(token)));
             }
             mCurrentOperations.remove(token);
         }
@@ -1838,8 +2013,8 @@
     /** Block until we received an operation complete message (from the agent or cancellation). */
     public boolean waitUntilOperationComplete(int token) {
         if (MORE_DEBUG) {
-            Slog.i(TAG, "Blocking until operation complete for "
-                    + Integer.toHexString(token));
+            Slog.i(TAG, addUserIdToLogMessage(mUserId, "Blocking until operation complete for "
+                    + Integer.toHexString(token)));
         }
         int finalState = OP_PENDING;
         Operation op = null;
@@ -1858,8 +2033,12 @@
                         // When the wait is notified we loop around and recheck the current state
                     } else {
                         if (MORE_DEBUG) {
-                            Slog.d(TAG, "Unblocked waiting for operation token="
-                                    + Integer.toHexString(token));
+                            Slog.d(
+                                    TAG,
+                                    addUserIdToLogMessage(
+                                            mUserId,
+                                            "Unblocked waiting for operation token="
+                                                    + Integer.toHexString(token)));
                         }
                         // No longer pending; we're done
                         finalState = op.state;
@@ -1874,8 +2053,8 @@
             mBackupHandler.removeMessages(getMessageIdForOperationType(op.type));
         }
         if (MORE_DEBUG) {
-            Slog.v(TAG, "operation " + Integer.toHexString(token)
-                    + " complete: finalState=" + finalState);
+            Slog.v(TAG, addUserIdToLogMessage(mUserId, "operation " + Integer.toHexString(token)
+                    + " complete: finalState=" + finalState));
         }
         return finalState == OP_ACKNOWLEDGED;
     }
@@ -1888,21 +2067,31 @@
             op = mCurrentOperations.get(token);
             if (MORE_DEBUG) {
                 if (op == null) {
-                    Slog.w(TAG, "Cancel of token " + Integer.toHexString(token)
-                            + " but no op found");
+                    Slog.w(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId,
+                                    "Cancel of token "
+                                            + Integer.toHexString(token)
+                                            + " but no op found"));
                 }
             }
             int state = (op != null) ? op.state : OP_TIMEOUT;
             if (state == OP_ACKNOWLEDGED) {
                 // The operation finished cleanly, so we have nothing more to do.
                 if (DEBUG) {
-                    Slog.w(TAG, "Operation already got an ack."
-                            + "Should have been removed from mCurrentOperations.");
+                    Slog.w(TAG, addUserIdToLogMessage(mUserId, "Operation already got an ack."
+                            + "Should have been removed from mCurrentOperations."));
                 }
                 op = null;
                 mCurrentOperations.delete(token);
             } else if (state == OP_PENDING) {
-                if (DEBUG) Slog.v(TAG, "Cancel: token=" + Integer.toHexString(token));
+                if (DEBUG) {
+                    Slog.v(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Cancel: token=" + Integer.toHexString(token)));
+                }
                 op.state = OP_TIMEOUT;
                 // Can't delete op from mCurrentOperations here. waitUntilOperationComplete may be
                 // called after we receive cancel here. We need this op's state there.
@@ -1920,7 +2109,7 @@
         // If there's a TimeoutHandler for this event, call it
         if (op != null && op.callback != null) {
             if (MORE_DEBUG) {
-                Slog.v(TAG, "   Invoking cancel on " + op.callback);
+                Slog.v(TAG, addUserIdToLogMessage(mUserId, "   Invoking cancel on " + op.callback));
             }
             op.callback.handleCancel(cancelAll);
         }
@@ -1955,13 +2144,20 @@
             //     manifest flag!  TODO something less direct.
             if (!UserHandle.isCore(app.uid)
                     && !app.packageName.equals("com.android.backupconfirm")) {
-                if (MORE_DEBUG) Slog.d(TAG, "Killing agent host process");
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, addUserIdToLogMessage(mUserId, "Killing agent host process"));
+                }
                 mActivityManager.killApplicationProcess(app.processName, app.uid);
             } else {
-                if (MORE_DEBUG) Slog.d(TAG, "Not killing after operation: " + app.processName);
+                if (MORE_DEBUG) {
+                    Slog.d(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Not killing after operation: " + app.processName));
+                }
             }
         } catch (RemoteException e) {
-            Slog.d(TAG, "Lost app trying to shut down");
+            Slog.d(TAG, addUserIdToLogMessage(mUserId, "Lost app trying to shut down"));
         }
     }
 
@@ -1975,7 +2171,12 @@
         } catch (Exception e) {
             // If we can't talk to the storagemanager service we have a serious problem; fail
             // "secure" i.e. assuming that the device is encrypted.
-            Slog.e(TAG, "Unable to communicate with storagemanager service: " + e.getMessage());
+            Slog.e(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Unable to communicate with storagemanager service: "
+                                    + e.getMessage()));
             return true;
         }
     }
@@ -1999,7 +2200,10 @@
                 FullBackupJob.schedule(mUserId, mContext, latency, mConstants);
             } else {
                 if (DEBUG_SCHEDULING) {
-                    Slog.i(TAG, "Full backup queue empty; not scheduling");
+                    Slog.i(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Full backup queue empty; not scheduling"));
                 }
             }
         }
@@ -2054,7 +2258,10 @@
 
     private boolean fullBackupAllowable(String transportName) {
         if (!mTransportManager.isTransportRegistered(transportName)) {
-            Slog.w(TAG, "Transport not registered; full data backup not performed");
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Transport not registered; full data backup not performed"));
             return false;
         }
 
@@ -2066,12 +2273,19 @@
             File pmState = new File(stateDir, PACKAGE_MANAGER_SENTINEL);
             if (pmState.length() <= 0) {
                 if (DEBUG) {
-                    Slog.i(TAG, "Full backup requested but dataset not yet initialized");
+                    Slog.i(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId,
+                                    "Full backup requested but dataset not yet initialized"));
                 }
                 return false;
             }
         } catch (Exception e) {
-            Slog.w(TAG, "Unable to get transport name: " + e.getMessage());
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Unable to get transport name: " + e.getMessage()));
             return false;
         }
 
@@ -2104,8 +2318,8 @@
             // the job driving automatic backups; that job will be scheduled again when
             // the user enables backup.
             if (MORE_DEBUG) {
-                Slog.i(TAG, "beginFullBackup but enabled=" + mEnabled
-                        + " setupComplete=" + mSetupComplete + "; ignoring");
+                Slog.i(TAG, addUserIdToLogMessage(mUserId, "beginFullBackup but enabled=" + mEnabled
+                        + " setupComplete=" + mSetupComplete + "; ignoring"));
             }
             return false;
         }
@@ -2115,19 +2329,29 @@
         final PowerSaveState result =
                 mPowerManager.getPowerSaveState(ServiceType.FULL_BACKUP);
         if (result.batterySaverEnabled) {
-            if (DEBUG) Slog.i(TAG, "Deferring scheduled full backups in battery saver mode");
+            if (DEBUG) {
+                Slog.i(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Deferring scheduled full backups in battery saver mode"));
+            }
             FullBackupJob.schedule(mUserId, mContext, keyValueBackupInterval, mConstants);
             return false;
         }
 
         if (DEBUG_SCHEDULING) {
-            Slog.i(TAG, "Beginning scheduled full backup operation");
+            Slog.i(
+                    TAG,
+                    addUserIdToLogMessage(mUserId, "Beginning scheduled full backup operation"));
         }
 
         // Great; we're able to run full backup jobs now.  See if we have any work to do.
         synchronized (mQueueLock) {
             if (mRunningFullBackupTask != null) {
-                Slog.e(TAG, "Backup triggered but one already/still running!");
+                Slog.e(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Backup triggered but one already/still running!"));
                 return false;
             }
 
@@ -2143,7 +2367,10 @@
                 if (mFullBackupQueue.size() == 0) {
                     // no work to do so just bow out
                     if (DEBUG) {
-                        Slog.i(TAG, "Backup queue empty; doing nothing");
+                        Slog.i(
+                                TAG,
+                                addUserIdToLogMessage(
+                                        mUserId, "Backup queue empty; doing nothing"));
                     }
                     runBackup = false;
                     break;
@@ -2154,7 +2381,10 @@
                 String transportName = mTransportManager.getCurrentTransportName();
                 if (!fullBackupAllowable(transportName)) {
                     if (MORE_DEBUG) {
-                        Slog.i(TAG, "Preconditions not met; not running full backup");
+                        Slog.i(
+                                TAG,
+                                addUserIdToLogMessage(
+                                        mUserId, "Preconditions not met; not running full backup"));
                     }
                     runBackup = false;
                     // Typically this means we haven't run a key/value backup yet.  Back off
@@ -2170,7 +2400,11 @@
                     if (!runBackup) {
                         // It's too early to back up the next thing in the queue, so bow out
                         if (MORE_DEBUG) {
-                            Slog.i(TAG, "Device ready but too early to back up next app");
+                            Slog.i(
+                                    TAG,
+                                    addUserIdToLogMessage(
+                                            mUserId,
+                                            "Device ready but too early to back up next app"));
                         }
                         // Wait until the next app in the queue falls due for a full data backup
                         latency = fullBackupInterval - timeSinceRun;
@@ -2185,8 +2419,14 @@
                             // so we cull it and force a loop around to consider the new head
                             // app.
                             if (MORE_DEBUG) {
-                                Slog.i(TAG, "Culling package " + entry.packageName
-                                        + " in full-backup queue but not eligible");
+                                Slog.i(
+                                        TAG,
+                                        addUserIdToLogMessage(
+                                                mUserId,
+                                                "Culling package "
+                                                        + entry.packageName
+                                                        + " in full-backup queue but not"
+                                                        + " eligible"));
                             }
                             mFullBackupQueue.remove(0);
                             headBusy = true; // force the while() condition
@@ -2204,9 +2444,14 @@
                                     + mTokenGenerator.nextInt(BUSY_BACKOFF_FUZZ);
                             if (DEBUG_SCHEDULING) {
                                 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-                                Slog.i(TAG, "Full backup time but " + entry.packageName
-                                        + " is busy; deferring to "
-                                        + sdf.format(new Date(nextEligible)));
+                                Slog.i(
+                                        TAG,
+                                        addUserIdToLogMessage(
+                                                mUserId,
+                                                "Full backup time but "
+                                                        + entry.packageName
+                                                        + " is busy; deferring to "
+                                                        + sdf.format(new Date(nextEligible))));
                             }
                             // This relocates the app's entry from the head of the queue to
                             // its order-appropriate position further down, so upon looping
@@ -2225,7 +2470,11 @@
 
             if (!runBackup) {
                 if (DEBUG_SCHEDULING) {
-                    Slog.i(TAG, "Nothing pending full backup; rescheduling +" + latency);
+                    Slog.i(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId,
+                                    "Nothing pending full backup; rescheduling +" + latency));
                 }
                 final long deferTime = latency;     // pin for the closure
                 FullBackupJob.schedule(mUserId, mContext, deferTime, mConstants);
@@ -2273,7 +2522,10 @@
                 }
                 if (pftbt != null) {
                     if (DEBUG_SCHEDULING) {
-                        Slog.i(TAG, "Telling running backup to stop");
+                        Slog.i(
+                                TAG,
+                                addUserIdToLogMessage(
+                                        mUserId, "Telling running backup to stop"));
                     }
                     pftbt.handleCancel(true);
                 }
@@ -2286,7 +2538,7 @@
     public void restoreWidgetData(String packageName, byte[] widgetData) {
         // Apply the restored widget state and generate the ID update for the app
         if (MORE_DEBUG) {
-            Slog.i(TAG, "Incorporating restored widget data");
+            Slog.i(TAG, addUserIdToLogMessage(mUserId, "Incorporating restored widget data"));
         }
         AppWidgetBackupBridge.restoreWidgetState(packageName, widgetData, mUserId);
     }
@@ -2306,8 +2558,15 @@
         // may share a uid, we need to note all candidates within that uid and schedule
         // a backup pass for each of them.
         if (targets == null) {
-            Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
-                    + " uid=" + Binder.getCallingUid());
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "dataChanged but no participant pkg='"
+                                    + packageName
+                                    + "'"
+                                    + " uid="
+                                    + Binder.getCallingUid()));
             return;
         }
 
@@ -2318,7 +2577,12 @@
                 // one already there, then overwrite it, but no harm done.
                 BackupRequest req = new BackupRequest(packageName);
                 if (mPendingBackups.put(packageName, req) == null) {
-                    if (MORE_DEBUG) Slog.d(TAG, "Now staging backup of " + packageName);
+                    if (MORE_DEBUG) {
+                        Slog.d(
+                                TAG,
+                                addUserIdToLogMessage(
+                                        mUserId, "Now staging backup of " + packageName));
+                    }
 
                     // Journal this request in case of crash.  The put()
                     // operation returned null when this package was not already
@@ -2358,7 +2622,10 @@
             if (mJournal == null) mJournal = DataChangedJournal.newJournal(mJournalDir);
             mJournal.addPackage(str);
         } catch (IOException e) {
-            Slog.e(TAG, "Can't write " + str + " to backup journal", e);
+            Slog.e(
+                    TAG,
+                    addUserIdToLogMessage(mUserId, "Can't write " + str + " to backup journal"),
+                    e);
             mJournal = null;
         }
     }
@@ -2369,8 +2636,15 @@
     public void dataChanged(final String packageName) {
         final HashSet<String> targets = dataChangedTargets(packageName);
         if (targets == null) {
-            Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
-                    + " uid=" + Binder.getCallingUid());
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "dataChanged but no participant pkg='"
+                                    + packageName
+                                    + "'"
+                                    + " uid="
+                                    + Binder.getCallingUid()));
             return;
         }
 
@@ -2385,7 +2659,10 @@
     public void initializeTransports(String[] transportNames, IBackupObserver observer) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "initializeTransport");
-        Slog.v(TAG, "initializeTransport(): " + Arrays.asList(transportNames));
+        Slog.v(
+                TAG,
+                addUserIdToLogMessage(
+                        mUserId, "initializeTransport(): " + Arrays.asList(transportNames)));
 
         final long oldId = Binder.clearCallingIdentity();
         try {
@@ -2404,11 +2681,18 @@
     public void setAncestralSerialNumber(long ancestralSerialNumber) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
                 "setAncestralSerialNumber");
-        Slog.v(TAG, "Setting ancestral work profile id to " + ancestralSerialNumber);
+        Slog.v(
+                TAG,
+                addUserIdToLogMessage(
+                        mUserId, "Setting ancestral work profile id to " + ancestralSerialNumber));
         try (RandomAccessFile af = getAncestralSerialNumberFile()) {
             af.writeLong(ancestralSerialNumber);
         } catch (IOException e) {
-            Slog.w(TAG, "Unable to write to work profile serial mapping file:", e);
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Unable to write to work profile serial mapping file:"),
+                    e);
         }
     }
 
@@ -2420,7 +2704,11 @@
         try (RandomAccessFile af = getAncestralSerialNumberFile()) {
             return af.readLong();
         } catch (IOException e) {
-            Slog.w(TAG, "Unable to write to work profile serial number file:", e);
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Unable to write to work profile serial number file:"),
+                    e);
             return -1;
         }
     }
@@ -2443,13 +2731,24 @@
 
     /** Clear the given package's backup data from the current transport. */
     public void clearBackupData(String transportName, String packageName) {
-        if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
+        if (DEBUG) {
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "clearBackupData() of " + packageName + " on " + transportName));
+        }
+
         PackageInfo info;
         try {
             info = mPackageManager.getPackageInfoAsUser(packageName,
                     PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
         } catch (NameNotFoundException e) {
-            Slog.d(TAG, "No such package '" + packageName + "' - not clearing backup data");
+            Slog.d(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "No such package '" + packageName + "' - not clearing backup data"));
             return;
         }
 
@@ -2462,13 +2761,22 @@
         } else {
             // a caller with full permission can ask to back up any participating app
             // !!! TODO: allow data-clear of ANY app?
-            if (MORE_DEBUG) Slog.v(TAG, "Privileged caller, allowing clear of other apps");
+            if (MORE_DEBUG) {
+                Slog.v(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Privileged caller, allowing clear of other apps"));
+            }
             apps = mProcessedPackagesJournal.getPackagesCopy();
         }
 
         if (apps.contains(packageName)) {
             // found it; fire off the clear request
-            if (MORE_DEBUG) Slog.v(TAG, "Found the app - running clear process");
+            if (MORE_DEBUG) {
+                Slog.v(
+                        TAG,
+                        addUserIdToLogMessage(mUserId, "Found the app - running clear process"));
+            }
             mBackupHandler.removeMessages(MSG_RETRY_CLEAR);
             synchronized (mQueueLock) {
                 TransportClient transportClient =
@@ -2507,24 +2815,36 @@
             final PowerSaveState result =
                     mPowerManager.getPowerSaveState(ServiceType.KEYVALUE_BACKUP);
             if (result.batterySaverEnabled) {
-                if (DEBUG) Slog.v(TAG, "Not running backup while in battery save mode");
+                if (DEBUG) {
+                    Slog.v(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Not running backup while in battery save mode"));
+                }
                 // Try again in several hours.
                 KeyValueBackupJob.schedule(mUserId, mContext, mConstants);
             } else {
-                if (DEBUG) Slog.v(TAG, "Scheduling immediate backup pass");
+                if (DEBUG) {
+                    Slog.v(TAG, addUserIdToLogMessage(mUserId, "Scheduling immediate backup pass"));
+                }
 
                 synchronized (getQueueLock()) {
                     if (getPendingInits().size() > 0) {
                         // If there are pending init operations, we process those and then settle
                         // into the usual periodic backup schedule.
                         if (MORE_DEBUG) {
-                            Slog.v(TAG, "Init pending at scheduled backup");
+                            Slog.v(
+                                    TAG,
+                                    addUserIdToLogMessage(
+                                            mUserId, "Init pending at scheduled backup"));
                         }
                         try {
                             getAlarmManager().cancel(mRunInitIntent);
                             mRunInitIntent.send();
                         } catch (PendingIntent.CanceledException ce) {
-                            Slog.w(TAG, "Run init intent cancelled");
+                            Slog.w(
+                                    TAG,
+                                    addUserIdToLogMessage(mUserId, "Run init intent cancelled"));
                         }
                         return;
                     }
@@ -2534,8 +2854,8 @@
                 if (!isEnabled() || !isSetupComplete()) {
                     Slog.w(
                             TAG,
-                            "Backup pass but enabled="  + isEnabled()
-                                    + " setupComplete=" + isSetupComplete());
+                            addUserIdToLogMessage(mUserId, "Backup pass but enabled="  + isEnabled()
+                                    + " setupComplete=" + isSetupComplete()));
                     return;
                 }
 
@@ -2582,16 +2902,31 @@
         long oldId = Binder.clearCallingIdentity();
         try {
             if (!mSetupComplete) {
-                Slog.i(TAG, "Backup not supported before setup");
+                Slog.i(TAG, addUserIdToLogMessage(mUserId, "Backup not supported before setup"));
                 return;
             }
 
             if (DEBUG) {
-                Slog.v(TAG, "Requesting backup: apks=" + includeApks + " obb=" + includeObbs
-                        + " shared=" + includeShared + " all=" + doAllApps + " system="
-                        + includeSystem + " includekeyvalue=" + doKeyValue + " pkgs=" + pkgList);
+                Slog.v(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "Requesting backup: apks="
+                                        + includeApks
+                                        + " obb="
+                                        + includeObbs
+                                        + " shared="
+                                        + includeShared
+                                        + " all="
+                                        + doAllApps
+                                        + " system="
+                                        + includeSystem
+                                        + " includekeyvalue="
+                                        + doKeyValue
+                                        + " pkgs="
+                                        + pkgList));
             }
-            Slog.i(TAG, "Beginning adb backup...");
+            Slog.i(TAG, addUserIdToLogMessage(mUserId, "Beginning adb backup..."));
 
             AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs,
                     includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue,
@@ -2602,9 +2937,16 @@
             }
 
             // start up the confirmation UI
-            if (DEBUG) Slog.d(TAG, "Starting backup confirmation UI, token=" + token);
+            if (DEBUG) {
+                Slog.d(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Starting backup confirmation UI, token=" + token));
+            }
             if (!startConfirmationUi(token, FullBackup.FULL_BACKUP_INTENT_ACTION)) {
-                Slog.e(TAG, "Unable to launch backup confirmation UI");
+                Slog.e(
+                        TAG,
+                        addUserIdToLogMessage(mUserId, "Unable to launch backup confirmation UI"));
                 mAdbBackupRestoreConfirmations.delete(token);
                 return;
             }
@@ -2618,16 +2960,22 @@
             startConfirmationTimeout(token, params);
 
             // wait for the backup to be performed
-            if (DEBUG) Slog.d(TAG, "Waiting for backup completion...");
+            if (DEBUG) {
+                Slog.d(TAG, addUserIdToLogMessage(mUserId, "Waiting for backup completion..."));
+            }
             waitForCompletion(params);
         } finally {
             try {
                 fd.close();
             } catch (IOException e) {
-                Slog.e(TAG, "IO error closing output for adb backup: " + e.getMessage());
+                Slog.e(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "IO error closing output for adb backup: " + e.getMessage()));
             }
             Binder.restoreCallingIdentity(oldId);
-            Slog.d(TAG, "Adb backup processing complete.");
+            Slog.d(TAG, addUserIdToLogMessage(mUserId, "Adb backup processing complete."));
         }
     }
 
@@ -2644,10 +2992,14 @@
 
         String transportName = mTransportManager.getCurrentTransportName();
         if (!fullBackupAllowable(transportName)) {
-            Slog.i(TAG, "Full backup not currently possible -- key/value backup not yet run?");
+            Slog.i(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Full backup not currently possible -- key/value backup not yet run?"));
         } else {
             if (DEBUG) {
-                Slog.d(TAG, "fullTransportBackup()");
+                Slog.d(TAG, addUserIdToLogMessage(mUserId, "fullTransportBackup()"));
             }
 
             final long oldId = Binder.clearCallingIdentity();
@@ -2687,7 +3039,7 @@
         }
 
         if (DEBUG) {
-            Slog.d(TAG, "Done with full transport backup.");
+            Slog.d(TAG, addUserIdToLogMessage(mUserId, "Done with full transport backup."));
         }
     }
 
@@ -2707,11 +3059,13 @@
 
         try {
             if (!mSetupComplete) {
-                Slog.i(TAG, "Full restore not permitted before setup");
+                Slog.i(
+                        TAG,
+                        addUserIdToLogMessage(mUserId, "Full restore not permitted before setup"));
                 return;
             }
 
-            Slog.i(TAG, "Beginning restore...");
+            Slog.i(TAG, addUserIdToLogMessage(mUserId, "Beginning restore..."));
 
             AdbRestoreParams params = new AdbRestoreParams(fd);
             final int token = generateRandomIntegerToken();
@@ -2720,9 +3074,16 @@
             }
 
             // start up the confirmation UI
-            if (DEBUG) Slog.d(TAG, "Starting restore confirmation UI, token=" + token);
+            if (DEBUG) {
+                Slog.d(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Starting restore confirmation UI, token=" + token));
+            }
             if (!startConfirmationUi(token, FullBackup.FULL_RESTORE_INTENT_ACTION)) {
-                Slog.e(TAG, "Unable to launch restore confirmation");
+                Slog.e(
+                        TAG,
+                        addUserIdToLogMessage(mUserId, "Unable to launch restore confirmation"));
                 mAdbBackupRestoreConfirmations.delete(token);
                 return;
             }
@@ -2736,16 +3097,21 @@
             startConfirmationTimeout(token, params);
 
             // wait for the restore to be performed
-            if (DEBUG) Slog.d(TAG, "Waiting for restore completion...");
+            if (DEBUG) {
+                Slog.d(TAG, addUserIdToLogMessage(mUserId, "Waiting for restore completion..."));
+            }
             waitForCompletion(params);
         } finally {
             try {
                 fd.close();
             } catch (IOException e) {
-                Slog.w(TAG, "Error trying to close fd after adb restore: " + e);
+                Slog.w(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Error trying to close fd after adb restore: " + e));
             }
             Binder.restoreCallingIdentity(oldId);
-            Slog.i(TAG, "adb restore processing complete.");
+            Slog.i(TAG, addUserIdToLogMessage(mUserId, "adb restore processing complete."));
         }
     }
 
@@ -2773,8 +3139,8 @@
 
     private void startConfirmationTimeout(int token, AdbParams params) {
         if (MORE_DEBUG) {
-            Slog.d(TAG, "Posting conf timeout msg after "
-                    + TIMEOUT_FULL_CONFIRMATION + " millis");
+            Slog.d(TAG, addUserIdToLogMessage(mUserId, "Posting conf timeout msg after "
+                    + TIMEOUT_FULL_CONFIRMATION + " millis"));
         }
         Message msg = mBackupHandler.obtainMessage(MSG_FULL_CONFIRMATION_TIMEOUT,
                 token, 0, params);
@@ -2806,8 +3172,11 @@
     public void acknowledgeAdbBackupOrRestore(int token, boolean allow,
             String curPassword, String encPpassword, IFullBackupRestoreObserver observer) {
         if (DEBUG) {
-            Slog.d(TAG, "acknowledgeAdbBackupOrRestore : token=" + token
-                    + " allow=" + allow);
+            Slog.d(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "acknowledgeAdbBackupOrRestore : token=" + token + " allow=" + allow));
         }
 
         // TODO: possibly require not just this signature-only permission, but even
@@ -2835,17 +3204,29 @@
 
                         params.encryptPassword = encPpassword;
 
-                        if (MORE_DEBUG) Slog.d(TAG, "Sending conf message with verb " + verb);
+                        if (MORE_DEBUG) {
+                            Slog.d(
+                                    TAG,
+                                    addUserIdToLogMessage(
+                                            mUserId, "Sending conf message with verb " + verb));
+                        }
                         mWakelock.acquire();
                         Message msg = mBackupHandler.obtainMessage(verb, params);
                         mBackupHandler.sendMessage(msg);
                     } else {
-                        Slog.w(TAG, "User rejected full backup/restore operation");
+                        Slog.w(
+                                TAG,
+                                addUserIdToLogMessage(
+                                        mUserId, "User rejected full backup/restore operation"));
                         // indicate completion without having actually transferred any data
                         signalAdbBackupRestoreCompletion(params);
                     }
                 } else {
-                    Slog.w(TAG, "Attempted to ack full backup/restore with invalid token");
+                    Slog.w(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId,
+                                    "Attempted to ack full backup/restore with invalid token"));
                 }
             }
         } finally {
@@ -2858,7 +3239,7 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupEnabled");
 
-        Slog.i(TAG, "Backup enabled => " + enable);
+        Slog.i(TAG, addUserIdToLogMessage(mUserId, "Backup enabled => " + enable));
 
         long oldId = Binder.clearCallingIdentity();
         try {
@@ -2875,7 +3256,9 @@
                     scheduleNextFullBackupJob(0);
                 } else if (!enable) {
                     // No longer enabled, so stop running backups
-                    if (MORE_DEBUG) Slog.i(TAG, "Opting out of backup");
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, addUserIdToLogMessage(mUserId, "Opting out of backup"));
+                    }
 
                     KeyValueBackupJob.cancel(mUserId, mContext);
 
@@ -2891,12 +3274,15 @@
                                 name -> {
                                     final String dirName;
                                     try {
-                                        dirName =
-                                                mTransportManager
-                                                        .getTransportDirName(name);
+                                        dirName = mTransportManager.getTransportDirName(name);
                                     } catch (TransportNotRegisteredException e) {
                                         // Should never happen
-                                        Slog.e(TAG, "Unexpected unregistered transport", e);
+                                        Slog.e(
+                                                TAG,
+                                                addUserIdToLogMessage(
+                                                        mUserId,
+                                                        "Unexpected unregistered transport"),
+                                                e);
                                         return;
                                     }
                                     transportNames.add(name);
@@ -2925,7 +3311,7 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setAutoRestore");
 
-        Slog.i(TAG, "Auto restore => " + doAutoRestore);
+        Slog.i(TAG, addUserIdToLogMessage(mUserId, "Auto restore => " + doAutoRestore));
 
         final long oldId = Binder.clearCallingIdentity();
         try {
@@ -2951,7 +3337,12 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getCurrentTransport");
         String currentTransport = mTransportManager.getCurrentTransportName();
-        if (MORE_DEBUG) Slog.v(TAG, "... getCurrentTransport() returning " + currentTransport);
+        if (MORE_DEBUG) {
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "... getCurrentTransport() returning " + currentTransport));
+        }
         return currentTransport;
     }
 
@@ -3090,8 +3481,14 @@
         try {
             String previousTransportName = mTransportManager.selectTransport(transportName);
             updateStateForTransport(transportName);
-            Slog.v(TAG, "selectBackupTransport(transport = " + transportName
-                    + "): previous transport = " + previousTransportName);
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "selectBackupTransport(transport = "
+                                    + transportName
+                                    + "): previous transport = "
+                                    + previousTransportName));
             return previousTransportName;
         } finally {
             Binder.restoreCallingIdentity(oldId);
@@ -3110,7 +3507,11 @@
         final long oldId = Binder.clearCallingIdentity();
         try {
             String transportString = transportComponent.flattenToShortString();
-            Slog.v(TAG, "selectBackupTransportAsync(transport = " + transportString + ")");
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "selectBackupTransportAsync(transport = " + transportString + ")"));
             mBackupHandler.post(
                     () -> {
                         String transportName = null;
@@ -3122,7 +3523,10 @@
                                         mTransportManager.getTransportName(transportComponent);
                                 updateStateForTransport(transportName);
                             } catch (TransportNotRegisteredException e) {
-                                Slog.e(TAG, "Transport got unregistered");
+                                Slog.e(
+                                        TAG,
+                                        addUserIdToLogMessage(
+                                                mUserId, "Transport got unregistered"));
                                 result = BackupManager.ERROR_TRANSPORT_UNAVAILABLE;
                             }
                         }
@@ -3134,7 +3538,12 @@
                                 listener.onFailure(result);
                             }
                         } catch (RemoteException e) {
-                            Slog.e(TAG, "ISelectBackupTransportCallback listener not available");
+                            Slog.e(
+                                    TAG,
+                                    addUserIdToLogMessage(
+                                            mUserId,
+                                            "ISelectBackupTransportCallback listener not"
+                                                + " available"));
                         }
                     });
         } finally {
@@ -3159,11 +3568,23 @@
                 // Oops.  We can't know the current dataset token, so reset and figure it out
                 // when we do the next k/v backup operation on this transport.
                 mCurrentToken = 0;
-                Slog.w(TAG, "Transport " + newTransportName + " not available: current token = 0");
+                Slog.w(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "Transport "
+                                        + newTransportName
+                                        + " not available: current token = 0"));
             }
             mTransportManager.disposeOfTransportClient(transportClient, callerLogString);
         } else {
-            Slog.w(TAG, "Transport " + newTransportName + " not registered: current token = 0");
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Transport "
+                                    + newTransportName
+                                    + " not registered: current token = 0"));
             // The named transport isn't registered, so we can't know what its current dataset token
             // is. Reset as above.
             mCurrentToken = 0;
@@ -3181,11 +3602,19 @@
         try {
             Intent intent = mTransportManager.getTransportConfigurationIntent(transportName);
             if (MORE_DEBUG) {
-                Slog.d(TAG, "getConfigurationIntent() returning intent " + intent);
+                Slog.d(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "getConfigurationIntent() returning intent " + intent));
             }
             return intent;
         } catch (TransportNotRegisteredException e) {
-            Slog.e(TAG, "Unable to get configuration intent from transport: " + e.getMessage());
+            Slog.e(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Unable to get configuration intent from transport: "
+                                    + e.getMessage()));
             return null;
         }
     }
@@ -3206,11 +3635,18 @@
         try {
             String string = mTransportManager.getTransportCurrentDestinationString(transportName);
             if (MORE_DEBUG) {
-                Slog.d(TAG, "getDestinationString() returning " + string);
+                Slog.d(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "getDestinationString() returning " + string));
             }
             return string;
         } catch (TransportNotRegisteredException e) {
-            Slog.e(TAG, "Unable to get destination string from transport: " + e.getMessage());
+            Slog.e(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Unable to get destination string from transport: " + e.getMessage()));
             return null;
         }
     }
@@ -3223,11 +3659,18 @@
         try {
             Intent intent = mTransportManager.getTransportDataManagementIntent(transportName);
             if (MORE_DEBUG) {
-                Slog.d(TAG, "getDataManagementIntent() returning intent " + intent);
+                Slog.d(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "getDataManagementIntent() returning intent " + intent));
             }
             return intent;
         } catch (TransportNotRegisteredException e) {
-            Slog.e(TAG, "Unable to get management intent from transport: " + e.getMessage());
+            Slog.e(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Unable to get management intent from transport: " + e.getMessage()));
             return null;
         }
     }
@@ -3243,11 +3686,18 @@
         try {
             CharSequence label = mTransportManager.getTransportDataManagementLabel(transportName);
             if (MORE_DEBUG) {
-                Slog.d(TAG, "getDataManagementLabel() returning " + label);
+                Slog.d(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "getDataManagementLabel() returning " + label));
             }
             return label;
         } catch (TransportNotRegisteredException e) {
-            Slog.e(TAG, "Unable to get management label from transport: " + e.getMessage());
+            Slog.e(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Unable to get management label from transport: " + e.getMessage()));
             return null;
         }
     }
@@ -3259,12 +3709,21 @@
     public void agentConnected(String packageName, IBinder agentBinder) {
         synchronized (mAgentConnectLock) {
             if (Binder.getCallingUid() == Process.SYSTEM_UID) {
-                Slog.d(TAG, "agentConnected pkg=" + packageName + " agent=" + agentBinder);
+                Slog.d(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "agentConnected pkg=" + packageName + " agent=" + agentBinder));
                 mConnectedAgent = IBackupAgent.Stub.asInterface(agentBinder);
                 mConnecting = false;
             } else {
-                Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
-                        + " claiming agent connected");
+                Slog.w(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "Non-system process uid="
+                                        + Binder.getCallingUid()
+                                        + " claiming agent connected"));
             }
             mAgentConnectLock.notifyAll();
         }
@@ -3282,8 +3741,13 @@
                 mConnectedAgent = null;
                 mConnecting = false;
             } else {
-                Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
-                        + " claiming agent disconnected");
+                Slog.w(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "Non-system process uid="
+                                        + Binder.getCallingUid()
+                                        + " claiming agent disconnected"));
             }
             mAgentConnectLock.notifyAll();
         }
@@ -3295,8 +3759,13 @@
      */
     public void restoreAtInstall(String packageName, int token) {
         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
-                    + " attemping install-time restore");
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "Non-system process uid="
+                                    + Binder.getCallingUid()
+                                    + " attemping install-time restore"));
             return;
         }
 
@@ -3304,25 +3773,35 @@
 
         long restoreSet = getAvailableRestoreToken(packageName);
         if (DEBUG) {
-            Slog.v(TAG, "restoreAtInstall pkg=" + packageName
-                    + " token=" + Integer.toHexString(token)
-                    + " restoreSet=" + Long.toHexString(restoreSet));
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "restoreAtInstall pkg="
+                                    + packageName
+                                    + " token="
+                                    + Integer.toHexString(token)
+                                    + " restoreSet="
+                                    + Long.toHexString(restoreSet)));
         }
         if (restoreSet == 0) {
-            if (MORE_DEBUG) Slog.i(TAG, "No restore set");
+            if (MORE_DEBUG) Slog.i(TAG, addUserIdToLogMessage(mUserId, "No restore set"));
             skip = true;
         }
 
         TransportClient transportClient =
                 mTransportManager.getCurrentTransportClient("BMS.restoreAtInstall()");
         if (transportClient == null) {
-            if (DEBUG) Slog.w(TAG, "No transport client");
+            if (DEBUG) Slog.w(TAG, addUserIdToLogMessage(mUserId, "No transport client"));
             skip = true;
         }
 
         if (!mAutoRestore) {
             if (DEBUG) {
-                Slog.w(TAG, "Non-restorable state: auto=" + mAutoRestore);
+                Slog.w(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Non-restorable state: auto=" + mAutoRestore));
             }
             skip = true;
         }
@@ -3341,7 +3820,9 @@
                 };
 
                 if (MORE_DEBUG) {
-                    Slog.d(TAG, "Restore at install of " + packageName);
+                    Slog.d(
+                            TAG,
+                            addUserIdToLogMessage(mUserId, "Restore at install of " + packageName));
                 }
                 Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
                 msg.obj =
@@ -3356,7 +3837,10 @@
                 mBackupHandler.sendMessage(msg);
             } catch (Exception e) {
                 // Calling into the transport broke; back off and proceed with the installation.
-                Slog.e(TAG, "Unable to contact transport: " + e.getMessage());
+                Slog.e(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Unable to contact transport: " + e.getMessage()));
                 skip = true;
             }
         }
@@ -3370,7 +3854,7 @@
             }
 
             // Tell the PackageManager to proceed with the post-install handling for this package.
-            if (DEBUG) Slog.v(TAG, "Finishing install immediately");
+            if (DEBUG) Slog.v(TAG, addUserIdToLogMessage(mUserId, "Finishing install immediately"));
             try {
                 mPackageManagerBinder.finishPackageInstall(token, false);
             } catch (RemoteException e) { /* can't happen */ }
@@ -3380,8 +3864,11 @@
     /** Hand off a restore session. */
     public IRestoreSession beginRestoreSession(String packageName, String transport) {
         if (DEBUG) {
-            Slog.v(TAG, "beginRestoreSession: pkg=" + packageName
-                    + " transport=" + transport);
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "beginRestoreSession: pkg=" + packageName + " transport=" + transport));
         }
 
         boolean needPermission = true;
@@ -3393,7 +3880,10 @@
                 try {
                     app = mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId);
                 } catch (NameNotFoundException nnf) {
-                    Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
+                    Slog.w(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Asked to restore nonexistent pkg " + packageName));
                     throw new IllegalArgumentException("Package " + packageName + " not found");
                 }
 
@@ -3407,19 +3897,32 @@
         }
 
         if (needPermission) {
-            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
-                    "beginRestoreSession");
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.BACKUP, "beginRestoreSession");
         } else {
-            if (DEBUG) Slog.d(TAG, "restoring self on current transport; no permission needed");
+            if (DEBUG) {
+                Slog.d(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "restoring self on current transport; no permission needed"));
+            }
         }
 
         synchronized (this) {
             if (mActiveRestoreSession != null) {
-                Slog.i(TAG, "Restore session requested but one already active");
+                Slog.i(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId, "Restore session requested but one already active"));
                 return null;
             }
             if (mBackupRunning) {
-                Slog.i(TAG, "Restore session requested but currently running backups");
+                Slog.i(
+                        TAG,
+                        addUserIdToLogMessage(
+                                mUserId,
+                                "Restore session requested but currently running backups"));
                 return null;
             }
             mActiveRestoreSession = new ActiveRestoreSession(this, packageName, transport);
@@ -3433,9 +3936,14 @@
     public void clearRestoreSession(ActiveRestoreSession currentSession) {
         synchronized (this) {
             if (currentSession != mActiveRestoreSession) {
-                Slog.e(TAG, "ending non-current restore session");
+                Slog.e(TAG, addUserIdToLogMessage(mUserId, "ending non-current restore session"));
             } else {
-                if (DEBUG) Slog.v(TAG, "Clearing restore session and halting timeout");
+                if (DEBUG) {
+                    Slog.v(
+                            TAG,
+                            addUserIdToLogMessage(
+                                    mUserId, "Clearing restore session and halting timeout"));
+                }
                 mActiveRestoreSession = null;
                 mBackupHandler.removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
             }
@@ -3448,7 +3956,11 @@
      */
     public void opComplete(int token, long result) {
         if (MORE_DEBUG) {
-            Slog.v(TAG, "opComplete: " + Integer.toHexString(token) + " result=" + result);
+            Slog.v(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId,
+                            "opComplete: " + Integer.toHexString(token) + " result=" + result));
         }
         Operation op = null;
         synchronized (mCurrentOpLock) {
@@ -3461,8 +3973,12 @@
                     mCurrentOperations.delete(token);
                 } else if (op.state == OP_ACKNOWLEDGED) {
                     if (DEBUG) {
-                        Slog.w(TAG, "Received duplicate ack for token="
-                                + Integer.toHexString(token));
+                        Slog.w(
+                                TAG,
+                                addUserIdToLogMessage(
+                                        mUserId,
+                                        "Received duplicate ack for token="
+                                                + Integer.toHexString(token)));
                     }
                     op = null;
                     mCurrentOperations.remove(token);
@@ -3606,7 +4122,7 @@
                                     "       " + f.getName() + " - " + f.length() + " state bytes");
                         }
                     } catch (Exception e) {
-                        Slog.e(TAG, "Error in transport", e);
+                        Slog.e(TAG, addUserIdToLogMessage(mUserId, "Error in transport"), e);
                         pw.println("        Error: " + e);
                     }
                 }
@@ -3665,6 +4181,10 @@
         }
     }
 
+    private static String addUserIdToLogMessage(int userId, String message) {
+        return "[UserID:" + userId + "] " + message;
+    }
+
 
     public IBackupManager getBackupManagerBinder() {
         return mBackupManagerBinder;
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 9fddafb..7d85966 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -66,7 +66,6 @@
     public static final int PACKAGE_CONFIGURATOR = 9;
     public static final int PACKAGE_INCIDENT_REPORT_APPROVER = 10;
     public static final int PACKAGE_APP_PREDICTOR = 11;
-    public static final int PACKAGE_TELEPHONY = 12;
     public static final int PACKAGE_WIFI = 13;
     public static final int PACKAGE_COMPANION = 14;
     public static final int PACKAGE_RETAIL_DEMO = 15;
@@ -124,7 +123,6 @@
         PACKAGE_CONFIGURATOR,
         PACKAGE_INCIDENT_REPORT_APPROVER,
         PACKAGE_APP_PREDICTOR,
-        PACKAGE_TELEPHONY,
         PACKAGE_WIFI,
         PACKAGE_COMPANION,
         PACKAGE_RETAIL_DEMO,
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index deae459..b89b1eb 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1666,7 +1666,7 @@
         if (newNc.getNetworkSpecifier() != null) {
             newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
         }
-        newNc.setAdministratorUids(Collections.EMPTY_LIST);
+        newNc.setAdministratorUids(new int[0]);
 
         return newNc;
     }
@@ -1727,7 +1727,7 @@
             nc.setSingleUid(callerUid);
         }
         nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
-        nc.setAdministratorUids(Collections.EMPTY_LIST);
+        nc.setAdministratorUids(new int[0]);
 
         // Clear owner UID; this can never come from an app.
         nc.setOwnerUid(INVALID_UID);
@@ -7864,7 +7864,7 @@
 
     private void clearNetworkCapabilitiesUids(@NonNull NetworkCapabilities nc) {
         nc.setUids(null);
-        nc.setAdministratorUids(Collections.EMPTY_LIST);
+        nc.setAdministratorUids(new int[0]);
         nc.setOwnerUid(Process.INVALID_UID);
     }
 
@@ -7911,8 +7911,9 @@
         }
 
         // Administrator UIDs also contains the Owner UID
-        if (nai.networkCapabilities.getAdministratorUids().contains(callbackUid)) {
-            return true;
+        final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
+        for (final int uid : administratorUids) {
+            if (uid == callbackUid) return true;
         }
 
         return false;
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 52a1b5a..41a104c 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -161,6 +161,9 @@
     private final Runnable mSaveToFile = this::saveToFile;
     private final SystemClock mSystemClock;
     private final BootThreshold mBootThreshold;
+    // The set of packages that have been synced with the ExplicitHealthCheckController
+    @GuardedBy("mLock")
+    private Set<String> mRequestedHealthCheckPackages = new ArraySet<>();
     @GuardedBy("mLock")
     private boolean mIsPackagesReady;
     // Flag to control whether explicit health checks are supported or not
@@ -174,6 +177,9 @@
     // 0 if no prune is scheduled.
     @GuardedBy("mLock")
     private long mUptimeAtLastStateSync;
+    // If true, sync explicit health check packages with the ExplicitHealthCheckController.
+    @GuardedBy("mLock")
+    private boolean mSyncRequired = false;
 
     @FunctionalInterface
     @VisibleForTesting
@@ -249,6 +255,7 @@
      */
     public void registerHealthObserver(PackageHealthObserver observer) {
         synchronized (mLock) {
+            mSyncRequired = true;
             ObserverInternal internalObserver = mAllObservers.get(observer.getName());
             if (internalObserver != null) {
                 internalObserver.registeredObserver = observer;
@@ -628,17 +635,23 @@
      * @see #syncRequestsAsync
      */
     private void syncRequests() {
-        Set<String> packages = null;
+        boolean syncRequired = false;
         synchronized (mLock) {
             if (mIsPackagesReady) {
-                packages = getPackagesPendingHealthChecksLocked();
+                Set<String> packages = getPackagesPendingHealthChecksLocked();
+                if (!packages.equals(mRequestedHealthCheckPackages) || mSyncRequired) {
+                    syncRequired = true;
+                    mRequestedHealthCheckPackages = packages;
+                }
             } // else, we will sync requests when packages become ready
         }
 
         // Call outside lock to avoid holding lock when calling into the controller.
-        if (packages != null) {
-            Slog.i(TAG, "Syncing health check requests for packages: " + packages);
-            mHealthCheckController.syncRequests(packages);
+        if (syncRequired) {
+            Slog.i(TAG, "Syncing health check requests for packages: "
+                    + mRequestedHealthCheckPackages);
+            mHealthCheckController.syncRequests(mRequestedHealthCheckPackages);
+            mSyncRequired = false;
         }
     }
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 2c220d3..5a056d3 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -4076,7 +4076,7 @@
                 return Zygote.MOUNT_EXTERNAL_NONE;
             }
 
-            if (mIsFuseEnabled && mMediaStoreAuthorityAppId == UserHandle.getAppId(uid)) {
+            if (mIsFuseEnabled && mStorageManagerInternal.isExternalStorageService(uid)) {
                 // Determine if caller requires pass_through mount; note that we do this for
                 // all processes that share a UID with MediaProvider; but this is fine, since
                 // those processes anyway share the same rights as MediaProvider.
@@ -4422,14 +4422,16 @@
                             String.format("/storage/emulated/%d/Android/data/%s/",
                                     userId, pkg);
 
+                    int appUid =
+                            UserHandle.getUid(userId, mPmInternal.getPackage(pkg).getUid());
                     // Create package obb and data dir if it doesn't exist.
                     File file = new File(packageObbDir);
                     if (!file.exists()) {
-                        vold.setupAppDir(packageObbDir, mPmInternal.getPackage(pkg).getUid());
+                        vold.setupAppDir(packageObbDir, appUid);
                     }
                     file = new File(packageDataDir);
                     if (!file.exists()) {
-                        vold.setupAppDir(packageDataDir, mPmInternal.getPackage(pkg).getUid());
+                        vold.setupAppDir(packageDataDir, appUid);
                     }
                 }
             } catch (ServiceManager.ServiceNotFoundException | RemoteException e) {
@@ -4524,6 +4526,11 @@
             }
         }
 
+        @Override
+        public boolean isExternalStorageService(int uid) {
+            return mMediaStoreAuthorityAppId == UserHandle.getAppId(uid);
+        }
+
         public boolean hasExternalStorage(int uid, String packageName) {
             // No need to check for system uid. This avoids a deadlock between
             // PackageManagerService and AppOpsService.
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index f772a4a..81a1372 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -53,7 +53,6 @@
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.ArrayList;
-import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -250,7 +249,7 @@
         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         nc.setNetworkSpecifier(new StringNetworkSpecifier(iface));
-        nc.setAdministratorUids(intArrayToList(administratorUids));
+        nc.setAdministratorUids(administratorUids);
         if (!isMetered) {
             nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
         }
@@ -293,14 +292,6 @@
         return new TestNetworkAgent(looper, context, ni, nc, lp, callingUid, binder);
     }
 
-    private List<Integer> intArrayToList(@NonNull int[] array) {
-        final List<Integer> list = new ArrayList<>(array.length);
-        for (final int i : array) {
-            list.add(i);
-        }
-        return list;
-    }
-
     /**
      * Sets up a Network with extremely limited privileges, guarded by the MANAGE_TEST_NETWORKS
      * permission.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4485af1..a458498 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -579,6 +579,13 @@
     static final String EXTRA_DESCRIPTION = "android.intent.extra.DESCRIPTION";
     static final String EXTRA_BUGREPORT_TYPE = "android.intent.extra.BUGREPORT_TYPE";
 
+    /**
+     * The maximum number of bytes that {@link #setProcessStateSummary} accepts.
+     *
+     * @see {@link android.app.ActivityManager#setProcessStateSummary(byte[])}
+     */
+    static final int MAX_STATE_DATA_SIZE = 128;
+
     /** All system services */
     SystemServiceManager mSystemServiceManager;
 
@@ -2179,9 +2186,17 @@
 
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
+                Process.enableFreezer(false);
+            }
+
             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
                     "meminfo", pw)) return;
             PriorityDump.dump(mPriorityDumper, fd, pw, args);
+
+            if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
+                Process.enableFreezer(true);
+            }
         }
     }
 
@@ -2193,9 +2208,17 @@
 
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
+                Process.enableFreezer(false);
+            }
+
             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
                     "gfxinfo", pw)) return;
             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
+
+            if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
+                Process.enableFreezer(true);
+            }
         }
     }
 
@@ -2207,9 +2230,17 @@
 
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
+                Process.enableFreezer(false);
+            }
+
             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
                     "dbinfo", pw)) return;
             mActivityManagerService.dumpDbInfo(fd, pw, args);
+
+            if (mActivityManagerService.mOomAdjuster.mCachedAppOptimizer.useFreezer()) {
+                Process.enableFreezer(true);
+            }
         }
     }
 
@@ -3178,7 +3209,7 @@
         return mAtmInternal.compatibilityInfoForPackage(ai);
     }
 
-    private void enforceNotIsolatedCaller(String caller) {
+    /* package */ void enforceNotIsolatedCaller(String caller) {
         if (UserHandle.isIsolated(Binder.getCallingUid())) {
             throw new SecurityException("Isolated process not allowed to call " + caller);
         }
@@ -3863,6 +3894,18 @@
     public static File dumpStackTraces(ArrayList<Integer> firstPids,
             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
             ArrayList<Integer> nativePids, StringWriter logExceptionCreatingFile) {
+        return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePids,
+                logExceptionCreatingFile, null);
+    }
+
+    /**
+     * @param firstPidOffsets Optional, when it's set, it receives the start/end offset
+     *                        of the very first pid to be dumped.
+     */
+    /* package */ static File dumpStackTraces(ArrayList<Integer> firstPids,
+            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
+            ArrayList<Integer> nativePids, StringWriter logExceptionCreatingFile,
+            long[] firstPidOffsets) {
         ArrayList<Integer> extraPids = null;
 
         Slog.i(TAG, "dumpStackTraces pids=" + lastPids + " nativepids=" + nativePids);
@@ -3914,12 +3957,22 @@
             return null;
         }
 
-        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids);
+        Pair<Long, Long> offsets = dumpStackTraces(
+                tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids);
+        if (firstPidOffsets != null) {
+            if (offsets == null) {
+                firstPidOffsets[0] = firstPidOffsets[1] = -1;
+            } else {
+                firstPidOffsets[0] = offsets.first; // Start offset to the ANR trace file
+                firstPidOffsets[1] = offsets.second; // End offset to the ANR trace file
+            }
+        }
         return tracesFile;
     }
 
     @GuardedBy("ActivityManagerService.class")
     private static SimpleDateFormat sAnrFileDateFormat;
+    static final String ANR_FILE_PREFIX = "anr_";
 
     private static synchronized File createAnrDumpFile(File tracesDir) throws IOException {
         if (sAnrFileDateFormat == null) {
@@ -3927,7 +3980,7 @@
         }
 
         final String formattedDate = sAnrFileDateFormat.format(new Date());
-        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
+        final File anrFile = new File(tracesDir, ANR_FILE_PREFIX + formattedDate);
 
         if (anrFile.createNewFile()) {
             FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
@@ -3996,7 +4049,10 @@
         return SystemClock.elapsedRealtime() - timeStart;
     }
 
-    public static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
+    /**
+     * @return The start/end offset of the trace of the very first PID
+     */
+    public static Pair<Long, Long> dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids) {
 
         Slog.i(TAG, "Dumping to " + tracesFile);
@@ -4008,21 +4064,39 @@
         // We must complete all stack dumps within 20 seconds.
         long remainingTime = 20 * 1000;
 
+        // As applications are usually interested with the ANR stack traces, but we can't share with
+        // them the stack traces other than their own stacks. So after the very first PID is
+        // dumped, remember the current file size.
+        long firstPidStart = -1;
+        long firstPidEnd = -1;
+
         // First collect all of the stacks of the most important pids.
         if (firstPids != null) {
             int num = firstPids.size();
             for (int i = 0; i < num; i++) {
-                Slog.i(TAG, "Collecting stacks for pid " + firstPids.get(i));
-                final long timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile,
+                final int pid = firstPids.get(i);
+                // We don't copy ANR traces from the system_server intentionally.
+                final boolean firstPid = i == 0 && MY_PID != pid;
+                File tf = null;
+                if (firstPid) {
+                    tf = new File(tracesFile);
+                    firstPidStart = tf.exists() ? tf.length() : 0;
+                }
+
+                Slog.i(TAG, "Collecting stacks for pid " + pid);
+                final long timeTaken = dumpJavaTracesTombstoned(pid, tracesFile,
                                                                 remainingTime);
 
                 remainingTime -= timeTaken;
                 if (remainingTime <= 0) {
-                    Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
-                           "); deadline exceeded.");
-                    return;
+                    Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + pid
+                            + "); deadline exceeded.");
+                    return firstPidStart >= 0 ? new Pair<>(firstPidStart, firstPidEnd) : null;
                 }
 
+                if (firstPid) {
+                    firstPidEnd = tf.length();
+                }
                 if (DEBUG_ANR) {
                     Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
                 }
@@ -4044,7 +4118,7 @@
                 if (remainingTime <= 0) {
                     Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
                         "); deadline exceeded.");
-                    return;
+                    return firstPidStart >= 0 ? new Pair<>(firstPidStart, firstPidEnd) : null;
                 }
 
                 if (DEBUG_ANR) {
@@ -4064,7 +4138,7 @@
                 if (remainingTime <= 0) {
                     Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
                             "); deadline exceeded.");
-                    return;
+                    return firstPidStart >= 0 ? new Pair<>(firstPidStart, firstPidEnd) : null;
                 }
 
                 if (DEBUG_ANR) {
@@ -4073,6 +4147,7 @@
             }
         }
         Slog.i(TAG, "Done dumping");
+        return firstPidStart >= 0 ? new Pair<>(firstPidStart, firstPidEnd) : null;
     }
 
     @Override
@@ -10256,6 +10331,15 @@
         return new ParceledListSlice<ApplicationExitInfo>(results);
     }
 
+    @Override
+    public void setProcessStateSummary(@Nullable byte[] state) {
+        if (state != null && state.length > MAX_STATE_DATA_SIZE) {
+            throw new IllegalArgumentException("Data size is too large");
+        }
+        mProcessList.mAppExitInfoTracker.setProcessStateSummary(Binder.getCallingUid(),
+                Binder.getCallingPid(), state);
+    }
+
     /**
      * Check if the calling process has the permission to dump given package,
      * throw SecurityException if it doesn't have the permission.
@@ -10263,7 +10347,7 @@
      * @return The UID of the given package, or {@link android.os.Process#INVALID_UID}
      *         if the package is not found.
      */
-    private int enforceDumpPermissionForPackage(String packageName, int userId, int callingUid,
+    int enforceDumpPermissionForPackage(String packageName, int userId, int callingUid,
             String function) {
         long identity = Binder.clearCallingIdentity();
         int uid = Process.INVALID_UID;
@@ -19818,6 +19902,7 @@
 
         void setPermissions(@Nullable String[] permissions) {
             mPermissions = permissions;
+            PackageManager.invalidatePackageInfoCache();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java
index 028a059..0c3d02d 100644
--- a/services/core/java/com/android/server/am/AppExitInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java
@@ -17,23 +17,31 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.RunningAppProcessInfo.procStateToImportance;
+import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
 
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
+import android.annotation.Nullable;
 import android.app.ApplicationExitInfo;
 import android.app.ApplicationExitInfo.Reason;
 import android.app.ApplicationExitInfo.SubReason;
+import android.app.IAppTraceRetriever;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.icu.text.SimpleDateFormat;
+import android.os.Binder;
+import android.os.FileUtils;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.system.OsConstants;
@@ -52,12 +60,17 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ProcessMap;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.IoThread;
 import com.android.server.ServiceThread;
 import com.android.server.SystemServiceManager;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -68,6 +81,10 @@
 import java.util.concurrent.TimeUnit;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.zip.GZIPOutputStream;
 
 /**
  * A class to manage all the {@link android.app.ApplicationExitInfo} records.
@@ -80,16 +97,21 @@
      */
     private static final long APP_EXIT_INFO_PERSIST_INTERVAL = TimeUnit.MINUTES.toMillis(30);
 
-    /** These are actions that the forEachPackage should take after each iteration */
+    /** These are actions that the forEach* should take after each iteration */
     private static final int FOREACH_ACTION_NONE = 0;
-    private static final int FOREACH_ACTION_REMOVE_PACKAGE = 1;
+    private static final int FOREACH_ACTION_REMOVE_ITEM = 1;
     private static final int FOREACH_ACTION_STOP_ITERATION = 2;
 
     private static final int APP_EXIT_RAW_INFO_POOL_SIZE = 8;
 
     @VisibleForTesting
+    static final String APP_EXIT_STORE_DIR = "procexitstore";
+
+    @VisibleForTesting
     static final String APP_EXIT_INFO_FILE = "procexitinfo";
 
+    private static final String APP_TRACE_FILE_SUFFIX = ".gz";
+
     private final Object mLock = new Object();
 
     /**
@@ -153,6 +175,13 @@
     final ArrayList<ApplicationExitInfo> mTmpInfoList2 = new ArrayList<ApplicationExitInfo>();
 
     /**
+     * The path to the directory which includes the historical proc exit info file
+     * as specified in {@link #mProcExitInfoFile}, as well as the associated trace files.
+     */
+    @VisibleForTesting
+    File mProcExitStoreDir;
+
+    /**
      * The path to the historical proc exit info file, persisted in the storage.
      */
     @VisibleForTesting
@@ -176,6 +205,35 @@
     final AppExitInfoExternalSource mAppExitInfoSourceLmkd =
             new AppExitInfoExternalSource("lmkd", ApplicationExitInfo.REASON_LOW_MEMORY);
 
+    /**
+     * The active per-UID/PID state data set by
+     * {@link android.app.ActivityManager#setProcessStateSummary};
+     * these state data are to be "claimed" when its process dies, by then the data will be moved
+     * from this list to the new instance of ApplicationExitInfo.
+     *
+     * <p> The mapping here is UID -> PID -> state </p>
+     *
+     * @see android.app.ActivityManager#setProcessStateSummary(byte[])
+     */
+    @GuardedBy("mLock")
+    final SparseArray<SparseArray<byte[]>> mActiveAppStateSummary = new SparseArray<>();
+
+    /**
+     * The active per-UID/PID trace file when an ANR occurs but the process hasn't been killed yet,
+     * each record is a path to the actual trace file;  these files are to be "claimed"
+     * when its process dies, by then the "ownership" of the files will be transferred
+     * from this list to the new instance of ApplicationExitInfo.
+     *
+     * <p> The mapping here is UID -> PID -> file </p>
+     */
+    @GuardedBy("mLock")
+    final SparseArray<SparseArray<File>> mActiveAppTraces = new SparseArray<>();
+
+    /**
+     * The implementation of the interface IAppTraceRetriever.
+     */
+    final AppTraceRetriever mAppTraceRetriever = new AppTraceRetriever();
+
     AppExitInfoTracker() {
         mData = new ProcessMap<AppExitInfoContainer>();
         mRawRecordsPool = new SynchronizedPool<ApplicationExitInfo>(APP_EXIT_RAW_INFO_POOL_SIZE);
@@ -187,7 +245,13 @@
                 THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
         thread.start();
         mKillHandler = new KillHandler(thread.getLooper());
-        mProcExitInfoFile = new File(SystemServiceManager.ensureSystemDir(), APP_EXIT_INFO_FILE);
+
+        mProcExitStoreDir = new File(SystemServiceManager.ensureSystemDir(), APP_EXIT_STORE_DIR);
+        if (!FileUtils.createDir(mProcExitStoreDir)) {
+            Slog.e(TAG, "Unable to create " + mProcExitStoreDir);
+            return;
+        }
+        mProcExitInfoFile = new File(mProcExitStoreDir, APP_EXIT_INFO_FILE);
 
         mAppExitInfoHistoryListSize = service.mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_app_exit_info_history_list_size);
@@ -304,7 +368,7 @@
                         + "(" + raw.getPid() + "/u" + raw.getRealUid() + ")");
             }
 
-            ApplicationExitInfo info = getExitInfo(raw.getPackageName(),
+            ApplicationExitInfo info = getExitInfoLocked(raw.getPackageName(),
                     raw.getPackageUid(), raw.getPid());
 
             // query zygote and lmkd to get the exit info, and clear the saved info
@@ -312,7 +376,7 @@
                     raw.getPid(), raw.getRealUid());
             Pair<Long, Object> lmkd = mAppExitInfoSourceLmkd.remove(
                     raw.getPid(), raw.getRealUid());
-            mIsolatedUidRecords.removeIsolatedUid(raw.getRealUid());
+            mIsolatedUidRecords.removeIsolatedUidLocked(raw.getRealUid());
 
             if (info == null) {
                 info = addExitInfoLocked(raw);
@@ -333,7 +397,7 @@
     @VisibleForTesting
     @GuardedBy("mLock")
     void handleNoteAppKillLocked(final ApplicationExitInfo raw) {
-        ApplicationExitInfo info = getExitInfo(
+        ApplicationExitInfo info = getExitInfoLocked(
                 raw.getPackageName(), raw.getPackageUid(), raw.getPid());
 
         if (info == null) {
@@ -359,7 +423,7 @@
         final String[] packages = raw.getPackageList();
         final int uid = raw.getPackageUid();
         for (int i = 0; i < packages.length; i++) {
-            addExitInfoInner(packages[i], uid, info);
+            addExitInfoInnerLocked(packages[i], uid, info);
         }
 
         schedulePersistProcessExitInfo(false);
@@ -400,39 +464,37 @@
      *
      * @return true if a recond is updated
      */
-    private boolean updateExitInfoIfNecessary(int pid, int uid, Integer status, Integer reason) {
-        synchronized (mLock) {
-            if (UserHandle.isIsolated(uid)) {
-                Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
-                if (k != null) {
-                    uid = k;
-                }
-            }
-            ArrayList<ApplicationExitInfo> tlist = mTmpInfoList;
-            tlist.clear();
-            final int targetUid = uid;
-            forEachPackage((packageName, records) -> {
-                AppExitInfoContainer container = records.get(targetUid);
-                if (container == null) {
-                    return FOREACH_ACTION_NONE;
-                }
-                tlist.clear();
-                container.getExitInfoLocked(pid, 1, tlist);
-                if (tlist.size() == 0) {
-                    return FOREACH_ACTION_NONE;
-                }
-                ApplicationExitInfo info = tlist.get(0);
-                if (info.getRealUid() != targetUid) {
-                    tlist.clear();
-                    return FOREACH_ACTION_NONE;
-                }
-                // Okay found it, update its reason.
-                updateExistingExitInfoRecordLocked(info, status, reason);
-
-                return FOREACH_ACTION_STOP_ITERATION;
-            });
-            return tlist.size() > 0;
+    @GuardedBy("mLock")
+    private boolean updateExitInfoIfNecessaryLocked(
+            int pid, int uid, Integer status, Integer reason) {
+        Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+        if (k != null) {
+            uid = k;
         }
+        ArrayList<ApplicationExitInfo> tlist = mTmpInfoList;
+        tlist.clear();
+        final int targetUid = uid;
+        forEachPackageLocked((packageName, records) -> {
+            AppExitInfoContainer container = records.get(targetUid);
+            if (container == null) {
+                return FOREACH_ACTION_NONE;
+            }
+            tlist.clear();
+            container.getExitInfoLocked(pid, 1, tlist);
+            if (tlist.size() == 0) {
+                return FOREACH_ACTION_NONE;
+            }
+            ApplicationExitInfo info = tlist.get(0);
+            if (info.getRealUid() != targetUid) {
+                tlist.clear();
+                return FOREACH_ACTION_NONE;
+            }
+            // Okay found it, update its reason.
+            updateExistingExitInfoRecordLocked(info, status, reason);
+
+            return FOREACH_ACTION_STOP_ITERATION;
+        });
+        return tlist.size() > 0;
     }
 
     /**
@@ -441,38 +503,43 @@
     @VisibleForTesting
     void getExitInfo(final String packageName, final int filterUid,
             final int filterPid, final int maxNum, final ArrayList<ApplicationExitInfo> results) {
-        synchronized (mLock) {
-            boolean emptyPackageName = TextUtils.isEmpty(packageName);
-            if (!emptyPackageName) {
-                // fast path
-                AppExitInfoContainer container = mData.get(packageName, filterUid);
-                if (container != null) {
-                    container.getExitInfoLocked(filterPid, maxNum, results);
-                }
-            } else {
-                // slow path
-                final ArrayList<ApplicationExitInfo> list = mTmpInfoList2;
-                list.clear();
-                // get all packages
-                forEachPackage((name, records) -> {
-                    AppExitInfoContainer container = records.get(filterUid);
+        long identity = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                boolean emptyPackageName = TextUtils.isEmpty(packageName);
+                if (!emptyPackageName) {
+                    // fast path
+                    AppExitInfoContainer container = mData.get(packageName, filterUid);
                     if (container != null) {
-                        mTmpInfoList.clear();
-                        results.addAll(container.toListLocked(mTmpInfoList, filterPid));
+                        container.getExitInfoLocked(filterPid, maxNum, results);
                     }
-                    return AppExitInfoTracker.FOREACH_ACTION_NONE;
-                });
+                } else {
+                    // slow path
+                    final ArrayList<ApplicationExitInfo> list = mTmpInfoList2;
+                    list.clear();
+                    // get all packages
+                    forEachPackageLocked((name, records) -> {
+                        AppExitInfoContainer container = records.get(filterUid);
+                        if (container != null) {
+                            mTmpInfoList.clear();
+                            results.addAll(container.toListLocked(mTmpInfoList, filterPid));
+                        }
+                        return AppExitInfoTracker.FOREACH_ACTION_NONE;
+                    });
 
-                Collections.sort(list, (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
-                int size = list.size();
-                if (maxNum > 0) {
-                    size = Math.min(size, maxNum);
+                    Collections.sort(list, (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
+                    int size = list.size();
+                    if (maxNum > 0) {
+                        size = Math.min(size, maxNum);
+                    }
+                    for (int i = 0; i < size; i++) {
+                        results.add(list.get(i));
+                    }
+                    list.clear();
                 }
-                for (int i = 0; i < size; i++) {
-                    results.add(list.get(i));
-                }
-                list.clear();
             }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
         }
     }
 
@@ -480,17 +547,16 @@
      * Return the first matching exit info record, for internal use, the parameters are not supposed
      * to be empty.
      */
-    private ApplicationExitInfo getExitInfo(final String packageName,
+    @GuardedBy("mLock")
+    private ApplicationExitInfo getExitInfoLocked(final String packageName,
             final int filterUid, final int filterPid) {
-        synchronized (mLock) {
-            ArrayList<ApplicationExitInfo> list = mTmpInfoList;
-            list.clear();
-            getExitInfo(packageName, filterUid, filterPid, 1, list);
+        ArrayList<ApplicationExitInfo> list = mTmpInfoList;
+        list.clear();
+        getExitInfo(packageName, filterUid, filterPid, 1, list);
 
-            ApplicationExitInfo info = list.size() > 0 ? list.get(0) : null;
-            list.clear();
-            return info;
-        }
+        ApplicationExitInfo info = list.size() > 0 ? list.get(0) : null;
+        list.clear();
+        return info;
     }
 
     @VisibleForTesting
@@ -498,8 +564,10 @@
         mAppExitInfoSourceZygote.removeByUserId(userId);
         mAppExitInfoSourceLmkd.removeByUserId(userId);
         mIsolatedUidRecords.removeByUserId(userId);
-        removeByUserId(userId);
-        schedulePersistProcessExitInfo(true);
+        synchronized (mLock) {
+            removeByUserIdLocked(userId);
+            schedulePersistProcessExitInfo(true);
+        }
     }
 
     @VisibleForTesting
@@ -507,13 +575,16 @@
         if (packageName != null) {
             final boolean removeUid = TextUtils.isEmpty(
                     mService.mPackageManagerInt.getNameForUid(uid));
-            if (removeUid) {
-                mAppExitInfoSourceZygote.removeByUid(uid, allUsers);
-                mAppExitInfoSourceLmkd.removeByUid(uid, allUsers);
-                mIsolatedUidRecords.removeAppUid(uid, allUsers);
+            synchronized (mLock) {
+                if (removeUid) {
+                    mAppExitInfoSourceZygote.removeByUidLocked(uid, allUsers);
+                    mAppExitInfoSourceLmkd.removeByUidLocked(uid, allUsers);
+                    mIsolatedUidRecords.removeAppUid(uid, allUsers);
+                }
+                removePackageLocked(packageName, uid, removeUid,
+                        allUsers ? UserHandle.USER_ALL : UserHandle.getUserId(uid));
+                schedulePersistProcessExitInfo(true);
             }
-            removePackage(packageName, allUsers ? UserHandle.USER_ALL : UserHandle.getUserId(uid));
-            schedulePersistProcessExitInfo(true);
         }
     }
 
@@ -593,6 +664,7 @@
             }
         }
         synchronized (mLock) {
+            pruneAnrTracesIfNecessaryLocked();
             mAppExitInfoLoaded = true;
         }
     }
@@ -634,7 +706,7 @@
             ProtoOutputStream proto = new ProtoOutputStream(out);
             proto.write(AppsExitInfoProto.LAST_UPDATE_TIMESTAMP, now);
             synchronized (mLock) {
-                forEachPackage((packageName, records) -> {
+                forEachPackageLocked((packageName, records) -> {
                     long token = proto.start(AppsExitInfoProto.PACKAGES);
                     proto.write(AppsExitInfoProto.Package.PACKAGE_NAME, packageName);
                     int uidArraySize = records.size();
@@ -688,6 +760,9 @@
                 mProcExitInfoFile.delete();
             }
             mData.getMap().clear();
+            mActiveAppStateSummary.clear();
+            mActiveAppTraces.clear();
+            pruneAnrTracesIfNecessaryLocked();
         }
     }
 
@@ -695,15 +770,15 @@
      * Helper function for shell command
      */
     void clearHistoryProcessExitInfo(String packageName, int userId) {
-        synchronized (mLock) {
-            if (TextUtils.isEmpty(packageName)) {
-                if (userId == UserHandle.USER_ALL) {
-                    mData.getMap().clear();
-                } else {
-                    removeByUserId(userId);
-                }
-            } else {
-                removePackage(packageName, userId);
+        if (TextUtils.isEmpty(packageName)) {
+            synchronized (mLock) {
+                removeByUserIdLocked(userId);
+            }
+        } else {
+            final int uid = mService.mPackageManagerInt.getPackageUid(packageName,
+                    PackageManager.MATCH_ALL, userId);
+            synchronized (mLock) {
+                removePackageLocked(packageName, uid, true, userId);
             }
         }
         schedulePersistProcessExitInfo(true);
@@ -716,7 +791,7 @@
             pw.println("Last Timestamp of Persistence Into Persistent Storage: "
                     + sdf.format(new Date(mLastAppExitInfoPersistTimestamp)));
             if (TextUtils.isEmpty(packageName)) {
-                forEachPackage((name, records) -> {
+                forEachPackageLocked((name, records) -> {
                     dumpHistoryProcessExitInfoLocked(pw, "  ", name, records, sdf);
                     return AppExitInfoTracker.FOREACH_ACTION_NONE;
                 });
@@ -741,86 +816,108 @@
         }
     }
 
-    private void addExitInfoInner(String packageName, int userId, ApplicationExitInfo info) {
-        synchronized (mLock) {
-            AppExitInfoContainer container = mData.get(packageName, userId);
-            if (container == null) {
-                container = new AppExitInfoContainer(mAppExitInfoHistoryListSize);
-                if (UserHandle.isIsolated(info.getRealUid())) {
-                    Integer k = mIsolatedUidRecords.getUidByIsolatedUid(info.getRealUid());
-                    if (k != null) {
-                        container.mUid = k;
-                    }
-                } else {
-                    container.mUid = info.getRealUid();
+    @GuardedBy("mLock")
+    private void addExitInfoInnerLocked(String packageName, int userId, ApplicationExitInfo info) {
+        AppExitInfoContainer container = mData.get(packageName, userId);
+        if (container == null) {
+            container = new AppExitInfoContainer(mAppExitInfoHistoryListSize);
+            if (UserHandle.isIsolated(info.getRealUid())) {
+                Integer k = mIsolatedUidRecords.getUidByIsolatedUid(info.getRealUid());
+                if (k != null) {
+                    container.mUid = k;
                 }
-                mData.put(packageName, userId, container);
+            } else {
+                container.mUid = info.getRealUid();
             }
-            container.addExitInfoLocked(info);
+            mData.put(packageName, userId, container);
         }
+        container.addExitInfoLocked(info);
     }
 
-    private void forEachPackage(
+    @GuardedBy("mLocked")
+    private void forEachPackageLocked(
             BiFunction<String, SparseArray<AppExitInfoContainer>, Integer> callback) {
         if (callback != null) {
-            synchronized (mLock) {
-                ArrayMap<String, SparseArray<AppExitInfoContainer>> map = mData.getMap();
-                for (int i = map.size() - 1; i >= 0; i--) {
-                    switch (callback.apply(map.keyAt(i), map.valueAt(i))) {
-                        case FOREACH_ACTION_REMOVE_PACKAGE:
-                            map.removeAt(i);
-                            break;
-                        case FOREACH_ACTION_STOP_ITERATION:
-                            i = 0;
-                            break;
-                        case FOREACH_ACTION_NONE:
-                        default:
-                            break;
-                    }
-                }
-            }
-        }
-    }
-
-    private void removePackage(String packageName, int userId) {
-        synchronized (mLock) {
-            if (userId == UserHandle.USER_ALL) {
-                mData.getMap().remove(packageName);
-            } else {
-                ArrayMap<String, SparseArray<AppExitInfoContainer>> map =
-                        mData.getMap();
-                SparseArray<AppExitInfoContainer> array = map.get(packageName);
-                if (array == null) {
-                    return;
-                }
-                for (int i = array.size() - 1; i >= 0; i--) {
-                    if (UserHandle.getUserId(array.keyAt(i)) == userId) {
-                        array.removeAt(i);
+            ArrayMap<String, SparseArray<AppExitInfoContainer>> map = mData.getMap();
+            for (int i = map.size() - 1; i >= 0; i--) {
+                switch (callback.apply(map.keyAt(i), map.valueAt(i))) {
+                    case FOREACH_ACTION_REMOVE_ITEM:
+                        final SparseArray<AppExitInfoContainer> records = map.valueAt(i);
+                        for (int j = records.size() - 1; j >= 0; j--) {
+                            records.valueAt(j).destroyLocked();
+                        }
+                        map.removeAt(i);
                         break;
-                    }
-                }
-                if (array.size() == 0) {
-                    map.remove(packageName);
+                    case FOREACH_ACTION_STOP_ITERATION:
+                        i = 0;
+                        break;
+                    case FOREACH_ACTION_NONE:
+                    default:
+                        break;
                 }
             }
         }
     }
 
-    private void removeByUserId(final int userId) {
-        if (userId == UserHandle.USER_ALL) {
-            synchronized (mLock) {
-                mData.getMap().clear();
+    @GuardedBy("mLocked")
+    private void removePackageLocked(String packageName, int uid, boolean removeUid, int userId) {
+        if (removeUid) {
+            mActiveAppStateSummary.remove(uid);
+            final int idx = mActiveAppTraces.indexOfKey(uid);
+            if (idx >= 0) {
+                final SparseArray<File> array = mActiveAppTraces.valueAt(idx);
+                for (int i = array.size() - 1; i >= 0; i--) {
+                    array.valueAt(i).delete();
+                }
+                mActiveAppTraces.removeAt(idx);
             }
+        }
+        ArrayMap<String, SparseArray<AppExitInfoContainer>> map = mData.getMap();
+        SparseArray<AppExitInfoContainer> array = map.get(packageName);
+        if (array == null) {
             return;
         }
-        forEachPackage((packageName, records) -> {
+        if (userId == UserHandle.USER_ALL) {
+            for (int i = array.size() - 1; i >= 0; i--) {
+                array.valueAt(i).destroyLocked();
+            }
+            mData.getMap().remove(packageName);
+        } else {
+            for (int i = array.size() - 1; i >= 0; i--) {
+                if (UserHandle.getUserId(array.keyAt(i)) == userId) {
+                    array.valueAt(i).destroyLocked();
+                    array.removeAt(i);
+                    break;
+                }
+            }
+            if (array.size() == 0) {
+                map.remove(packageName);
+            }
+        }
+    }
+
+    @GuardedBy("mLocked")
+    private void removeByUserIdLocked(final int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            mData.getMap().clear();
+            mActiveAppStateSummary.clear();
+            mActiveAppTraces.clear();
+            pruneAnrTracesIfNecessaryLocked();
+            return;
+        }
+        removeFromSparse2dArray(mActiveAppStateSummary,
+                (v) -> UserHandle.getUserId(v) == userId, null, null);
+        removeFromSparse2dArray(mActiveAppTraces,
+                (v) -> UserHandle.getUserId(v) == userId, null, (v) -> v.delete());
+        forEachPackageLocked((packageName, records) -> {
             for (int i = records.size() - 1; i >= 0; i--) {
                 if (UserHandle.getUserId(records.keyAt(i)) == userId) {
+                    records.valueAt(i).destroyLocked();
                     records.removeAt(i);
                     break;
                 }
             }
-            return records.size() == 0 ? FOREACH_ACTION_REMOVE_PACKAGE : FOREACH_ACTION_NONE;
+            return records.size() == 0 ? FOREACH_ACTION_REMOVE_ITEM : FOREACH_ACTION_NONE;
         });
     }
 
@@ -862,6 +959,262 @@
     }
 
     /**
+     * Called from {@link ActivityManagerService#setProcessStateSummary}.
+     */
+    @VisibleForTesting
+    void setProcessStateSummary(int uid, final int pid, final byte[] data) {
+        synchronized (mLock) {
+            Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+            if (k != null) {
+                uid = k;
+            }
+            putToSparse2dArray(mActiveAppStateSummary, uid, pid, data, SparseArray::new, null);
+        }
+    }
+
+    @VisibleForTesting
+    @Nullable byte[] getProcessStateSummary(int uid, final int pid) {
+        synchronized (mLock) {
+            Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+            if (k != null) {
+                uid = k;
+            }
+            int index = mActiveAppStateSummary.indexOfKey(uid);
+            if (index < 0) {
+                return null;
+            }
+            return mActiveAppStateSummary.valueAt(index).get(pid);
+        }
+    }
+
+    /**
+     * Called from ProcessRecord when an ANR occurred and the ANR trace is taken.
+     */
+    void scheduleLogAnrTrace(final int pid, final int uid, final String[] packageList,
+            final File traceFile, final long startOff, final long endOff) {
+        mKillHandler.sendMessage(PooledLambda.obtainMessage(
+                this::handleLogAnrTrace, pid, uid, packageList,
+                traceFile, startOff, endOff));
+    }
+
+    /**
+     * Copy and compress the given ANR trace file
+     */
+    @VisibleForTesting
+    void handleLogAnrTrace(final int pid, int uid, final String[] packageList,
+            final File traceFile, final long startOff, final long endOff) {
+        if (!traceFile.exists() || ArrayUtils.isEmpty(packageList)) {
+            return;
+        }
+        final long size = traceFile.length();
+        final long length = endOff - startOff;
+        if (startOff >= size || endOff > size || length <= 0) {
+            return;
+        }
+
+        final File outFile = new File(mProcExitStoreDir, traceFile.getName()
+                + APP_TRACE_FILE_SUFFIX);
+        // Copy & compress
+        if (copyToGzFile(traceFile, outFile, startOff, length)) {
+            // Wrote successfully.
+            synchronized (mLock) {
+                Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+                if (k != null) {
+                    uid = k;
+                }
+                if (DEBUG_PROCESSES) {
+                    Slog.i(TAG, "Stored ANR traces of " + pid + "/u" + uid + " in " + outFile);
+                }
+                boolean pending = true;
+                // Unlikely but possible: the app has died
+                for (int i = 0; i < packageList.length; i++) {
+                    final AppExitInfoContainer container = mData.get(packageList[i], uid);
+                    // Try to see if we could append this trace to an existing record
+                    if (container != null && container.appendTraceIfNecessaryLocked(pid, outFile)) {
+                        // Okay someone took it
+                        pending = false;
+                    }
+                }
+                if (pending) {
+                    // Save it into a temporary list for later use (when the app dies).
+                    putToSparse2dArray(mActiveAppTraces, uid, pid, outFile,
+                            SparseArray::new, (v) -> v.delete());
+                }
+            }
+        }
+    }
+
+    /**
+     * Copy the given portion of the file into a gz file.
+     *
+     * @param inFile The source file.
+     * @param outFile The destination file, which will be compressed in gzip format.
+     * @param start The start offset where the copy should start from.
+     * @param length The number of bytes that should be copied.
+     * @return If the copy was successful or not.
+     */
+    private static boolean copyToGzFile(final File inFile, final File outFile,
+            final long start, final long length) {
+        long remaining = length;
+        try (
+            BufferedInputStream in = new BufferedInputStream(new FileInputStream(inFile));
+            GZIPOutputStream out = new GZIPOutputStream(new BufferedOutputStream(
+                    new FileOutputStream(outFile)))) {
+            final byte[] buffer = new byte[8192];
+            in.skip(start);
+            while (remaining > 0) {
+                int t = in.read(buffer, 0, (int) Math.min(buffer.length, remaining));
+                if (t < 0) {
+                    break;
+                }
+                out.write(buffer, 0, t);
+                remaining -= t;
+            }
+        } catch (IOException e) {
+            if (DEBUG_PROCESSES) {
+                Slog.e(TAG, "Error in copying ANR trace from " + inFile + " to " + outFile, e);
+            }
+            return false;
+        }
+        return remaining == 0 && outFile.exists();
+    }
+
+    /**
+     * In case there is any orphan ANR trace file, remove it.
+     */
+    @GuardedBy("mLock")
+    private void pruneAnrTracesIfNecessaryLocked() {
+        final ArraySet<String> allFiles = new ArraySet();
+        final File[] files = mProcExitStoreDir.listFiles((f) -> {
+            final String name = f.getName();
+            boolean trace = name.startsWith(ActivityManagerService.ANR_FILE_PREFIX)
+                    && name.endsWith(APP_TRACE_FILE_SUFFIX);
+            if (trace) {
+                allFiles.add(name);
+            }
+            return trace;
+        });
+        if (ArrayUtils.isEmpty(files)) {
+            return;
+        }
+        // Find out the owners from the existing records
+        forEachPackageLocked((name, records) -> {
+            for (int i = records.size() - 1; i >= 0; i--) {
+                final AppExitInfoContainer container = records.valueAt(i);
+                container.forEachRecordLocked((pid, info) -> {
+                    final File traceFile = info.getTraceFile();
+                    if (traceFile != null) {
+                        allFiles.remove(traceFile.getName());
+                    }
+                    return FOREACH_ACTION_NONE;
+                });
+            }
+            return AppExitInfoTracker.FOREACH_ACTION_NONE;
+        });
+        // See if there is any active process owns it.
+        forEachSparse2dArray(mActiveAppTraces, (v) -> allFiles.remove(v.getName()));
+
+        // Remove orphan traces if nobody claims it.
+        for (int i = allFiles.size() - 1; i >= 0; i--) {
+            (new File(mProcExitStoreDir, allFiles.valueAt(i))).delete();
+        }
+    }
+
+    /**
+     * A utility function to add the given value to the given 2d SparseArray
+     */
+    private static <T extends SparseArray<U>, U> void putToSparse2dArray(final SparseArray<T> array,
+            final int outerKey, final int innerKey, final U value, final Supplier<T> newInstance,
+            final Consumer<U> actionToOldValue) {
+        int idx = array.indexOfKey(outerKey);
+        T innerArray = null;
+        if (idx < 0) {
+            innerArray = newInstance.get();
+            array.put(outerKey, innerArray);
+        } else {
+            innerArray = array.valueAt(idx);
+        }
+        idx = innerArray.indexOfKey(innerKey);
+        if (idx >= 0) {
+            if (actionToOldValue != null) {
+                actionToOldValue.accept(innerArray.valueAt(idx));
+            }
+            innerArray.setValueAt(idx, value);
+        } else {
+            innerArray.put(innerKey, value);
+        }
+    }
+
+    /**
+     * A utility function to iterate through the given 2d SparseArray
+     */
+    private static <T extends SparseArray<U>, U> void forEachSparse2dArray(
+            final SparseArray<T> array, final Consumer<U> action) {
+        if (action != null) {
+            for (int i = array.size() - 1; i >= 0; i--) {
+                T innerArray = array.valueAt(i);
+                if (innerArray == null) {
+                    continue;
+                }
+                for (int j = innerArray.size() - 1; j >= 0; j--) {
+                    action.accept(innerArray.valueAt(j));
+                }
+            }
+        }
+    }
+
+    /**
+     * A utility function to remove elements from the given 2d SparseArray
+     */
+    private static <T extends SparseArray<U>, U> void removeFromSparse2dArray(
+            final SparseArray<T> array, final Predicate<Integer> outerPredicate,
+            final Predicate<Integer> innerPredicate, final Consumer<U> action) {
+        for (int i = array.size() - 1; i >= 0; i--) {
+            if (outerPredicate == null || outerPredicate.test(array.keyAt(i))) {
+                final T innerArray = array.valueAt(i);
+                if (innerArray == null) {
+                    continue;
+                }
+                for (int j = innerArray.size() - 1; j >= 0; j--) {
+                    if (innerPredicate == null || innerPredicate.test(innerArray.keyAt(j))) {
+                        if (action != null) {
+                            action.accept(innerArray.valueAt(j));
+                        }
+                        innerArray.removeAt(j);
+                    }
+                }
+                if (innerArray.size() == 0) {
+                    array.removeAt(i);
+                }
+            }
+        }
+    }
+
+    /**
+     * A utility function to find and remove elements from the given 2d SparseArray.
+     */
+    private static <T extends SparseArray<U>, U> U findAndRemoveFromSparse2dArray(
+            final SparseArray<T> array, final int outerKey, final int innerKey) {
+        final int idx = array.indexOfKey(outerKey);
+        if (idx >= 0) {
+            T p = array.valueAt(idx);
+            if (p == null) {
+                return null;
+            }
+            final int innerIdx = p.indexOfKey(innerKey);
+            if (innerIdx >= 0) {
+                final U ret = p.valueAt(innerIdx);
+                p.removeAt(innerIdx);
+                if (p.size() == 0) {
+                    array.removeAt(idx);
+                }
+                return ret;
+            }
+        }
+        return null;
+    }
+
+    /**
      * A container class of {@link android.app.ApplicationExitInfo}
      */
     final class AppExitInfoContainer {
@@ -934,10 +1287,68 @@
                     }
                 }
                 if (oldestIndex >= 0) {
+                    final File traceFile = mInfos.valueAt(oldestIndex).getTraceFile();
+                    if (traceFile != null) {
+                        traceFile.delete();
+                    }
                     mInfos.removeAt(oldestIndex);
                 }
             }
-            mInfos.append(info.getPid(), info);
+            // Claim the state information if there is any
+            final int uid = info.getPackageUid();
+            final int pid = info.getPid();
+            info.setProcessStateSummary(findAndRemoveFromSparse2dArray(
+                    mActiveAppStateSummary, uid, pid));
+            info.setTraceFile(findAndRemoveFromSparse2dArray(mActiveAppTraces, uid, pid));
+            info.setAppTraceRetriever(mAppTraceRetriever);
+            mInfos.append(pid, info);
+        }
+
+        @GuardedBy("mLock")
+        boolean appendTraceIfNecessaryLocked(final int pid, final File traceFile) {
+            final ApplicationExitInfo r = mInfos.get(pid);
+            if (r != null) {
+                r.setTraceFile(traceFile);
+                r.setAppTraceRetriever(mAppTraceRetriever);
+                return true;
+            }
+            return false;
+        }
+
+        @GuardedBy("mLock")
+        void destroyLocked() {
+            for (int i = mInfos.size() - 1; i >= 0; i--) {
+                ApplicationExitInfo ai = mInfos.valueAt(i);
+                final File traceFile = ai.getTraceFile();
+                if (traceFile != null) {
+                    traceFile.delete();
+                }
+                ai.setTraceFile(null);
+                ai.setAppTraceRetriever(null);
+            }
+        }
+
+        @GuardedBy("mLock")
+        void forEachRecordLocked(final BiFunction<Integer, ApplicationExitInfo, Integer> callback) {
+            if (callback != null) {
+                for (int i = mInfos.size() - 1; i >= 0; i--) {
+                    switch (callback.apply(mInfos.keyAt(i), mInfos.valueAt(i))) {
+                        case FOREACH_ACTION_REMOVE_ITEM:
+                            final File traceFile = mInfos.valueAt(i).getTraceFile();
+                            if (traceFile != null) {
+                                traceFile.delete();
+                            }
+                            mInfos.removeAt(i);
+                            break;
+                        case FOREACH_ACTION_STOP_ITERATION:
+                            i = 0;
+                            break;
+                        case FOREACH_ACTION_NONE:
+                        default:
+                            break;
+                    }
+                }
+            }
         }
 
         @GuardedBy("mLock")
@@ -1033,6 +1444,7 @@
             }
         }
 
+        @GuardedBy("mLock")
         Integer getUidByIsolatedUid(int isolatedUid) {
             if (UserHandle.isIsolated(isolatedUid)) {
                 synchronized (mLock) {
@@ -1053,6 +1465,7 @@
             }
         }
 
+        @VisibleForTesting
         void removeAppUid(int uid, boolean allUsers) {
             synchronized (mLock) {
                 if (allUsers) {
@@ -1071,23 +1484,22 @@
             }
         }
 
-        int removeIsolatedUid(int isolatedUid) {
+        @GuardedBy("mLock")
+        int removeIsolatedUidLocked(int isolatedUid) {
             if (!UserHandle.isIsolated(isolatedUid)) {
                 return isolatedUid;
             }
-            synchronized (mLock) {
-                int uid = mIsolatedUidToUidMap.get(isolatedUid, -1);
-                if (uid == -1) {
-                    return isolatedUid;
-                }
-                mIsolatedUidToUidMap.remove(isolatedUid);
-                ArraySet<Integer> set = mUidToIsolatedUidMap.get(uid);
-                if (set != null) {
-                    set.remove(isolatedUid);
-                }
-                // let the ArraySet stay in the mUidToIsolatedUidMap even if it's empty
-                return uid;
+            int uid = mIsolatedUidToUidMap.get(isolatedUid, -1);
+            if (uid == -1) {
+                return isolatedUid;
             }
+            mIsolatedUidToUidMap.remove(isolatedUid);
+            ArraySet<Integer> set = mUidToIsolatedUidMap.get(uid);
+            if (set != null) {
+                set.remove(isolatedUid);
+            }
+            // let the ArraySet stay in the mUidToIsolatedUidMap even if it's empty
+            return uid;
         }
 
         void removeByUserId(int userId) {
@@ -1193,33 +1605,29 @@
             mPresetReason = reason;
         }
 
-        void add(int pid, int uid, Object extra) {
-            if (UserHandle.isIsolated(uid)) {
-                Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
-                if (k != null) {
-                    uid = k;
-                }
+        @GuardedBy("mLock")
+        private void addLocked(int pid, int uid, Object extra) {
+            Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+            if (k != null) {
+                uid = k;
             }
 
-            synchronized (mLock) {
-                SparseArray<Pair<Long, Object>> array = mData.get(uid);
-                if (array == null) {
-                    array = new SparseArray<Pair<Long, Object>>();
-                    mData.put(uid, array);
-                }
-                array.put(pid, new Pair<Long, Object>(System.currentTimeMillis(), extra));
+            SparseArray<Pair<Long, Object>> array = mData.get(uid);
+            if (array == null) {
+                array = new SparseArray<Pair<Long, Object>>();
+                mData.put(uid, array);
             }
+            array.put(pid, new Pair<Long, Object>(System.currentTimeMillis(), extra));
         }
 
+        @VisibleForTesting
         Pair<Long, Object> remove(int pid, int uid) {
-            if (UserHandle.isIsolated(uid)) {
+            synchronized (mLock) {
                 Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
                 if (k != null) {
                     uid = k;
                 }
-            }
 
-            synchronized (mLock) {
                 SparseArray<Pair<Long, Object>> array = mData.get(uid);
                 if (array != null) {
                     Pair<Long, Object> p = array.get(pid);
@@ -1228,8 +1636,8 @@
                         return isFresh(p.first) ? p : null;
                     }
                 }
+                return null;
             }
-            return null;
         }
 
         void removeByUserId(int userId) {
@@ -1250,7 +1658,8 @@
             }
         }
 
-        void removeByUid(int uid, boolean allUsers) {
+        @GuardedBy("mLock")
+        void removeByUidLocked(int uid, boolean allUsers) {
             if (UserHandle.isIsolated(uid)) {
                 Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
                 if (k != null) {
@@ -1260,17 +1669,13 @@
 
             if (allUsers) {
                 uid = UserHandle.getAppId(uid);
-                synchronized (mLock) {
-                    for (int i = mData.size() - 1; i >= 0; i--) {
-                        if (UserHandle.getAppId(mData.keyAt(i)) == uid) {
-                            mData.removeAt(i);
-                        }
+                for (int i = mData.size() - 1; i >= 0; i--) {
+                    if (UserHandle.getAppId(mData.keyAt(i)) == uid) {
+                        mData.removeAt(i);
                     }
                 }
             } else {
-                synchronized (mLock) {
-                    mData.remove(uid);
-                }
+                mData.remove(uid);
             }
         }
 
@@ -1292,12 +1697,12 @@
 
             // Unlikely but possible: the record has been created
             // Let's update it if we could find a ApplicationExitInfo record
-            if (!updateExitInfoIfNecessary(pid, uid, status, mPresetReason)) {
-                add(pid, uid, status);
-            }
-
-            // Notify any interesed party regarding the lmkd kills
             synchronized (mLock) {
+                if (!updateExitInfoIfNecessaryLocked(pid, uid, status, mPresetReason)) {
+                    addLocked(pid, uid, status);
+                }
+
+                // Notify any interesed party regarding the lmkd kills
                 final BiConsumer<Integer, Integer> listener = mProcDiedListener;
                 if (listener != null) {
                     mService.mHandler.post(()-> listener.accept(pid, uid));
@@ -1305,4 +1710,51 @@
             }
         }
     }
+
+    /**
+     * The implementation to the IAppTraceRetriever interface.
+     */
+    @VisibleForTesting
+    class AppTraceRetriever extends IAppTraceRetriever.Stub {
+        @Override
+        public ParcelFileDescriptor getTraceFileDescriptor(final String packageName,
+                final int uid, final int pid) {
+            mService.enforceNotIsolatedCaller("getTraceFileDescriptor");
+
+            if (TextUtils.isEmpty(packageName)) {
+                throw new IllegalArgumentException("Invalid package name");
+            }
+            final int callingPid = Binder.getCallingPid();
+            final int callingUid = Binder.getCallingUid();
+            final int callingUserId = UserHandle.getCallingUserId();
+            final int userId = UserHandle.getUserId(uid);
+
+            mService.mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
+                    ALLOW_NON_FULL, "getTraceFileDescriptor", null);
+            if (mService.enforceDumpPermissionForPackage(packageName, userId,
+                    callingUid, "getTraceFileDescriptor") != Process.INVALID_UID) {
+                synchronized (mLock) {
+                    final ApplicationExitInfo info = getExitInfoLocked(packageName, uid, pid);
+                    if (info == null) {
+                        return null;
+                    }
+                    final File traceFile = info.getTraceFile();
+                    if (traceFile == null) {
+                        return null;
+                    }
+                    final long identity = Binder.clearCallingIdentity();
+                    try {
+                        // The fd will be closed after being written into Parcel
+                        return ParcelFileDescriptor.open(traceFile,
+                                ParcelFileDescriptor.MODE_READ_ONLY);
+                    } catch (FileNotFoundException e) {
+                        return null;
+                    } finally {
+                        Binder.restoreCallingIdentity(identity);
+                    }
+                }
+            }
+            return null;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/BugReportHandlerUtil.java b/services/core/java/com/android/server/am/BugReportHandlerUtil.java
index ba89fce..03f4a54 100644
--- a/services/core/java/com/android/server/am/BugReportHandlerUtil.java
+++ b/services/core/java/com/android/server/am/BugReportHandlerUtil.java
@@ -16,15 +16,20 @@
 
 package com.android.server.am;
 
+import static android.app.AppOpsManager.OP_NONE;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
+import android.app.Activity;
 import android.app.BroadcastOptions;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Binder;
+import android.os.BugreportManager;
+import android.os.BugreportParams;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -110,9 +115,17 @@
         options.setBackgroundActivityStartsAllowed(true);
         final long identity = Binder.clearCallingIdentity();
         try {
-            context.sendBroadcastAsUser(intent, UserHandle.of(handlerUser),
+            // Handler app's BroadcastReceiver should call setResultCode(Activity.RESULT_OK) to
+            // let ResultBroadcastReceiver know the handler app is available.
+            context.sendOrderedBroadcastAsUser(intent,
+                    UserHandle.of(handlerUser),
                     android.Manifest.permission.DUMP,
-                    options.toBundle());
+                    OP_NONE, options.toBundle(),
+                    new ResultBroadcastReceiver(),
+                    /* scheduler= */ null,
+                    Activity.RESULT_CANCELED,
+                    /* initialData= */ null,
+                    /* initialExtras= */ null);
         } catch (RuntimeException e) {
             Slog.e(TAG, "Error while trying to launch bugreport handler app.", e);
             return false;
@@ -176,4 +189,19 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
+
+    private static class ResultBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (getResultCode() == Activity.RESULT_OK) {
+                return;
+            }
+
+            Slog.w(TAG, "Request bug report because handler app seems to be not available.");
+            BugreportManager bugreportManager = context.getSystemService(BugreportManager.class);
+            bugreportManager.requestBugreport(
+                    new BugreportParams(BugreportParams.BUGREPORT_MODE_INTERACTIVE),
+                    /* shareTitle= */null, /* shareDescription= */ null);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 57bd42b..0f9d61f 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -71,7 +71,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManagerInternal;
-import android.content.pm.ProcessInfo;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.net.LocalSocket;
@@ -99,7 +98,6 @@
 import android.system.Os;
 import android.text.TextUtils;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.LongSparseArray;
 import android.util.Pair;
@@ -138,10 +136,8 @@
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * Activity manager code dealing with processes.
@@ -512,13 +508,6 @@
      */
     private final int[] mZygoteSigChldMessage = new int[3];
 
-    interface LmkdKillListener {
-        /**
-         * Called when there is a process kill by lmkd.
-         */
-        void onLmkdKillOccurred(int pid, int uid);
-    }
-
     final class IsolatedUidRange {
         @VisibleForTesting
         public final int mFirstUid;
@@ -2192,11 +2181,12 @@
                 app.setHasForegroundActivities(true);
             }
 
+            StorageManagerInternal storageManagerInternal = LocalServices.getService(
+                    StorageManagerInternal.class);
             final Map<String, Pair<String, Long>> pkgDataInfoMap;
             boolean bindMountAppStorageDirs = false;
 
             if (shouldIsolateAppData(app)) {
-                bindMountAppStorageDirs = mVoldAppDataIsolationEnabled;
                 // Get all packages belongs to the same shared uid. sharedPackages is empty array
                 // if it doesn't have shared uid.
                 final PackageManagerInternal pmInt = mService.getPackageManagerInternalLocked();
@@ -2206,9 +2196,9 @@
                         ? new String[]{app.info.packageName} : sharedPackages, uid);
 
                 int userId = UserHandle.getUserId(uid);
-                if (mVoldAppDataIsolationEnabled) {
-                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
-                            StorageManagerInternal.class);
+                if (mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid) &&
+                        !storageManagerInternal.isExternalStorageService(uid)) {
+                    bindMountAppStorageDirs = true;
                     if (!storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
                             app.processName)) {
                         // Cannot prepare Android/app and Android/obb directory,
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index e7f66bb..eec7519 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1621,9 +1621,11 @@
         // For background ANRs, don't pass the ProcessCpuTracker to
         // avoid spending 1/2 second collecting stats to rank lastPids.
         StringWriter tracesFileException = new StringWriter();
+        // To hold the start and end offset to the ANR trace file respectively.
+        final long[] offsets = new long[2];
         File tracesFile = ActivityManagerService.dumpStackTraces(firstPids,
                 (isSilentAnr()) ? null : processCpuTracker, (isSilentAnr()) ? null : lastPids,
-                nativePids, tracesFileException);
+                nativePids, tracesFileException, offsets);
 
         if (isMonitorCpuUsage()) {
             mService.updateCpuStatsNow();
@@ -1641,6 +1643,10 @@
         if (tracesFile == null) {
             // There is no trace file, so dump (only) the alleged culprit's threads to the log
             Process.sendSignal(pid, Process.SIGNAL_QUIT);
+        } else if (offsets[1] > 0) {
+            // We've dumped into the trace file successfully
+            mService.mProcessList.mAppExitInfoTracker.scheduleLogAnrTrace(
+                    pid, uid, getPackageList(), tracesFile, offsets[0], offsets[1]);
         }
 
         FrameworkStatsLog.write(FrameworkStatsLog.ANR_OCCURRED, uid, processName,
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index a7125b4..343b4ba 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -2218,19 +2218,23 @@
 
     /**
      * Returns whether the given user requires credential entry at this time. This is used to
-     * intercept activity launches for work apps when the Work Challenge is present.
+     * intercept activity launches for locked work apps due to work challenge being triggered
+     * or when the profile user is yet to be unlocked.
      */
     protected boolean shouldConfirmCredentials(@UserIdInt int userId) {
-        synchronized (mLock) {
-            if (mStartedUsers.get(userId) == null) {
-                return false;
-            }
-        }
-        if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+        if (getStartedUserState(userId) == null) {
             return false;
         }
-        final KeyguardManager km = mInjector.getKeyguardManager();
-        return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
+        if (!getUserInfo(userId).isManagedProfile()) {
+            return false;
+        }
+        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+            final KeyguardManager km = mInjector.getKeyguardManager();
+            return km.isDeviceLocked(userId) && km.isDeviceSecure(userId);
+        } else {
+            // For unified challenge, need to confirm credential if user is RUNNING_LOCKED.
+            return isUserRunning(userId, ActivityManager.FLAG_AND_LOCKED);
+        }
     }
 
     boolean isLockScreenDisabled(@UserIdInt int userId) {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index c1c3760..1b4ec8a 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -530,6 +530,11 @@
             return Settings.Global.getInt(contentResolver, keyName, defaultValue);
         }
 
+        public int settingsSecureGetInt(ContentResolver contentResolver, String keyName,
+                int defaultValue, int userId) {
+            return Settings.Secure.getIntForUser(contentResolver, keyName, defaultValue, userId);
+        }
+
         public @NonNull ManagedProfilePasswordCache getManagedProfilePasswordCache() {
             try {
                 java.security.KeyStore ks = java.security.KeyStore.getInstance("AndroidKeyStore");
@@ -1010,6 +1015,13 @@
         }
     }
 
+    private void enforceFrpResolved() {
+        if (mInjector.settingsSecureGetInt(mContext.getContentResolver(),
+                Settings.Secure.SECURE_FRP_MODE, 0, UserHandle.USER_SYSTEM) == 1) {
+            throw new SecurityException("Cannot change credential while FRP is not resolved yet");
+        }
+    }
+
     private final void checkWritePermission(int userId) {
         mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite");
     }
@@ -1572,6 +1584,7 @@
                     "This operation requires secure lock screen feature");
         }
         checkWritePermission(userId);
+        enforceFrpResolved();
 
         // When changing credential for profiles with unified challenge, some callers
         // will pass in empty credential while others will pass in the credential of
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index 265b9ad..28f8380 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -85,7 +85,9 @@
         mListener = listener;
         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
         buildBluetoothRoutes();
+    }
 
+    public void start() {
         mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP);
         mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEARING_AID);
 
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 5c97e90..c7d14e0 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -103,25 +103,20 @@
             publishProviderState();
 
             boolean sessionInfoChanged;
-            synchronized (mLock) {
-                sessionInfoChanged = updateSessionInfosIfNeededLocked();
-            }
+            sessionInfoChanged = updateSessionInfosIfNeeded();
             if (sessionInfoChanged) {
                 notifySessionInfoUpdated();
             }
         });
-
-        mHandler.post(() -> notifyProviderState());
-
-        //TODO: clean up this
-        // This is required because it is not instantiated in the main thread and
-        // BluetoothRoutesUpdatedListener can be called before here
-        synchronized (mLock) {
-            updateSessionInfosIfNeededLocked();
-        }
+        updateSessionInfosIfNeeded();
 
         mContext.registerReceiver(new VolumeChangeReceiver(),
                 new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
+
+        mHandler.post(() -> {
+            mBtRouteProvider.start();
+            notifyProviderState();
+        });
     }
 
     @Override
@@ -220,35 +215,38 @@
     /**
      * Updates the mSessionInfo. Returns true if the session info is changed.
      */
-    boolean updateSessionInfosIfNeededLocked() {
-        // Prevent to execute this method before mBtRouteProvider is created.
-        if (mBtRouteProvider == null) return false;
-        RoutingSessionInfo oldSessionInfo = mSessionInfos.isEmpty() ? null : mSessionInfos.get(0);
+    boolean updateSessionInfosIfNeeded() {
+        synchronized (mLock) {
+            // Prevent to execute this method before mBtRouteProvider is created.
+            if (mBtRouteProvider == null) return false;
+            RoutingSessionInfo oldSessionInfo = mSessionInfos.isEmpty() ? null : mSessionInfos.get(
+                    0);
 
-        RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
-                SYSTEM_SESSION_ID, "" /* clientPackageName */)
-                .setSystemSession(true);
+            RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
+                    SYSTEM_SESSION_ID, "" /* clientPackageName */)
+                    .setSystemSession(true);
 
-        MediaRoute2Info selectedRoute = mBtRouteProvider.getSelectedRoute();
-        if (selectedRoute == null) {
-            selectedRoute = mDefaultRoute;
-        } else {
-            builder.addTransferableRoute(mDefaultRoute.getId());
-        }
-        mSelectedRouteId = selectedRoute.getId();
-        builder.addSelectedRoute(mSelectedRouteId);
+            MediaRoute2Info selectedRoute = mBtRouteProvider.getSelectedRoute();
+            if (selectedRoute == null) {
+                selectedRoute = mDefaultRoute;
+            } else {
+                builder.addTransferableRoute(mDefaultRoute.getId());
+            }
+            mSelectedRouteId = selectedRoute.getId();
+            builder.addSelectedRoute(mSelectedRouteId);
 
-        for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) {
-            builder.addTransferableRoute(route.getId());
-        }
+            for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) {
+                builder.addTransferableRoute(route.getId());
+            }
 
-        RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build();
-        if (Objects.equals(oldSessionInfo, newSessionInfo)) {
-            return false;
-        } else {
-            mSessionInfos.clear();
-            mSessionInfos.add(newSessionInfo);
-            return true;
+            RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build();
+            if (Objects.equals(oldSessionInfo, newSessionInfo)) {
+                return false;
+            } else {
+                mSessionInfos.clear();
+                mSessionInfos.add(newSessionInfo);
+                return true;
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
index 563dcf7..48f1ddb 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -21,7 +21,7 @@
 import android.annotation.NonNull;
 import android.net.Network;
 import android.net.NetworkTemplate;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
+import android.net.netstats.provider.NetworkStatsProvider;
 import android.telephony.SubscriptionPlan;
 
 import java.util.Set;
@@ -130,8 +130,8 @@
             Set<String> packageNames, int userId);
 
     /**
-     *  Notifies that the specified {@link AbstractNetworkStatsProvider} has reached its quota
-     *  which was set through {@link AbstractNetworkStatsProvider#setLimit(String, long)}.
+     *  Notifies that the specified {@link NetworkStatsProvider} has reached its quota
+     *  which was set through {@link NetworkStatsProvider#onSetLimit(String, long)}.
      *
      * @param tag the human readable identifier of the custom network stats provider.
      */
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 0b1c91f..c5c1363 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -75,7 +75,7 @@
 import static android.net.NetworkTemplate.MATCH_WIFI;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.TrafficStats.MB_IN_BYTES;
-import static android.net.netstats.provider.AbstractNetworkStatsProvider.QUOTA_UNLIMITED;
+import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
 import static android.os.Trace.TRACE_TAG_NETWORK;
 import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
 import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED;
@@ -3087,17 +3087,38 @@
     private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) {
         // nothing to check if no plans
         if (plans.length == 0) {
+            Log.d(TAG, "Received empty plans list. Clearing existing SubscriptionPlans.");
             return;
         }
 
-        final ArraySet<Integer> applicableNetworkTypes = new ArraySet<Integer>();
-        boolean allNetworks = false;
-        for (SubscriptionPlan plan : plans) {
-            if (plan.getNetworkTypes() == null) {
-                allNetworks = true;
+        final int[] allNetworkTypes = TelephonyManager.getAllNetworkTypes();
+        final ArraySet<Integer> allNetworksSet = new ArraySet<>();
+        addAll(allNetworksSet, allNetworkTypes);
+
+        final ArraySet<Integer> applicableNetworkTypes = new ArraySet<>();
+        boolean hasGeneralPlan = false;
+        for (int i = 0; i < plans.length; i++) {
+            final int[] planNetworkTypes = plans[i].getNetworkTypes();
+            final ArraySet<Integer> planNetworksSet = new ArraySet<>();
+            for (int j = 0; j < planNetworkTypes.length; j++) {
+                // ensure all network types are valid
+                if (allNetworksSet.contains(planNetworkTypes[j])) {
+                    // ensure no duplicate network types in the same SubscriptionPlan
+                    if (!planNetworksSet.add(planNetworkTypes[j])) {
+                        throw new IllegalArgumentException(
+                                "Subscription plan contains duplicate network types.");
+                    }
+                } else {
+                    throw new IllegalArgumentException("Invalid network type: "
+                            + planNetworkTypes[j]);
+                }
+            }
+
+            if (planNetworkTypes.length == allNetworkTypes.length) {
+                hasGeneralPlan = true;
             } else {
-                final int[] networkTypes = plan.getNetworkTypes();
-                if (!addAll(applicableNetworkTypes, networkTypes)) {
+                // ensure no network type applies to multiple plans
+                if (!addAll(applicableNetworkTypes, planNetworkTypes)) {
                     throw new IllegalArgumentException(
                             "Multiple subscription plans defined for a single network type.");
                 }
@@ -3105,7 +3126,7 @@
         }
 
         // ensure at least one plan applies for every network type
-        if (!allNetworks) {
+        if (!hasGeneralPlan) {
             throw new IllegalArgumentException(
                     "No generic subscription plan that applies to all network types.");
         }
@@ -3114,12 +3135,12 @@
     /**
      * Adds all of the {@code elements} to the {@code set}.
      *
-     * @return {@code false} if any element is not added because the set already have the value.
+     * @return {@code false} if any element is not added because the set already has the value.
      */
-    private static boolean addAll(@NonNull Set<Integer> set, @NonNull int... elements) {
+    private static boolean addAll(@NonNull ArraySet<Integer> set, @NonNull int... elements) {
         boolean result = true;
-        for (int element : elements) {
-            result &= set.add(element);
+        for (int i = 0; i < elements.length; i++) {
+            result &= set.add(elements[i]);
         }
         return result;
     }
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 22b01be..75ffe35 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -229,7 +229,7 @@
                     entry.txPackets += reader.nextLong();
                 }
 
-                stats.addEntry(entry);
+                stats.insertEntry(entry);
                 reader.finishLine();
             }
         } catch (NullPointerException|NumberFormatException e) {
@@ -279,7 +279,7 @@
                 entry.txBytes = reader.nextLong();
                 entry.txPackets = reader.nextLong();
 
-                stats.addEntry(entry);
+                stats.insertEntry(entry);
                 reader.finishLine();
             }
         } catch (NullPointerException|NumberFormatException e) {
@@ -439,7 +439,7 @@
                 if ((limitIfaces == null || ArrayUtils.contains(limitIfaces, entry.iface))
                         && (limitUid == UID_ALL || limitUid == entry.uid)
                         && (limitTag == TAG_ALL || limitTag == entry.tag)) {
-                    stats.addEntry(entry);
+                    stats.insertEntry(entry);
                 }
 
                 reader.finishLine();
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 4504704..10136b3 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -17,6 +17,7 @@
 package com.android.server.net;
 
 import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.NETWORK_STATS_PROVIDER;
 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
 import static android.Manifest.permission.UPDATE_DEVICE_STATS;
 import static android.content.Intent.ACTION_SHUTDOWN;
@@ -102,7 +103,7 @@
 import android.net.TrafficStats;
 import android.net.netstats.provider.INetworkStatsProvider;
 import android.net.netstats.provider.INetworkStatsProviderCallback;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
 import android.os.BestClock;
 import android.os.Binder;
 import android.os.DropBoxManager;
@@ -557,7 +558,7 @@
         } catch (RemoteException e) {
             // ignored; service lives in system_server
         }
-        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setAlert(mGlobalAlertBytes));
+        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes));
     }
 
     @Override
@@ -758,7 +759,7 @@
         final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
 
         final NetworkStats stats = new NetworkStats(end - start, 1);
-        stats.addEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
+        stats.insertEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
                 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
                 entry.txBytes, entry.txPackets, entry.operations));
         return stats;
@@ -1375,7 +1376,8 @@
         Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
         final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount();
         mStatsProviderSem.drainPermits();
-        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */));
+        invokeForAllStatsProviderCallbacks(
+                (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
         try {
             mStatsProviderSem.tryAcquire(registeredCallbackCount,
                     MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
@@ -1550,7 +1552,7 @@
         @Override
         public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
             Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
-            invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota));
+            invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota));
         }
     }
 
@@ -1819,16 +1821,15 @@
      *
      * @param tag a human readable identifier of the custom network stats provider.
      * @param provider the {@link INetworkStatsProvider} binder corresponding to the
-     *                 {@link android.net.netstats.provider.AbstractNetworkStatsProvider} to be
-     *                 registered.
+     *                 {@link NetworkStatsProvider} to be registered.
      *
-     * @return a binder interface of
-     *         {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be
-     *         used to report events to the system.
+     * @return a {@link INetworkStatsProviderCallback} binder
+     *         interface, which can be used to report events to the system.
      */
     public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider(
             @NonNull String tag, @NonNull INetworkStatsProvider provider) {
-        mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
+        enforceAnyPermissionOf(NETWORK_STATS_PROVIDER,
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
         Objects.requireNonNull(provider, "provider is null");
         Objects.requireNonNull(tag, "tag is null");
         try {
@@ -1929,7 +1930,7 @@
         }
 
         @Override
-        public void onStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
+        public void notifyStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
                 @Nullable NetworkStats uidStats) {
             // TODO: 1. Use token to map ifaces to correct NetworkIdentity.
             //       2. Store the difference and store it directly to the recorder.
@@ -1941,12 +1942,12 @@
         }
 
         @Override
-        public void onAlertReached() throws RemoteException {
+        public void notifyAlertReached() throws RemoteException {
             mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */);
         }
 
         @Override
-        public void onLimitReached() {
+        public void notifyLimitReached() {
             Log.d(TAG, mTag + ": onLimitReached");
             LocalServices.getService(NetworkPolicyManagerInternal.class)
                     .onStatsProviderLimitReached(mTag);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index f45e66e..2853956 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -141,6 +141,7 @@
         updateDefaultAutomaticRuleNames();
         mConfig = mDefaultConfig.copy();
         mConfigs.put(UserHandle.USER_SYSTEM, mConfig);
+        mConsolidatedPolicy = mConfig.toNotificationPolicy();
 
         mSettingsObserver = new SettingsObserver(mHandler);
         mSettingsObserver.observe();
@@ -821,9 +822,6 @@
      * @return a copy of the zen mode consolidated policy
      */
     public Policy getConsolidatedNotificationPolicy() {
-        if (mConsolidatedPolicy == null) {
-            return null;
-        }
         return mConsolidatedPolicy.copy();
     }
 
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 79a4da2..690b9f7 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -481,6 +481,12 @@
                         mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
                     }
                 }
+                // if either package instruments the other, mark both as visible to one another
+                if (pkgInstruments(newPkgSetting, existingSetting)
+                        || pkgInstruments(existingSetting, newPkgSetting)) {
+                    mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
+                    mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
+                }
             }
 
             int existingSize = existingSettings.size();
@@ -715,19 +721,6 @@
                 Trace.endSection();
             }
 
-            if (callingPkgSetting != null) {
-                if (callingPkgInstruments(callingPkgSetting, targetPkgSetting, targetName)) {
-                    return false;
-                }
-            } else {
-                for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
-                    if (callingPkgInstruments(callingSharedPkgSettings.valueAt(i),
-                            targetPkgSetting, targetName)) {
-                        return false;
-                    }
-                }
-            }
-
             try {
                 Trace.beginSection("mOverlayReferenceMapper");
                 if (callingSharedPkgSettings != null) {
@@ -762,16 +755,16 @@
         }
     }
 
-    private static boolean callingPkgInstruments(PackageSetting callingPkgSetting,
-            PackageSetting targetPkgSetting,
-            String targetName) {
+    /** Returns {@code true} if the source package instruments the target package. */
+    private static boolean pkgInstruments(PackageSetting source, PackageSetting target) {
         try {
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "callingPkgInstruments");
-            final List<ParsedInstrumentation> inst = callingPkgSetting.pkg.getInstrumentations();
+            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "pkgInstruments");
+            final String packageName = target.pkg.getPackageName();
+            final List<ParsedInstrumentation> inst = source.pkg.getInstrumentations();
             for (int i = ArrayUtils.size(inst) - 1; i >= 0; i--) {
-                if (Objects.equals(inst.get(i).getTargetPackage(), targetName)) {
+                if (Objects.equals(inst.get(i).getTargetPackage(), packageName)) {
                     if (DEBUG_LOGGING) {
-                        log(callingPkgSetting, targetPkgSetting, "instrumentation");
+                        log(source, target, "instrumentation");
                     }
                     return true;
                 }
diff --git a/services/core/java/com/android/server/pm/DataLoaderManagerService.java b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
index 8eb773a..09baf6e 100644
--- a/services/core/java/com/android/server/pm/DataLoaderManagerService.java
+++ b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
@@ -213,7 +213,7 @@
 
         void destroy() {
             try {
-                mDataLoader.destroy();
+                mDataLoader.destroy(mId);
             } catch (RemoteException ignored) {
             }
             mContext.unbindService(this);
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 8031eaa..1b271a7 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -819,6 +819,18 @@
         }
 
         @Override
+        public String getShortcutIconUri(String callingPackage, String packageName,
+                String shortcutId, int userId) {
+            ensureShortcutPermission(callingPackage);
+            if (!canAccessProfile(userId, "Cannot access shortcuts")) {
+                return null;
+            }
+
+            return mShortcutServiceInternal.getShortcutIconUri(getCallingUserId(), callingPackage,
+                    packageName, shortcutId, userId);
+        }
+
+        @Override
         public boolean hasShortcutHostPermission(String callingPackage) {
             verifyCallingPackage(callingPackage);
             return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index cdc3736..2ff3d2a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -47,7 +47,6 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -1038,80 +1037,11 @@
         }
     }
 
-    static void sendPendingStreaming(Context context, IntentSender target, int sessionId,
-            Throwable cause) {
-        final Intent intent = new Intent();
-        intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
-        intent.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_STREAMING);
-        if (cause != null && !TextUtils.isEmpty(cause.getMessage())) {
-            intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
-                    "Staging Image Not Ready [" + cause.getMessage() + "]");
-        } else {
-            intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready");
-        }
-        try {
-            target.sendIntent(context, 0, intent, null, null);
-        } catch (SendIntentException ignored) {
-        }
-    }
-
-    static void sendOnUserActionRequired(Context context, IntentSender target, int sessionId,
-            Intent intent) {
-        final Intent fillIn = new Intent();
-        fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
-        fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_USER_ACTION);
-        fillIn.putExtra(Intent.EXTRA_INTENT, intent);
-        try {
-            target.sendIntent(context, 0, fillIn, null, null);
-        } catch (SendIntentException ignored) {
-        }
-    }
-
-    static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
-            boolean showNotification, int userId, String basePackageName, int returnCode,
-            String msg, Bundle extras) {
-        if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {
-            boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
-            Notification notification = buildSuccessNotification(context,
-                    context.getResources()
-                            .getString(update ? R.string.package_updated_device_owner :
-                                    R.string.package_installed_device_owner),
-                    basePackageName,
-                    userId);
-            if (notification != null) {
-                NotificationManager notificationManager = (NotificationManager)
-                        context.getSystemService(Context.NOTIFICATION_SERVICE);
-                notificationManager.notify(basePackageName,
-                        SystemMessage.NOTE_PACKAGE_STATE,
-                        notification);
-            }
-        }
-        final Intent fillIn = new Intent();
-        fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
-        fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
-        fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
-                PackageManager.installStatusToPublicStatus(returnCode));
-        fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
-                PackageManager.installStatusToString(returnCode, msg));
-        fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
-        if (extras != null) {
-            final String existing = extras.getString(
-                    PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
-            if (!TextUtils.isEmpty(existing)) {
-                fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
-            }
-        }
-        try {
-            target.sendIntent(context, 0, fillIn, null, null);
-        } catch (SendIntentException ignored) {
-        }
-    }
-
     /**
      * Build a notification for package installation / deletion by device owners that is shown if
      * the operation succeeds.
      */
-    private static Notification buildSuccessNotification(Context context, String contentText,
+    static Notification buildSuccessNotification(Context context, String contentText,
             String basePackageName, int userId) {
         PackageInfo packageInfo = null;
         try {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 28d7c13..5b7e8bf 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -51,6 +51,8 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.Notification;
+import android.app.NotificationManager;
 import android.app.admin.DevicePolicyEventLogger;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.ComponentName;
@@ -119,9 +121,11 @@
 import android.util.SparseIntArray;
 import android.util.apk.ApkSignatureVerifier;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.NativeLibraryHelper;
 import com.android.internal.content.PackageHelper;
+import com.android.internal.messages.nano.SystemMessageProto;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
@@ -440,8 +444,7 @@
                     final int returnCode = args.argi1;
                     args.recycle();
 
-                    PackageInstallerService.sendOnPackageInstalled(mContext,
-                            statusReceiver, sessionId,
+                    sendOnPackageInstalled(mContext, statusReceiver, sessionId,
                             isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId,
                             packageName, returnCode, message, extras);
 
@@ -1636,8 +1639,7 @@
                 }
             }
             if (!success) {
-                PackageInstallerService.sendOnPackageInstalled(mContext,
-                        mRemoteStatusReceiver, sessionId,
+                sendOnPackageInstalled(mContext, mRemoteStatusReceiver, sessionId,
                         isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId, null,
                         failure.error, failure.getLocalizedMessage(), null);
                 return;
@@ -1684,8 +1686,7 @@
                     intent.setPackage(mPm.getPackageInstallerPackageName());
                     intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
 
-                    PackageInstallerService.sendOnUserActionRequired(mContext,
-                            mRemoteStatusReceiver, sessionId, intent);
+                    sendOnUserActionRequired(mContext, mRemoteStatusReceiver, sessionId, intent);
 
                     // Commit was keeping session marked as active until now; release
                     // that extra refcount so session appears idle.
@@ -2582,12 +2583,13 @@
                             if (manualStartAndDestroy) {
                                 // IncrementalFileStorages will call start after all files are
                                 // created in IncFS.
-                                dataLoader.start();
+                                dataLoader.start(dataLoaderId);
                             }
                             break;
                         }
                         case IDataLoaderStatusListener.DATA_LOADER_STARTED: {
                             dataLoader.prepareImage(
+                                    dataLoaderId,
                                     addedFiles.toArray(
                                             new InstallationFileParcel[addedFiles.size()]),
                                     removedFiles.toArray(new String[removedFiles.size()]));
@@ -2602,7 +2604,7 @@
                                 dispatchStreamValidateAndCommit();
                             }
                             if (manualStartAndDestroy) {
-                                dataLoader.destroy();
+                                dataLoader.destroy(dataLoaderId);
                             }
                             break;
                         }
@@ -2612,7 +2614,7 @@
                                     new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
                                             "Failed to prepare image."));
                             if (manualStartAndDestroy) {
-                                dataLoader.destroy();
+                                dataLoader.destroy(dataLoaderId);
                             }
                             break;
                         }
@@ -2620,9 +2622,8 @@
                 } catch (RemoteException e) {
                     // In case of streaming failure we don't want to fail or commit the session.
                     // Just return from this method and allow caller to commit again.
-                    PackageInstallerService.sendPendingStreaming(mContext,
-                            mRemoteStatusReceiver,
-                            sessionId, new StreamingException(e));
+                    sendPendingStreaming(mContext, mRemoteStatusReceiver, sessionId,
+                            new StreamingException(e));
                 }
             }
         };
@@ -2924,6 +2925,75 @@
         pw.decreaseIndent();
     }
 
+    private static void sendOnUserActionRequired(Context context, IntentSender target,
+            int sessionId, Intent intent) {
+        final Intent fillIn = new Intent();
+        fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+        fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_USER_ACTION);
+        fillIn.putExtra(Intent.EXTRA_INTENT, intent);
+        try {
+            target.sendIntent(context, 0, fillIn, null, null);
+        } catch (IntentSender.SendIntentException ignored) {
+        }
+    }
+
+    private static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
+            boolean showNotification, int userId, String basePackageName, int returnCode,
+            String msg, Bundle extras) {
+        if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {
+            boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
+            Notification notification = PackageInstallerService.buildSuccessNotification(context,
+                    context.getResources()
+                            .getString(update ? R.string.package_updated_device_owner :
+                                    R.string.package_installed_device_owner),
+                    basePackageName,
+                    userId);
+            if (notification != null) {
+                NotificationManager notificationManager = (NotificationManager)
+                        context.getSystemService(Context.NOTIFICATION_SERVICE);
+                notificationManager.notify(basePackageName,
+                        SystemMessageProto.SystemMessage.NOTE_PACKAGE_STATE,
+                        notification);
+            }
+        }
+        final Intent fillIn = new Intent();
+        fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
+        fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+        fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
+                PackageManager.installStatusToPublicStatus(returnCode));
+        fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
+                PackageManager.installStatusToString(returnCode, msg));
+        fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
+        if (extras != null) {
+            final String existing = extras.getString(
+                    PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
+            if (!TextUtils.isEmpty(existing)) {
+                fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
+            }
+        }
+        try {
+            target.sendIntent(context, 0, fillIn, null, null);
+        } catch (IntentSender.SendIntentException ignored) {
+        }
+    }
+
+    private static void sendPendingStreaming(Context context, IntentSender target, int sessionId,
+            Throwable cause) {
+        final Intent intent = new Intent();
+        intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+        intent.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_STREAMING);
+        if (cause != null && !TextUtils.isEmpty(cause.getMessage())) {
+            intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
+                    "Staging Image Not Ready [" + cause.getMessage() + "]");
+        } else {
+            intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready");
+        }
+        try {
+            target.sendIntent(context, 0, intent, null, null);
+        } catch (IntentSender.SendIntentException ignored) {
+        }
+    }
+
     private static void writeGrantedRuntimePermissionsLocked(XmlSerializer out,
             String[] grantedRuntimePermissions) throws IOException {
         if (grantedRuntimePermissions != null) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 24ebd32..09e4e60 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1548,7 +1548,6 @@
     final @Nullable String mConfiguratorPackage;
     final @Nullable String mAppPredictionServicePackage;
     final @Nullable String mIncidentReportApproverPackage;
-    final @Nullable String[] mTelephonyPackages;
     final @Nullable String mServicesExtensionPackageName;
     final @Nullable String mSharedSystemSharedLibraryPackageName;
     final @Nullable String mRetailDemoPackage;
@@ -3181,7 +3180,6 @@
             mConfiguratorPackage = getDeviceConfiguratorPackageName();
             mAppPredictionServicePackage = getAppPredictionServicePackageName();
             mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
-            mTelephonyPackages = getTelephonyPackageNames();
             mRetailDemoPackage = getRetailDemoPackageName();
 
             // Now that we know all of the shared libraries, update all clients to have
@@ -19939,16 +19937,6 @@
     }
 
     @Override
-    public String[] getTelephonyPackageNames() {
-        String names = mContext.getString(R.string.config_telephonyPackages);
-        String[] telephonyPackageNames = null;
-        if (!TextUtils.isEmpty(names)) {
-            telephonyPackageNames = names.trim().split(",");
-        }
-        return ensureSystemPackageNames(telephonyPackageNames);
-    }
-
-    @Override
     public String getContentCaptureServicePackageName() {
         final String flattenedContentCaptureService =
                 mContext.getString(R.string.config_defaultContentCaptureService);
@@ -23335,8 +23323,6 @@
                     return filterOnlySystemPackages(mIncidentReportApproverPackage);
                 case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
                     return filterOnlySystemPackages(mAppPredictionServicePackage);
-                case PackageManagerInternal.PACKAGE_TELEPHONY:
-                    return filterOnlySystemPackages(mTelephonyPackages);
                 case PackageManagerInternal.PACKAGE_COMPANION:
                     return filterOnlySystemPackages("com.android.companiondevicemanager");
                 case PackageManagerInternal.PACKAGE_RETAIL_DEMO:
diff --git a/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java b/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java
index dc534a7..1c5f0a7 100644
--- a/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java
+++ b/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java
@@ -28,7 +28,6 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
 import com.android.server.pm.ShortcutService.FileOutputStreamWithPath;
 
 import libcore.io.IoUtils;
@@ -150,9 +149,10 @@
         shortcut.setIconResourceId(0);
         shortcut.setIconResName(null);
         shortcut.setBitmapPath(null);
+        shortcut.setIconUri(null);
         shortcut.clearFlags(ShortcutInfo.FLAG_HAS_ICON_FILE |
                 ShortcutInfo.FLAG_ADAPTIVE_BITMAP | ShortcutInfo.FLAG_HAS_ICON_RES |
-                ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE);
+                ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE | ShortcutInfo.FLAG_HAS_ICON_URI);
     }
 
     public void saveBitmapLocked(ShortcutInfo shortcut,
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index c8df5c7..1fc0a38 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -102,6 +102,7 @@
     private static final String ATTR_ICON_RES_ID = "icon-res";
     private static final String ATTR_ICON_RES_NAME = "icon-resname";
     private static final String ATTR_BITMAP_PATH = "bitmap-path";
+    private static final String ATTR_ICON_URI = "icon-uri";
     private static final String ATTR_LOCUS_ID = "locus-id";
 
     private static final String ATTR_PERSON_NAME = "name";
@@ -1628,7 +1629,8 @@
             int flags = si.getFlags() &
                     ~(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES
                             | ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE
-                            | ShortcutInfo.FLAG_DYNAMIC);
+                            | ShortcutInfo.FLAG_DYNAMIC
+                            | ShortcutInfo.FLAG_HAS_ICON_URI | ShortcutInfo.FLAG_ADAPTIVE_BITMAP);
             ShortcutService.writeAttr(out, ATTR_FLAGS, flags);
 
             // Set the publisher version code at every backup.
@@ -1646,6 +1648,7 @@
             ShortcutService.writeAttr(out, ATTR_ICON_RES_ID, si.getIconResourceId());
             ShortcutService.writeAttr(out, ATTR_ICON_RES_NAME, si.getIconResName());
             ShortcutService.writeAttr(out, ATTR_BITMAP_PATH, si.getBitmapPath());
+            ShortcutService.writeAttr(out, ATTR_ICON_URI, si.getIconUri());
         }
 
         if (shouldBackupDetails) {
@@ -1764,6 +1767,7 @@
         int iconResId;
         String iconResName;
         String bitmapPath;
+        String iconUri;
         final String locusIdString;
         int backupVersionCode;
         ArraySet<String> categories = null;
@@ -1791,6 +1795,7 @@
         iconResId = (int) ShortcutService.parseLongAttribute(parser, ATTR_ICON_RES_ID);
         iconResName = ShortcutService.parseStringAttribute(parser, ATTR_ICON_RES_NAME);
         bitmapPath = ShortcutService.parseStringAttribute(parser, ATTR_BITMAP_PATH);
+        iconUri = ShortcutService.parseStringAttribute(parser, ATTR_ICON_URI);
         locusIdString = ShortcutService.parseStringAttribute(parser, ATTR_LOCUS_ID);
 
         final int outerDepth = parser.getDepth();
@@ -1866,8 +1871,8 @@
                 categories,
                 intents.toArray(new Intent[intents.size()]),
                 rank, extras, lastChangedTimestamp, flags,
-                iconResId, iconResName, bitmapPath, disabledReason,
-                persons.toArray(new Person[persons.size()]), locusId);
+                iconResId, iconResName, bitmapPath, iconUri,
+                disabledReason, persons.toArray(new Person[persons.size()]), locusId);
     }
 
     private static Intent parseIntent(XmlPullParser parser)
@@ -1991,16 +1996,26 @@
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " still has an icon");
             }
-            if (si.hasAdaptiveBitmap() && !si.hasIconFile()) {
+            if (si.hasAdaptiveBitmap() && !(si.hasIconFile() || si.hasIconUri())) {
                 failed = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
-                    + " has adaptive bitmap but was not saved to a file.");
+                        + " has adaptive bitmap but was not saved to a file nor has icon uri.");
             }
             if (si.hasIconFile() && si.hasIconResource()) {
                 failed = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " has both resource and bitmap icons");
             }
+            if (si.hasIconFile() && si.hasIconUri()) {
+                failed = true;
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+                        + " has both url and bitmap icons");
+            }
+            if (si.hasIconUri() && si.hasIconResource()) {
+                failed = true;
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+                        + " has both url and resource icons");
+            }
             if (si.isEnabled()
                     != (si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED)) {
                 failed = true;
diff --git a/services/core/java/com/android/server/pm/ShortcutParser.java b/services/core/java/com/android/server/pm/ShortcutParser.java
index f9c0db0..d3aace1 100644
--- a/services/core/java/com/android/server/pm/ShortcutParser.java
+++ b/services/core/java/com/android/server/pm/ShortcutParser.java
@@ -449,6 +449,7 @@
                 iconResId,
                 null, // icon res name
                 null, // bitmap path
+                null, // icon Url
                 disabledReason,
                 null /* persons */,
                 null /* locusId */);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 66f3574..8768ab0 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -24,6 +24,8 @@
 import android.app.ActivityManagerInternal;
 import android.app.AppGlobals;
 import android.app.IUidObserver;
+import android.app.IUriGrantsManager;
+import android.app.UriGrantsManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.BroadcastReceiver;
@@ -65,6 +67,7 @@
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.LocaleList;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
@@ -106,6 +109,7 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.pm.ShortcutUser.PackageWithUser;
+import com.android.server.uri.UriGrantsManagerInternal;
 
 import libcore.io.IoUtils;
 
@@ -327,6 +331,9 @@
     private final UserManagerInternal mUserManagerInternal;
     private final UsageStatsManagerInternal mUsageStatsManagerInternal;
     private final ActivityManagerInternal mActivityManagerInternal;
+    private final IUriGrantsManager mUriGrantsManager;
+    private final UriGrantsManagerInternal mUriGrantsManagerInternal;
+    private final IBinder mUriPermissionOwner;
 
     private final ShortcutRequestPinProcessor mShortcutRequestPinProcessor;
     private final ShortcutBitmapSaver mShortcutBitmapSaver;
@@ -449,6 +456,11 @@
         mActivityManagerInternal = Objects.requireNonNull(
                 LocalServices.getService(ActivityManagerInternal.class));
 
+        mUriGrantsManager = UriGrantsManager.getService();
+        mUriGrantsManagerInternal = Objects.requireNonNull(
+                LocalServices.getService(UriGrantsManagerInternal.class));
+        mUriPermissionOwner = mUriGrantsManagerInternal.newUriPermissionOwner(TAG);
+
         mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock);
         mShortcutBitmapSaver = new ShortcutBitmapSaver(this);
         mShortcutDumpFiles = new ShortcutDumpFiles(this);
@@ -1414,7 +1426,7 @@
     }
 
     void saveIconAndFixUpShortcutLocked(ShortcutInfo shortcut) {
-        if (shortcut.hasIconFile() || shortcut.hasIconResource()) {
+        if (shortcut.hasIconFile() || shortcut.hasIconResource() || shortcut.hasIconUri()) {
             return;
         }
 
@@ -1438,6 +1450,15 @@
                         shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_RES);
                         return;
                     }
+                    case Icon.TYPE_URI:
+                        shortcut.setIconUri(icon.getUriString());
+                        shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_URI);
+                        return;
+                    case Icon.TYPE_URI_ADAPTIVE_BITMAP:
+                        shortcut.setIconUri(icon.getUriString());
+                        shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_URI
+                                | ShortcutInfo.FLAG_ADAPTIVE_BITMAP);
+                        return;
                     case Icon.TYPE_BITMAP:
                         bitmap = icon.getBitmap(); // Don't recycle in this case.
                         break;
@@ -3129,6 +3150,59 @@
         }
 
         @Override
+        public String getShortcutIconUri(int launcherUserId, @NonNull String launcherPackage,
+                @NonNull String packageName, @NonNull String shortcutId, int userId) {
+            Objects.requireNonNull(launcherPackage, "launcherPackage");
+            Objects.requireNonNull(packageName, "packageName");
+            Objects.requireNonNull(shortcutId, "shortcutId");
+
+            synchronized (mLock) {
+                throwIfUserLockedL(userId);
+                throwIfUserLockedL(launcherUserId);
+
+                getLauncherShortcutsLocked(launcherPackage, userId, launcherUserId)
+                        .attemptToRestoreIfNeededAndSave();
+
+                final ShortcutPackage p = getUserShortcutsLocked(userId)
+                        .getPackageShortcutsIfExists(packageName);
+                if (p == null) {
+                    return null;
+                }
+
+                final ShortcutInfo shortcutInfo = p.findShortcutById(shortcutId);
+                if (shortcutInfo == null || !shortcutInfo.hasIconUri()) {
+                    return null;
+                }
+                String uri = shortcutInfo.getIconUri();
+                if (uri == null) {
+                    Slog.w(TAG, "null uri detected in getShortcutIconUri()");
+                    return null;
+                }
+
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    int packageUid = mPackageManagerInternal.getPackageUidInternal(packageName,
+                            PackageManager.MATCH_DIRECT_BOOT_AUTO, userId);
+                    // Grant read uri permission to the caller on behalf of the shortcut owner. All
+                    // granted permissions are revoked when the default launcher changes, or when
+                    // device is rebooted.
+                    // b/151572645 is tracking a bug where Uri permissions are persisted across
+                    // reboots, even when Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION is not used.
+                    mUriGrantsManager.grantUriPermissionFromOwner(mUriPermissionOwner, packageUid,
+                            launcherPackage, Uri.parse(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION,
+                            userId, launcherUserId);
+                } catch (Exception e) {
+                    Slog.e(TAG, "Failed to grant uri access to " + launcherPackage + " for " + uri,
+                            e);
+                    uri = null;
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+                return uri;
+            }
+        }
+
+        @Override
         public boolean hasShortcutHostPermission(int launcherUserId,
                 @NonNull String callingPackage, int callingPid, int callingUid) {
             return ShortcutService.this.hasShortcutHostPermission(callingPackage, launcherUserId,
@@ -3241,7 +3315,14 @@
                     user.clearLauncher();
                 }
                 if (Intent.ACTION_PREFERRED_ACTIVITY_CHANGED.equals(action)) {
-                    // Nothing farther to do.
+                    final ShortcutUser user = getUserShortcutsLocked(userId);
+                    final ComponentName lastLauncher = user.getLastKnownLauncher();
+                    final ComponentName currentLauncher = getDefaultLauncher(userId);
+                    if (currentLauncher == null || !currentLauncher.equals(lastLauncher)) {
+                        // Default launcher is removed or changed, revoke all URI permissions.
+                        mUriGrantsManagerInternal.revokeUriPermissionFromOwner(mUriPermissionOwner,
+                                null, ~0, 0);
+                    }
                     return;
                 }
 
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 1c2fcc1..8280a61 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -455,11 +455,13 @@
 
         @Override
         public void onFinished(int id, Bundle extras) {
-            try {
-                mContext.startIntentSender(mTarget, null, 0, 0, 0);
-            } catch (IntentSender.SendIntentException e) {
-                Slog.e(LOG_TAG, "Failed to start the target in the callback", e);
-            }
+            mHandler.post(() -> {
+                try {
+                    mContext.startIntentSender(mTarget, null, 0, 0, 0);
+                } catch (IntentSender.SendIntentException e) {
+                    Slog.e(LOG_TAG, "Failed to start the target in the callback", e);
+                }
+            });
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index f8e5082..1d7d038 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -277,9 +277,6 @@
     public boolean isAppPredictor() {
         return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0;
     }
-    public boolean isTelephony() {
-        return (protectionLevel & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0;
-    }
     public boolean isCompanion() {
         return (protectionLevel & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0;
     }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 46f121d..5d6eaf2 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -3464,13 +3464,6 @@
                 // Special permissions for the system app predictor.
                 allowed = true;
             }
-            if (!allowed && bp.isTelephony()
-                    && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
-                        PackageManagerInternal.PACKAGE_TELEPHONY, UserHandle.USER_SYSTEM),
-                    pkg.getPackageName())) {
-                // Special permissions for the system telephony apps.
-                allowed = true;
-            }
             if (!allowed && bp.isCompanion()
                     && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                         PackageManagerInternal.PACKAGE_COMPANION, UserHandle.USER_SYSTEM),
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 294deba..3257b63 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -18,6 +18,8 @@
 
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT;
+import static android.os.PowerManagerInternal.MODE_DEVICE_IDLE;
+import static android.os.PowerManagerInternal.MODE_DISPLAY_INACTIVE;
 import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
 import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
 import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
@@ -42,8 +44,6 @@
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
-import android.hardware.power.Boost;
-import android.hardware.power.Mode;
 import android.hardware.power.V1_0.PowerHint;
 import android.net.Uri;
 import android.os.BatteryManager;
@@ -2975,6 +2975,8 @@
             synchronized (mLock) {
                 if (mDisplayState != state) {
                     mDisplayState = state;
+                    setPowerModeInternal(MODE_DISPLAY_INACTIVE,
+                            !Display.isActiveState(state));
                     if (state == Display.STATE_OFF) {
                         if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
                             setHalInteractiveModeLocked(false);
@@ -3297,6 +3299,7 @@
             }
             mDeviceIdleMode = enabled;
             updateWakeLockDisabledStatesLocked();
+            setPowerModeInternal(MODE_DEVICE_IDLE, mDeviceIdleMode || mLightDeviceIdleMode);
         }
         if (enabled) {
             EventLogTags.writeDeviceIdleOnPhase("power");
@@ -3310,6 +3313,7 @@
         synchronized (mLock) {
             if (mLightDeviceIdleMode != enabled) {
                 mLightDeviceIdleMode = enabled;
+                setPowerModeInternal(MODE_DEVICE_IDLE, mDeviceIdleMode || mLightDeviceIdleMode);
                 return true;
             }
             return false;
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 74a6383..0d16fcc 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -234,7 +234,7 @@
 
         handleRequest(
                 event.getSystemTextClassifierMetadata(),
-                /* verifyCallingPackage= */ false,
+                /* verifyCallingPackage= */ true,
                 /* attemptToBind= */ false,
                 service -> service.onSelectionEvent(sessionId, event),
                 "onSelectionEvent",
@@ -253,7 +253,7 @@
 
         handleRequest(
                 systemTcMetadata,
-                /* verifyCallingPackage= */ false,
+                /* verifyCallingPackage= */ true,
                 /* attemptToBind= */ false,
                 service -> service.onTextClassifierEvent(sessionId, event),
                 "onTextClassifierEvent",
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index bd63b2d..25585b3 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.tv.tunerresourcemanager;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -41,8 +40,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.SystemService;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -79,25 +76,6 @@
     // Used to synchronize the access to the service.
     private final Object mLock = new Object();
 
-    /**
-     * Tuner resource type to help generate resource handle
-     */
-    @IntDef({
-        TUNER_RESOURCE_TYPE_FRONTEND,
-        TUNER_RESOURCE_TYPE_DEMUX,
-        TUNER_RESOURCE_TYPE_DESCRAMBLER,
-        TUNER_RESOURCE_TYPE_LNB,
-        TUNER_RESOURCE_TYPE_CAS_SESSION,
-     })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TunerResourceType {}
-
-    public static final int TUNER_RESOURCE_TYPE_FRONTEND = 0;
-    public static final int TUNER_RESOURCE_TYPE_DEMUX = 1;
-    public static final int TUNER_RESOURCE_TYPE_DESCRAMBLER = 2;
-    public static final int TUNER_RESOURCE_TYPE_LNB = 3;
-    public static final int TUNER_RESOURCE_TYPE_CAS_SESSION = 4;
-
     public TunerResourceManagerService(@Nullable Context context) {
         super(context);
     }
@@ -465,7 +443,7 @@
         // Grant frontend when there is unused resource.
         if (grantingFrontendId > -1) {
             frontendHandle[0] = generateResourceHandle(
-                    TUNER_RESOURCE_TYPE_FRONTEND, grantingFrontendId);
+                    TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, grantingFrontendId);
             updateFrontendClientMappingOnNewGrant(grantingFrontendId, request.getClientId());
             return true;
         }
@@ -474,7 +452,7 @@
         // request client has higher priority.
         if (inUseLowestPriorityFrId > -1 && (requestClient.getPriority() > currentLowestPriority)) {
             frontendHandle[0] = generateResourceHandle(
-                    TUNER_RESOURCE_TYPE_FRONTEND, inUseLowestPriorityFrId);
+                    TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, inUseLowestPriorityFrId);
             reclaimFrontendResource(getFrontendResource(
                     inUseLowestPriorityFrId).getOwnerClientId());
             updateFrontendClientMappingOnNewGrant(inUseLowestPriorityFrId, request.getClientId());
@@ -489,7 +467,7 @@
         if (DEBUG) {
             Slog.d(TAG, "requestDemux(request=" + request + ")");
         }
-        demuxHandle[0] = generateResourceHandle(TUNER_RESOURCE_TYPE_DEMUX, 0);
+        demuxHandle[0] = generateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX, 0);
         return true;
     }
 
@@ -498,7 +476,8 @@
         if (DEBUG) {
             Slog.d(TAG, "requestDescrambler(request=" + request + ")");
         }
-        descramblerHandle[0] = generateResourceHandle(TUNER_RESOURCE_TYPE_DESCRAMBLER, 0);
+        descramblerHandle[0] =
+                generateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_DESCRAMBLER, 0);
         return true;
     }
 
@@ -664,7 +643,8 @@
         return mClientProfiles.keySet().contains(clientId);
     }
 
-    private int generateResourceHandle(@TunerResourceType int resourceType, int resourceId) {
+    private int generateResourceHandle(
+            @TunerResourceManager.TunerResourceType int resourceType, int resourceId) {
         return (resourceType & 0x000000ff) << 24
                 | (resourceId << 16)
                 | (mResourceRequestCount++ & 0xffff);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c4545fa..00c6f3a 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5936,7 +5936,7 @@
         if (win == null) {
             return;
         }
-        final Rect frame = win.getFrameLw();
+        final Rect frame = win.getRelativeFrameLw();
         final int thumbnailDrawableRes = task.mUserId == mWmService.mCurrentUserId
                 ? R.drawable.ic_account_circle
                 : R.drawable.ic_corp_badge;
@@ -5946,12 +5946,12 @@
         if (thumbnail == null) {
             return;
         }
-        final Transaction transaction = getAnimatingContainer().getPendingTransaction();
+        final Transaction transaction = getPendingTransaction();
         mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory,
-                transaction, getAnimatingContainer(), thumbnail);
+                transaction, getTask(), thumbnail);
         final Animation animation =
                 getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
-                        win.getFrameLw());
+                        frame);
         mThumbnail.startAnimation(transaction, animation, new Point(frame.left, frame.top));
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 4ebb423..e8bfe8e 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -1510,7 +1510,7 @@
      */
     @StackVisibility
     int getVisibility(ActivityRecord starting) {
-        if (!isAttached() || mForceHidden) {
+        if (!isAttached() || isForceHidden()) {
             return STACK_VISIBILITY_INVISIBLE;
         }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 6d7f8fb..57f357d 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -75,6 +75,7 @@
 import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
 import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
 import static com.android.server.wm.RootWindowContainer.TAG_STATES;
+import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
 import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE;
 import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
 import static com.android.server.wm.Task.LOCK_TASK_AUTH_WHITELISTED;
@@ -1565,9 +1566,9 @@
              * stopping list by handling the idle.
              */
             stack.cancelAnimation();
-            stack.mForceHidden = true;
+            stack.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */);
             stack.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
-            stack.mForceHidden = false;
+            stack.setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, false /* set */);
             activityIdleInternal(null /* idleActivity */, false /* fromTimeout */,
                     true /* processPausingActivities */, null /* configuration */);
 
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 1009771..57b6024 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -178,7 +178,7 @@
             // before issuing the work challenge.
             return true;
         }
-        return interceptWorkProfileChallengeIfNeeded();
+        return interceptLockedManagedProfileIfNeeded();
     }
 
     private boolean hasCrossProfileAnimation() {
@@ -296,7 +296,7 @@
         return true;
     }
 
-    private boolean interceptWorkProfileChallengeIfNeeded() {
+    private boolean interceptLockedManagedProfileIfNeeded() {
         final Intent interceptingIntent = interceptWithConfirmCredentialsIfNeeded(mAInfo, mUserId);
         if (interceptingIntent == null) {
             return false;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index ab96c61..38a406e 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -28,6 +28,7 @@
 import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT;
 import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
 import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
+import static android.view.InsetsState.ITYPE_CAPTION_BAR;
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT;
 import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
@@ -1024,6 +1025,13 @@
             case TYPE_STATUS_BAR_PANEL:
                 return WindowManagerGlobal.ADD_INVALID_TYPE;
         }
+
+        if (attrs.providesInsetsTypes != null) {
+            mContext.enforcePermission(
+                    android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
+                    "DisplayPolicy");
+            enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providesInsetsTypes);
+        }
         return ADD_OKAY;
     }
 
@@ -1110,6 +1118,28 @@
                         });
                 if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                 break;
+            default:
+                if (attrs.providesInsetsTypes != null) {
+                    for (int insetsType : attrs.providesInsetsTypes) {
+                        mDisplayContent.setInsetProvider(insetsType, win, null);
+                    }
+                }
+                break;
+        }
+    }
+
+    private static void enforceSingleInsetsTypeCorrespondingToWindowType(int[] insetsTypes) {
+        int count = 0;
+        for (int insetsType : insetsTypes) {
+            switch (insetsType) {
+                case ITYPE_NAVIGATION_BAR:
+                case ITYPE_STATUS_BAR:
+                case ITYPE_CAPTION_BAR:
+                    if (++count > 1) {
+                        throw new IllegalArgumentException(
+                                "Multiple InsetsTypes corresponding to Window type");
+                    }
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 19f8ca9..aa817fd 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -36,6 +36,7 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.function.Supplier;
 
 /**
  * A class that can run animations on objects that have a set of child surfaces. We do this by
@@ -145,7 +146,7 @@
         if (mLeash == null) {
             mLeash = createAnimationLeash(mAnimatable, surface, t, type,
                     mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
-                    0 /* y */, hidden);
+                    0 /* y */, hidden, mService.mTransactionFactory);
             mAnimatable.onAnimationLeashCreated(t, mLeash);
         }
         mAnimatable.onLeashAnimationStarting(t, mLeash);
@@ -374,13 +375,21 @@
 
     static SurfaceControl createAnimationLeash(Animatable animatable, SurfaceControl surface,
             Transaction t, @AnimationType int type, int width, int height, int x, int y,
-            boolean hidden) {
+            boolean hidden, Supplier<Transaction> transactionFactory) {
         if (DEBUG_ANIM) Slog.i(TAG, "Reparenting to leash");
         final SurfaceControl.Builder builder = animatable.makeAnimationLeash()
                 .setParent(animatable.getAnimationLeashParent())
-                .setHidden(hidden)
                 .setName(surface + " - animation-leash");
         final SurfaceControl leash = builder.build();
+        if (!hidden) {
+            // TODO(b/151665759) Defer reparent calls
+            // We want the leash to be visible immediately but we want to set the effects on
+            // the layer. Since the transaction used in this function may be deferred, we apply
+            // another transaction immediately with the correct visibility and effects.
+            // If this doesn't work, you will can see the 2/3 button nav bar flicker during
+            // seamless rotation.
+            transactionFactory.get().unsetColor(leash).show(leash).apply();
+        }
         t.setWindowCrop(leash, width, height);
         t.setPosition(leash, x, y);
         t.show(leash);
diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java
index a696daf..8ab5043 100644
--- a/services/core/java/com/android/server/wm/SurfaceFreezer.java
+++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java
@@ -75,7 +75,8 @@
 
         mLeash = SurfaceAnimator.createAnimationLeash(mAnimatable, mAnimatable.getSurfaceControl(),
                 t, ANIMATION_TYPE_SCREEN_ROTATION, startBounds.width(), startBounds.height(),
-                startBounds.left, startBounds.top, false /* hidden */);
+                startBounds.left, startBounds.top, false /* hidden */,
+                mWmService.mTransactionFactory);
         mAnimatable.onAnimationLeashCreated(t, mLeash);
 
         SurfaceControl freezeTarget = mAnimatable.getFreezeSnapshotTarget();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index e78f2ee..f826deb 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -431,7 +431,10 @@
     private boolean mForceShowForAllUsers;
 
     /** When set, will force the task to report as invisible. */
-    boolean mForceHidden = false;
+    static final int FLAG_FORCE_HIDDEN_FOR_PINNED_TASK = 1;
+    static final int FLAG_FORCE_HIDDEN_FOR_TASK_ORG = 1 << 1;
+    private int mForceHiddenFlags = 0;
+
 
     SurfaceControl.Transaction mMainWindowSizeChangeTransaction;
 
@@ -3047,7 +3050,7 @@
      */
     @VisibleForTesting
     boolean isTranslucent(ActivityRecord starting) {
-        if (!isAttached() || mForceHidden) {
+        if (!isAttached() || isForceHidden()) {
             return true;
         }
         final PooledPredicate p = PooledLambda.obtainPredicate(Task::isOpaqueActivity,
@@ -4045,17 +4048,17 @@
             return;
         }
         // Let the old organizer know it has lost control.
-        if (mTaskOrganizer != null) {
-            sendTaskVanished();
-        }
+        sendTaskVanished();
         mTaskOrganizer = organizer;
         sendTaskAppeared();
+        onTaskOrganizerChanged();
     }
 
     // Called on Binder death.
     void taskOrganizerDied() {
         mTaskOrganizer = null;
         mLastTaskOrganizerWindowingMode = -1;
+        onTaskOrganizerChanged();
     }
 
     /**
@@ -4090,6 +4093,14 @@
         mLastTaskOrganizerWindowingMode = windowingMode;
     }
 
+    private void onTaskOrganizerChanged() {
+        if (mTaskOrganizer == null) {
+            // If this task is no longer controlled by a task organizer, then reset the force hidden
+            // state
+            setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, false /* set */);
+        }
+    }
+
     @Override
     void setSurfaceControl(SurfaceControl sc) {
         super.setSurfaceControl(sc);
@@ -4200,6 +4211,31 @@
         c.recycle();
     }
 
+    /**
+     * Sets/unsets the forced-hidden state flag for this task depending on {@param set}.
+     * @return Whether the force hidden state changed
+     */
+    boolean setForceHidden(int flags, boolean set) {
+        int newFlags = mForceHiddenFlags;
+        if (set) {
+            newFlags |= flags;
+        } else {
+            newFlags &= ~flags;
+        }
+        if (mForceHiddenFlags == newFlags) {
+            return false;
+        }
+        mForceHiddenFlags = newFlags;
+        return true;
+    }
+
+    /**
+     * Returns whether this task is currently forced to be hidden for any reason.
+     */
+    protected boolean isForceHidden() {
+        return mForceHiddenFlags != 0;
+    }
+
     @Override
     long getProtoFieldId() {
         return TASK;
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 9cbc9ee..8f09f3f 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -23,6 +23,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 
 import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
@@ -475,6 +476,7 @@
         if (!(container instanceof Task)) {
             throw new RuntimeException("Invalid token in task transaction");
         }
+        final Task task = (Task) container;
         // The "client"-facing API should prevent bad changes; however, just in case, sanitize
         // masks here.
         int configMask = change.getConfigSetMask();
@@ -498,6 +500,11 @@
                 effects |= TRANSACT_EFFECTS_LIFECYCLE;
             }
         }
+        if ((change.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) {
+            if (task.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, change.getHidden())) {
+                effects |= TRANSACT_EFFECTS_LIFECYCLE;
+            }
+        }
         return effects;
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index f83b052..0f5cafe 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -352,9 +352,19 @@
         }
         task.getBounds(mTmpRect);
         mTmpRect.offsetTo(0, 0);
+
+        SurfaceControl[] excludeLayers;
+        final WindowState imeWindow = task.getDisplayContent().mInputMethodWindow;
+        if (imeWindow != null) {
+            excludeLayers = new SurfaceControl[1];
+            excludeLayers[0] = imeWindow.getSurfaceControl();
+        } else {
+            excludeLayers = new SurfaceControl[0];
+        }
         final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
-                SurfaceControl.captureLayers(
-                        task.getSurfaceControl(), mTmpRect, scaleFraction, pixelFormat);
+                SurfaceControl.captureLayersExcluding(
+                        task.getSurfaceControl(), mTmpRect, scaleFraction,
+                        pixelFormat, excludeLayers);
         if (outTaskSize != null) {
             outTaskSize.x = mTmpRect.width();
             outTaskSize.y = mTmpRect.height();
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 9a92832..a1902bb 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -2476,9 +2476,12 @@
 
     boolean prepareForSync(BLASTSyncEngine.TransactionReadyListener waitingListener,
             int waitingId) {
-        boolean willSync = false;
-        if (!isVisible()) {
-            return willSync;
+        boolean willSync = true;
+
+        // If we are invisible, no need to sync, likewise if we are already engaged in a sync,
+        // we can't support overlapping syncs on a single container yet.
+        if (!isVisible() || mWaitingListener != null) {
+            return false;
         }
         mUsingBLASTSyncTransaction = true;
 
diff --git a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
index 90e3be7..a27a112 100644
--- a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
+++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
@@ -97,7 +97,7 @@
         // TODO: This should be attached as a child to the app token, once the thumbnail animations
         // use relative coordinates. Once we start animating task we can also consider attaching
         // this to the task.
-        mSurfaceControl = mWindowContainer.makeSurface()
+        mSurfaceControl = mWindowContainer.makeChildSurface(mWindowContainer.getTopChild())
                 .setName("thumbnail anim: " + mWindowContainer.toString())
                 .setBufferSize(mWidth, mHeight)
                 .setFormat(PixelFormat.TRANSLUCENT)
@@ -209,7 +209,7 @@
 
     @Override
     public Builder makeAnimationLeash() {
-        return mWindowContainer.makeSurface();
+        return mWindowContainer.makeChildSurface(mWindowContainer.getTopChild());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1a77807..eb18678 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -186,7 +186,6 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.service.vr.IVrManager;
 import android.service.vr.IVrStateCallbacks;
@@ -882,7 +881,13 @@
                     FEATURE_FREEFORM_WINDOW_MANAGEMENT) || Settings.Global.getInt(
                     resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
 
-            mAtmService.mSupportsFreeformWindowManagement = freeformWindowManagement;
+            if (mAtmService.mSupportsFreeformWindowManagement != freeformWindowManagement) {
+                mAtmService.mSupportsFreeformWindowManagement = freeformWindowManagement;
+                synchronized (mGlobalLock) {
+                    // Notify the root window container that the display settings value may change.
+                    mRoot.onSettingsRetrieved();
+                }
+            }
         }
 
         void updateForceResizableTasks() {
@@ -1162,9 +1167,7 @@
         mAnimator = new WindowAnimator(this);
         mRoot = new RootWindowContainer(this);
 
-        mUseBLAST = DeviceConfig.getBoolean(
-                    DeviceConfig.NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT,
-                    WM_USE_BLAST_ADAPTER_FLAG, false);
+        mUseBLAST = true;
 
         mWindowPlacerLocked = new WindowSurfacePlacer(this);
         mTaskSnapshotController = new TaskSnapshotController(this);
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 336934e..822f383 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1448,13 +1448,13 @@
 
     SET(BasebandCn0DbHz, measurement_V2_1->basebandCN0DbHz);
 
-    if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_RECEIVER_ISB) {
-        SET(ReceiverInterSignalBiasNanos, measurement_V2_1->receiverInterSignalBiasNs);
+    if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_FULL_ISB) {
+        SET(FullInterSignalBiasNanos, measurement_V2_1->fullInterSignalBiasNs);
     }
 
-    if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_RECEIVER_ISB_UNCERTAINTY) {
-        SET(ReceiverInterSignalBiasUncertaintyNanos,
-            measurement_V2_1->receiverInterSignalBiasUncertaintyNs);
+    if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_FULL_ISB_UNCERTAINTY) {
+        SET(FullInterSignalBiasUncertaintyNanos,
+            measurement_V2_1->fullInterSignalBiasUncertaintyNs);
     }
 
     if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_SATELLITE_ISB) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index fc9044a..6ab5303 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1076,6 +1076,7 @@
         private static final String TAG_PROFILE_OFF_DEADLINE = "profile-off-deadline";
         private static final String TAG_ALWAYS_ON_VPN_PACKAGE = "vpn-package";
         private static final String TAG_ALWAYS_ON_VPN_LOCKDOWN = "vpn-lockdown";
+        private static final String TAG_COMMON_CRITERIA_MODE = "common-criteria-mode";
         DeviceAdminInfo info;
 
 
@@ -1206,7 +1207,7 @@
 
         public String mAlwaysOnVpnPackage;
         public boolean mAlwaysOnVpnLockdown;
-
+        boolean mCommonCriteriaMode;
 
         ActiveAdmin(DeviceAdminInfo _info, boolean parent) {
             info = _info;
@@ -1454,6 +1455,9 @@
             if (mAlwaysOnVpnLockdown) {
                 writeAttributeValueToXml(out, TAG_ALWAYS_ON_VPN_LOCKDOWN, mAlwaysOnVpnLockdown);
             }
+            if (mCommonCriteriaMode) {
+                writeAttributeValueToXml(out, TAG_COMMON_CRITERIA_MODE, mCommonCriteriaMode);
+            }
         }
 
         void writeTextToXml(XmlSerializer out, String tag, String text) throws IOException {
@@ -1704,6 +1708,9 @@
                 } else if (TAG_ALWAYS_ON_VPN_LOCKDOWN.equals(tag)) {
                     mAlwaysOnVpnLockdown = Boolean.parseBoolean(
                             parser.getAttributeValue(null, ATTR_VALUE));
+                } else if (TAG_COMMON_CRITERIA_MODE.equals(tag)) {
+                    mCommonCriteriaMode = Boolean.parseBoolean(
+                            parser.getAttributeValue(null, ATTR_VALUE));
                 } else {
                     Slog.w(LOG_TAG, "Unknown admin tag: " + tag);
                     XmlUtils.skipCurrentTag(parser);
@@ -1940,6 +1947,8 @@
             pw.println(mAlwaysOnVpnPackage);
             pw.print("mAlwaysOnVpnLockdown=");
             pw.println(mAlwaysOnVpnLockdown);
+            pw.print("mCommonCriteriaMode=");
+            pw.println(mCommonCriteriaMode);
         }
     }
 
@@ -15606,28 +15615,38 @@
     }
 
     @Override
-    public void setCommonCriteriaModeEnabled(ComponentName admin, boolean enabled) {
+    public void setCommonCriteriaModeEnabled(ComponentName who, boolean enabled) {
+        final int userId = mInjector.userHandleGetCallingUserId();
         synchronized (getLockObject()) {
-            getActiveAdminForCallerLocked(admin,
+            final ActiveAdmin admin = getActiveAdminForCallerLocked(who,
                     DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER);
+            admin.mCommonCriteriaMode = enabled;
+            saveSettingsLocked(userId);
         }
-        mInjector.binderWithCleanCallingIdentity(
-                () -> mInjector.settingsGlobalPutInt(Settings.Global.COMMON_CRITERIA_MODE,
-                        enabled ? 1 : 0));
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.SET_COMMON_CRITERIA_MODE)
-                .setAdmin(admin)
+                .setAdmin(who)
                 .setBoolean(enabled)
                 .write();
     }
 
     @Override
-    public boolean isCommonCriteriaModeEnabled(ComponentName admin) {
-        synchronized (getLockObject()) {
-            getActiveAdminForCallerLocked(admin,
-                    DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER);
+    public boolean isCommonCriteriaModeEnabled(ComponentName who) {
+        if (who != null) {
+            synchronized (getLockObject()) {
+                final ActiveAdmin admin = getActiveAdminForCallerLocked(who,
+                        DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER);
+                return admin.mCommonCriteriaMode;
+            }
         }
-        return mInjector.settingsGlobalGetInt(Settings.Global.COMMON_CRITERIA_MODE, 0) != 0;
+        // Return aggregated state if caller is not admin (who == null).
+        synchronized (getLockObject()) {
+            // Only DO or COPE PO can turn on CC mode, so take a shortcut here and only look at
+            // their ActiveAdmin, instead of iterating through all admins.
+            final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
+                    UserHandle.USER_SYSTEM);
+            return admin != null ? admin.mCommonCriteriaMode : false;
+        }
     }
 
     @Override
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 7275936..2eadece 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -941,7 +941,7 @@
     if (!dataloader) {
         return false;
     }
-    status = dataloader->start();
+    status = dataloader->start(mountId);
     if (!status.isOk()) {
         return false;
     }
@@ -1090,7 +1090,9 @@
             base::unique_fd(::dup(ifs.control.pendingReads)));
     fsControlParcel.incremental->log.reset(base::unique_fd(::dup(ifs.control.logs)));
     sp<IncrementalDataLoaderListener> listener =
-            new IncrementalDataLoaderListener(*this, *externalListener);
+            new IncrementalDataLoaderListener(*this,
+                                              externalListener ? *externalListener
+                                                               : DataLoaderStatusListener());
     bool created = false;
     auto status = mDataLoaderManager->initializeDataLoader(ifs.mountId, *dlp, fsControlParcel,
                                                            listener, &created);
@@ -1230,8 +1232,8 @@
         std::unique_lock l(incrementalService.mLock);
         const auto& ifs = incrementalService.getIfsLocked(mountId);
         if (!ifs) {
-            LOG(WARNING) << "Received data loader status " << int(newStatus) << " for unknown mount "
-                         << mountId;
+            LOG(WARNING) << "Received data loader status " << int(newStatus)
+                         << " for unknown mount " << mountId;
             return binder::Status::ok();
         }
         ifs->dataLoaderStatus = newStatus;
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 6002226..f5b88d9 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -100,10 +100,11 @@
                           const sp<IDataLoaderStatusListener>&) override {
         return binder::Status::ok();
     }
-    binder::Status start() override { return binder::Status::ok(); }
-    binder::Status stop() override { return binder::Status::ok(); }
-    binder::Status destroy() override { return binder::Status::ok(); }
-    binder::Status prepareImage(const std::vector<InstallationFileParcel>&,
+    binder::Status start(int32_t) override { return binder::Status::ok(); }
+    binder::Status stop(int32_t) override { return binder::Status::ok(); }
+    binder::Status destroy(int32_t) override { return binder::Status::ok(); }
+    binder::Status prepareImage(int32_t,
+                                const std::vector<InstallationFileParcel>&,
                                 const std::vector<std::string>&) override {
         return binder::Status::ok();
     }
diff --git a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
index 84421ef..77b5b61 100644
--- a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
+++ b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
@@ -166,7 +166,7 @@
         PowerManager powerManager =
                 (PowerManager) application.getSystemService(Context.POWER_SERVICE);
         return new UserBackupManagerService.BackupWakeLock(
-                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*"));
+                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*"), 0);
     }
 
     /**
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
index efe8119..23381ff 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -46,6 +46,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManagerInternal;
 import android.os.Debug;
+import android.os.FileUtils;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Process;
@@ -55,6 +56,7 @@
 import android.text.TextUtils;
 import android.util.Pair;
 
+import com.android.internal.util.ArrayUtils;
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.appop.AppOpsService;
@@ -71,10 +73,17 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
+import java.util.Random;
+import java.util.zip.GZIPInputStream;
 
 /**
  * Test class for {@link android.app.ApplicationExitInfo}.
@@ -119,6 +128,8 @@
         setFieldValue(AppExitInfoTracker.class, mAppExitInfoTracker, "mAppExitInfoSourceLmkd",
                 spy(mAppExitInfoTracker.new AppExitInfoExternalSource("lmkd",
                 ApplicationExitInfo.REASON_LOW_MEMORY)));
+        setFieldValue(AppExitInfoTracker.class, mAppExitInfoTracker, "mAppTraceRetriever",
+                spy(mAppExitInfoTracker.new AppTraceRetriever()));
         setFieldValue(ProcessList.class, mProcessList, "mAppExitInfoTracker", mAppExitInfoTracker);
         mInjector = new TestInjector(mContext);
         mAms = new ActivityManagerService(mInjector, mServiceThreadRule.getThread());
@@ -169,6 +180,11 @@
     public void testApplicationExitInfo() throws Exception {
         mAppExitInfoTracker.clearProcessExitInfo(true);
         mAppExitInfoTracker.mAppExitInfoLoaded = true;
+        mAppExitInfoTracker.mProcExitStoreDir = new File(mContext.getFilesDir(),
+                AppExitInfoTracker.APP_EXIT_STORE_DIR);
+        assertTrue(FileUtils.createDir(mAppExitInfoTracker.mProcExitStoreDir));
+        mAppExitInfoTracker.mProcExitInfoFile = new File(mAppExitInfoTracker.mProcExitStoreDir,
+                AppExitInfoTracker.APP_EXIT_INFO_FILE);
 
         // Test application calls System.exit()
         doNothing().when(mAppExitInfoTracker).schedulePersistProcessExitInfo(anyBoolean());
@@ -188,6 +204,10 @@
         final long app1Rss3 = 45680;
         final String app1ProcessName = "com.android.test.stub1:process";
         final String app1PackageName = "com.android.test.stub1";
+        final byte[] app1Cookie1 = {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
+                (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08};
+        final byte[] app1Cookie2 = {(byte) 0x08, (byte) 0x07, (byte) 0x06, (byte) 0x05,
+                (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x01};
 
         final long now1 = System.currentTimeMillis();
         ProcessRecord app = makeProcessRecord(
@@ -204,6 +224,9 @@
 
         // Case 1: basic System.exit() test
         int exitCode = 5;
+        mAppExitInfoTracker.setProcessStateSummary(app1Uid, app1Pid1, app1Cookie1);
+        assertTrue(ArrayUtils.equals(mAppExitInfoTracker.getProcessStateSummary(app1Uid,
+                app1Pid1), app1Cookie1, app1Cookie1.length));
         doReturn(new Pair<Long, Object>(now1, Integer.valueOf(makeExitStatus(exitCode))))
                 .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
                 .remove(anyInt(), anyInt());
@@ -235,6 +258,10 @@
                 IMPORTANCE_CACHED,                    // importance
                 null);                                // description
 
+        assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), app1Cookie1,
+                app1Cookie1.length));
+        assertEquals(info.getTraceInputStream(), null);
+
         // Case 2: create another app1 process record with a different pid
         sleep(1);
         final long now2 = System.currentTimeMillis();
@@ -250,6 +277,12 @@
                 app1ProcessName,        // processName
                 app1PackageName);       // packageName
         exitCode = 6;
+
+        mAppExitInfoTracker.setProcessStateSummary(app1Uid, app1Pid2, app1Cookie1);
+        // Override with a different cookie
+        mAppExitInfoTracker.setProcessStateSummary(app1Uid, app1Pid2, app1Cookie2);
+        assertTrue(ArrayUtils.equals(mAppExitInfoTracker.getProcessStateSummary(app1Uid,
+                app1Pid2), app1Cookie2, app1Cookie2.length));
         doReturn(new Pair<Long, Object>(now2, Integer.valueOf(makeExitStatus(exitCode))))
                 .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
                 .remove(anyInt(), anyInt());
@@ -280,6 +313,12 @@
                 IMPORTANCE_SERVICE,                   // importance
                 null);                                // description
 
+        assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), app1Cookie2,
+                app1Cookie2.length));
+        info = list.get(1);
+        assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), app1Cookie1,
+                app1Cookie1.length));
+
         // Case 3: Create an instance of app1 with different user, and died because of SIGKILL
         sleep(1);
         final long now3 = System.currentTimeMillis();
@@ -702,9 +741,19 @@
                 app1PackageName);             // packageName
 
         mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app1IsolatedUid2User2, app1UidUser2);
+
+        // Pretent it gets an ANR trace too (although the reason here should be REASON_ANR)
+        final File traceFile = new File(mContext.getFilesDir(), "anr_original.txt");
+        final int traceSize = 10240;
+        final int traceStart = 1024;
+        final int traceEnd = 8192;
+        createRandomFile(traceFile, traceSize);
+        assertEquals(traceSize, traceFile.length());
+        mAppExitInfoTracker.handleLogAnrTrace(app.pid, app.uid, app.getPackageList(),
+                traceFile, traceStart, traceEnd);
+
         noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
                 ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY, app1Description2);
-
         updateExitInfo(app);
         list.clear();
         mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1Pid2User2, 1, list);
@@ -729,6 +778,10 @@
                 IMPORTANCE_CACHED,                            // importance
                 app1Description2);                            // description
 
+        // Verify if the traceFile get copied into the records correctly.
+        verifyTraceFile(traceFile, traceStart, info.getTraceFile(), 0, traceEnd - traceStart);
+        traceFile.delete();
+        info.getTraceFile().delete();
 
         // Case 9: User2 gets removed
         sleep(1);
@@ -801,8 +854,6 @@
         mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, original);
         assertTrue(original.size() > 0);
 
-        mAppExitInfoTracker.mProcExitInfoFile = new File(mContext.getFilesDir(),
-                AppExitInfoTracker.APP_EXIT_INFO_FILE);
         mAppExitInfoTracker.persistProcessExitInfo();
         assertTrue(mAppExitInfoTracker.mProcExitInfoFile.exists());
 
@@ -836,6 +887,37 @@
         }
     }
 
+    private static void createRandomFile(File file, int size) throws IOException {
+        try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
+            Random random = new Random();
+            byte[] buf = random.ints('a', 'z').limit(size).collect(
+                    StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
+                    .toString().getBytes();
+            out.write(buf);
+        }
+    }
+
+    private static void verifyTraceFile(File originFile, int originStart, File traceFile,
+            int traceStart, int length) throws IOException {
+        assertTrue(originFile.exists());
+        assertTrue(traceFile.exists());
+        assertTrue(originStart < originFile.length());
+        try (GZIPInputStream traceIn = new GZIPInputStream(new FileInputStream(traceFile));
+            BufferedInputStream originIn = new BufferedInputStream(
+                    new FileInputStream(originFile))) {
+            assertEquals(traceStart, traceIn.skip(traceStart));
+            assertEquals(originStart, originIn.skip(originStart));
+            byte[] buf1 = new byte[8192];
+            byte[] buf2 = new byte[8192];
+            while (length > 0) {
+                int len = traceIn.read(buf1, 0, Math.min(buf1.length, length));
+                assertEquals(len, originIn.read(buf2, 0, len));
+                assertTrue(ArrayUtils.equals(buf1, buf2, len));
+                length -= len;
+            }
+        }
+    }
+
     private ProcessRecord makeProcessRecord(int pid, int uid, int packageUid, Integer definingUid,
             int connectionGroup, int procState, long pss, long rss,
             String processName, String packageName) {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index d038d6c..f57b5f2 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -5990,26 +5990,29 @@
     public void testSetCommonCriteriaMode_asDeviceOwner() throws Exception {
         setDeviceOwner();
 
-        dpm.setCommonCriteriaModeEnabled(admin1, true);
-        verify(getServices().settings).settingsGlobalPutInt(
-                Settings.Global.COMMON_CRITERIA_MODE, 1);
+        assertFalse(dpm.isCommonCriteriaModeEnabled(admin1));
+        assertFalse(dpm.isCommonCriteriaModeEnabled(null));
 
-        when(getServices().settings.settingsGlobalGetInt(Settings.Global.COMMON_CRITERIA_MODE, 0))
-                .thenReturn(1);
+        dpm.setCommonCriteriaModeEnabled(admin1, true);
+
         assertTrue(dpm.isCommonCriteriaModeEnabled(admin1));
+        assertTrue(dpm.isCommonCriteriaModeEnabled(null));
     }
 
     public void testSetCommonCriteriaMode_asPoOfOrgOwnedDevice() throws Exception {
-        setupProfileOwner();
-        configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+        final int managedProfileUserId = 15;
+        final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+        addManagedProfile(admin1, managedProfileAdminUid, admin1);
+        configureProfileOwnerOfOrgOwnedDevice(admin1, managedProfileUserId);
+        mContext.binder.callingUid = managedProfileAdminUid;
+
+        assertFalse(dpm.isCommonCriteriaModeEnabled(admin1));
+        assertFalse(dpm.isCommonCriteriaModeEnabled(null));
 
         dpm.setCommonCriteriaModeEnabled(admin1, true);
-        verify(getServices().settings).settingsGlobalPutInt(
-                Settings.Global.COMMON_CRITERIA_MODE, 1);
 
-        when(getServices().settings.settingsGlobalGetInt(Settings.Global.COMMON_CRITERIA_MODE, 0))
-                .thenReturn(1);
         assertTrue(dpm.isCommonCriteriaModeEnabled(admin1));
+        assertTrue(dpm.isCommonCriteriaModeEnabled(null));
     }
 
     public void testCanProfileOwnerResetPasswordWhenLocked_nonDirectBootAwarePo()
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/FakeSettings.java b/services/tests/servicestests/src/com/android/server/locksettings/FakeSettings.java
index 70a927c..c5e924b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/FakeSettings.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/FakeSettings.java
@@ -15,16 +15,23 @@
  */
 package com.android.server.locksettings;
 
+import android.content.ContentResolver;
+import android.os.UserHandle;
 import android.provider.Settings;
 
 public class FakeSettings {
 
     private int mDeviceProvisioned;
+    private int mSecureFrpMode;
 
     public void setDeviceProvisioned(boolean provisioned) {
         mDeviceProvisioned = provisioned ? 1 : 0;
     }
 
+    public void setSecureFrpMode(boolean secure) {
+        mSecureFrpMode = secure ? 1 : 0;
+    }
+
     public int globalGetInt(String keyName) {
         switch (keyName) {
             case Settings.Global.DEVICE_PROVISIONED:
@@ -33,4 +40,12 @@
                 throw new IllegalArgumentException("Unhandled global settings: " + keyName);
         }
     }
+
+    public int secureGetInt(ContentResolver contentResolver, String keyName, int defaultValue,
+            int userId) {
+        if (Settings.Secure.SECURE_FRP_MODE.equals(keyName) && userId == UserHandle.USER_SYSTEM) {
+            return mSecureFrpMode;
+        }
+        return defaultValue;
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 1ff451b..4e1454b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -124,6 +124,12 @@
         }
 
         @Override
+        public int settingsSecureGetInt(ContentResolver contentResolver, String keyName,
+                int defaultValue, int userId) {
+            return mSettings.secureGetInt(contentResolver, keyName, defaultValue, userId);
+        }
+
+        @Override
         public UserManagerInternal getUserManagerInternal() {
             return mUserManagerInternal;
         }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 684bbd4..661ce11 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -416,6 +416,15 @@
                         eq(CREDENTIAL_TYPE_PASSWORD), any(), eq(MANAGED_PROFILE_USER_ID));
     }
 
+    @Test
+    public void testCredentialChangeNotPossibleInSecureFrpMode() {
+        mSettings.setSecureFrpMode(true);
+        try {
+            mService.setLockCredential(newPassword("1234"), nonePassword(), PRIMARY_USER_ID);
+            fail("Password shouldn't be changeable before FRP unlock");
+        } catch (SecurityException e) { }
+    }
+
     private void testCreateCredential(int userId, LockscreenCredential credential)
             throws RemoteException {
         assertTrue(mService.setLockCredential(credential, nonePassword(), userId));
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 7e3cfc8..128177b 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -1084,7 +1084,7 @@
 
         // pretend that 512 bytes total have happened
         stats = new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
+                .insertEntry(TEST_IFACE, 256L, 2L, 256L, 2L);
         when(mStatsService.getNetworkTotalBytes(sTemplateWifi, CYCLE_START, CYCLE_END))
                 .thenReturn(stats.getTotalBytes());
 
@@ -1276,11 +1276,11 @@
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
             stats.clear();
-            stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
-            stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
-            stats.addEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
 
             reset(mNotifManager);
@@ -1304,9 +1304,9 @@
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
             stats.clear();
-            stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0);
-            stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
 
             reset(mNotifManager);
@@ -1338,7 +1338,7 @@
         // bring up wifi network with metered policy
         state = new NetworkState[] { buildWifi() };
         stats = new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 0L, 0L, 0L, 0L);
 
         {
             when(mConnManager.getAllNetworkState()).thenReturn(state);
@@ -1769,7 +1769,7 @@
         final int CYCLE_DAY = 15;
 
         final NetworkStats stats = new NetworkStats(0L, 1);
-        stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
+        stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
                 2999, 1, 2000, 1, 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
                 .thenReturn(stats.getTotalBytes());
@@ -1793,7 +1793,7 @@
         reset(mStatsService);
 
         // Increase the usage.
-        stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
+        stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
                 1000, 1, 999, 1, 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
                 .thenReturn(stats.getTotalBytes());
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index 5d5c714..22591c6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -31,6 +31,7 @@
 import android.content.pm.Signature;
 import android.content.pm.parsing.ParsingPackage;
 import android.content.pm.parsing.component.ParsedActivity;
+import android.content.pm.parsing.component.ParsedInstrumentation;
 import android.content.pm.parsing.component.ParsedIntentInfo;
 import android.content.pm.parsing.component.ParsedProvider;
 import android.os.Build;
@@ -135,6 +136,13 @@
                 .addActivity(activity);
     }
 
+    private static ParsingPackage pkgWithInstrumentation(
+            String packageName, String instrumentationTargetPackage) {
+        ParsedInstrumentation instrumentation = new ParsedInstrumentation();
+        instrumentation.setTargetPackage(instrumentationTargetPackage);
+        return pkg(packageName).addInstrumentation(instrumentation);
+    }
+
     private static ParsingPackage pkgWithProvider(String packageName, String authority) {
         ParsedProvider provider = new ParsedProvider();
         provider.setPackageName(packageName);
@@ -608,6 +616,25 @@
         assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
     }
 
+    @Test
+    public void testInstrumentation_DoesntFilter() {
+        final AppsFilter appsFilter =
+                new AppsFilter(mFeatureConfigMock, new String[]{}, false, null);
+        appsFilter.onSystemReady();
+
+
+        PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
+                DUMMY_TARGET_UID);
+        PackageSetting instrumentation = simulateAddPackage(appsFilter,
+                pkgWithInstrumentation("com.some.other.package", "com.some.package"),
+                DUMMY_CALLING_UID);
+
+        assertFalse(
+                appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, instrumentation, target, 0));
+        assertFalse(
+                appsFilter.shouldFilterApplication(DUMMY_TARGET_UID, target, instrumentation, 0));
+    }
+
     private interface WithSettingBuilder {
         PackageSettingBuilder withBuilder(PackageSettingBuilder builder);
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 6c769485..6a88298 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -94,6 +94,8 @@
 import com.android.server.SystemService;
 import com.android.server.pm.LauncherAppsService.LauncherAppsImpl;
 import com.android.server.pm.ShortcutUser.PackageWithUser;
+import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.uri.UriPermissionOwner;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import org.junit.Assert;
@@ -630,6 +632,9 @@
     protected UsageStatsManagerInternal mMockUsageStatsManagerInternal;
     protected ActivityManagerInternal mMockActivityManagerInternal;
     protected ActivityTaskManagerInternal mMockActivityTaskManagerInternal;
+    protected UriGrantsManagerInternal mMockUriGrantsManagerInternal;
+
+    protected UriPermissionOwner mUriPermissionOwner;
 
     protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
     protected static final int CALLING_UID_1 = 10001;
@@ -771,6 +776,7 @@
         mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class);
         mMockActivityManagerInternal = mock(ActivityManagerInternal.class);
         mMockActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
+        mMockUriGrantsManagerInternal = mock(UriGrantsManagerInternal.class);
 
         LocalServices.removeServiceForTest(PackageManagerInternal.class);
         LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
@@ -782,6 +788,10 @@
         LocalServices.addService(ActivityTaskManagerInternal.class, mMockActivityTaskManagerInternal);
         LocalServices.removeServiceForTest(UserManagerInternal.class);
         LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal);
+        LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
+        LocalServices.addService(UriGrantsManagerInternal.class, mMockUriGrantsManagerInternal);
+
+        mUriPermissionOwner = new UriPermissionOwner(mMockUriGrantsManagerInternal, TAG);
 
         // Prepare injection values.
 
@@ -2193,6 +2203,7 @@
         for (ShortcutInfo s : actualShortcuts) {
             assertTrue("ID " + s.getId() + " not have icon res ID", s.hasIconResource());
             assertFalse("ID " + s.getId() + " shouldn't have icon FD", s.hasIconFile());
+            assertFalse("ID " + s.getId() + " shouldn't have icon URI", s.hasIconUri());
         }
         return actualShortcuts;
     }
@@ -2202,6 +2213,17 @@
         for (ShortcutInfo s : actualShortcuts) {
             assertFalse("ID " + s.getId() + " shouldn't have icon res ID", s.hasIconResource());
             assertTrue("ID " + s.getId() + " not have icon FD", s.hasIconFile());
+            assertFalse("ID " + s.getId() + " shouldn't have icon URI", s.hasIconUri());
+        }
+        return actualShortcuts;
+    }
+
+    public static List<ShortcutInfo> assertAllHaveIconUri(
+            List<ShortcutInfo> actualShortcuts) {
+        for (ShortcutInfo s : actualShortcuts) {
+            assertFalse("ID " + s.getId() + " shouldn't have icon res ID", s.hasIconResource());
+            assertFalse("ID " + s.getId() + " shouldn't have have icon FD", s.hasIconFile());
+            assertTrue("ID " + s.getId() + " not have icon URI", s.hasIconUri());
         }
         return actualShortcuts;
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 56460fb..2cbb6d5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -114,8 +114,11 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
@@ -133,6 +136,16 @@
  */
 @SmallTest
 public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
+
+    @Override
+    protected void tearDown() throws Exception {
+        deleteUriFile("file32x32.jpg");
+        deleteUriFile("file64x64.jpg");
+        deleteUriFile("file512x512.jpg");
+
+        super.tearDown();
+    }
+
     /**
      * Test for the first launch path, no settings file available.
      */
@@ -724,6 +737,17 @@
         final Icon bmp512x512 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                 getTestContext().getResources(), R.drawable.black_512x512));
 
+        // The corresponding files will be deleted in tearDown()
+        final Icon uri32x32 = Icon.createWithContentUri(
+                getFileUriFromResource("file32x32.jpg", R.drawable.black_32x32));
+        final Icon uri64x64_maskable = Icon.createWithAdaptiveBitmapContentUri(
+                getFileUriFromResource("file64x64.jpg", R.drawable.black_64x64));
+        final Icon uri512x512 = Icon.createWithContentUri(
+                getFileUriFromResource("file512x512.jpg", R.drawable.black_512x512));
+
+        doReturn(mUriPermissionOwner.getExternalToken())
+                .when(mMockUriGrantsManagerInternal).newUriPermissionOwner(anyString());
+
         // Set from package 1
         setCaller(CALLING_PACKAGE_1);
         assertTrue(mManager.setDynamicShortcuts(list(
@@ -732,6 +756,9 @@
                 makeShortcutWithIcon("bmp32x32", bmp32x32),
                 makeShortcutWithIcon("bmp64x64", bmp64x64_maskable),
                 makeShortcutWithIcon("bmp512x512", bmp512x512),
+                makeShortcutWithIcon("uri32x32", uri32x32),
+                makeShortcutWithIcon("uri64x64", uri64x64_maskable),
+                makeShortcutWithIcon("uri512x512", uri512x512),
                 makeShortcut("none")
         )));
 
@@ -742,6 +769,9 @@
                 "bmp32x32",
                 "bmp64x64",
                 "bmp512x512",
+                "uri32x32",
+                "uri64x64",
+                "uri512x512",
                 "none");
 
         // Call from another caller with the same ID, just to make sure storage is per-package.
@@ -749,11 +779,15 @@
         assertTrue(mManager.setDynamicShortcuts(list(
                 makeShortcutWithIcon("res32x32", res512x512),
                 makeShortcutWithIcon("res64x64", res512x512),
+                makeShortcutWithIcon("uri32x32", uri512x512),
+                makeShortcutWithIcon("uri64x64", uri512x512),
                 makeShortcutWithIcon("none", res512x512)
         )));
         assertShortcutIds(assertAllNotHaveIcon(mManager.getDynamicShortcuts()),
                 "res32x32",
                 "res64x64",
+                "uri32x32",
+                "uri64x64",
                 "none");
 
         // Different profile.  Note the names and the contents don't match.
@@ -795,6 +829,18 @@
                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_0))),
                 "bmp512x512");
 
+        assertShortcutIds(assertAllHaveIconUri(
+                list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri32x32", USER_0))),
+                "uri32x32");
+
+        assertShortcutIds(assertAllHaveIconUri(
+                list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri64x64", USER_0))),
+                "uri64x64");
+
+        assertShortcutIds(assertAllHaveIconUri(
+                list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri512x512", USER_0))),
+                "uri512x512");
+
         assertShortcutIds(assertAllHaveIconResId(
                 list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_P0))),
                 "res32x32");
@@ -860,15 +906,37 @@
         bmp = pfdToBitmap(
                 mLauncherApps.getShortcutIconFd(CALLING_PACKAGE_1, "bmp32x32", HANDLE_USER_P0));
         assertBitmapSize(128, 128, bmp);
+/*
+        bmp = pfdToBitmap(mLauncherApps.getUriShortcutIconFd(
+                getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri32x32", USER_0)));
+        assertBitmapSize(32, 32, bmp);
 
-        Drawable dr = mLauncherApps.getShortcutIconDrawable(
+        bmp = pfdToBitmap(mLauncherApps.getUriShortcutIconFd(
+                getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri64x64", USER_0)));
+        assertBitmapSize(64, 64, bmp);
+
+        bmp = pfdToBitmap(mLauncherApps.getUriShortcutIconFd(
+                getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri512x512", USER_0)));
+        assertBitmapSize(512, 512, bmp);
+*/
+
+        Drawable dr_bmp = mLauncherApps.getShortcutIconDrawable(
                 makeShortcutWithIcon("bmp64x64", bmp64x64_maskable), 0);
-        assertTrue(dr instanceof AdaptiveIconDrawable);
+        assertTrue(dr_bmp instanceof AdaptiveIconDrawable);
         float viewportPercentage = 1 / (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction());
         assertEquals((int) (bmp64x64_maskable.getBitmap().getWidth() * viewportPercentage),
-                dr.getIntrinsicWidth());
+                dr_bmp.getIntrinsicWidth());
         assertEquals((int) (bmp64x64_maskable.getBitmap().getHeight() * viewportPercentage),
-                dr.getIntrinsicHeight());
+                dr_bmp.getIntrinsicHeight());
+/*
+        Drawable dr_uri = mLauncherApps.getShortcutIconDrawable(
+                makeShortcutWithIcon("uri64x64", uri64x64_maskable), 0);
+        assertTrue(dr_uri instanceof AdaptiveIconDrawable);
+        assertEquals((int) (bmp64x64_maskable.getBitmap().getWidth() * viewportPercentage),
+                dr_uri.getIntrinsicWidth());
+        assertEquals((int) (bmp64x64_maskable.getBitmap().getHeight() * viewportPercentage),
+                dr_uri.getIntrinsicHeight());
+*/
     }
 
     public void testCleanupDanglingBitmaps() throws Exception {
@@ -1274,6 +1342,18 @@
                     makeShortcut("s1")
             )));
 
+            // Set uri icon
+            assertTrue(mManager.updateShortcuts(list(
+                    new ShortcutInfo.Builder(mClientContext, "s1")
+                            .setIcon(Icon.createWithContentUri("test_uri"))
+                            .build()
+            )));
+            mService.waitForBitmapSavesForTest();
+            assertWith(getCallerShortcuts())
+                    .forShortcutWithId("s1", si -> {
+                        assertTrue(si.hasIconUri());
+                        assertEquals("test_uri", si.getIconUri());
+                    });
             // Set resource icon
             assertTrue(mManager.updateShortcuts(list(
                     new ShortcutInfo.Builder(mClientContext, "s1")
@@ -1287,6 +1367,9 @@
                         assertEquals(R.drawable.black_32x32, si.getIconResourceId());
                     });
             mService.waitForBitmapSavesForTest();
+
+            mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
+
             // Set bitmap icon
             assertTrue(mManager.updateShortcuts(list(
                     new ShortcutInfo.Builder(mClientContext, "s1")
@@ -1300,9 +1383,7 @@
                         assertTrue(si.hasIconFile());
                     });
 
-            mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
-
-            // Do it again, with the reverse order (bitmap -> icon)
+            // Do it again, with the reverse order (bitmap -> resource -> uri)
             assertTrue(mManager.setDynamicShortcuts(list(
                     makeShortcut("s1")
             )));
@@ -1320,6 +1401,8 @@
                         assertTrue(si.hasIconFile());
                     });
 
+            mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
+
             // Set resource icon
             assertTrue(mManager.updateShortcuts(list(
                     new ShortcutInfo.Builder(mClientContext, "s1")
@@ -1332,6 +1415,18 @@
                         assertTrue(si.hasIconResource());
                         assertEquals(R.drawable.black_32x32, si.getIconResourceId());
                     });
+            // Set uri icon
+            assertTrue(mManager.updateShortcuts(list(
+                    new ShortcutInfo.Builder(mClientContext, "s1")
+                            .setIcon(Icon.createWithContentUri("test_uri"))
+                            .build()
+            )));
+            mService.waitForBitmapSavesForTest();
+            assertWith(getCallerShortcuts())
+                    .forShortcutWithId("s1", si -> {
+                        assertTrue(si.hasIconUri());
+                        assertEquals("test_uri", si.getIconUri());
+                    });
         });
     }
 
@@ -8499,4 +8594,26 @@
             }
         }
     }
+
+    private Uri getFileUriFromResource(String fileName, int resId) throws IOException {
+        File file = new File(getTestContext().getFilesDir(), fileName);
+        // Make sure we are not leaving phantom files behind.
+        assertFalse(file.exists());
+        try (InputStream source = getTestContext().getResources().openRawResource(resId);
+             OutputStream target = new FileOutputStream(file)) {
+            byte[] buffer = new byte[1024];
+            for (int len = source.read(buffer); len >= 0; len = source.read(buffer)) {
+                target.write(buffer, 0, len);
+            }
+        }
+        assertTrue(file.exists());
+        return Uri.fromFile(file);
+    }
+
+    private void deleteUriFile(String fileName) {
+        File file = new File(getTestContext().getFilesDir(), fileName);
+        if (file.exists()) {
+            file.delete();
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 7b101c7..ca77049 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -257,6 +257,7 @@
         si.addFlags(ShortcutInfo.FLAG_PINNED);
         si.setBitmapPath("abc");
         si.setIconResourceId(456);
+        si.setIconUri("test_uri");
 
         si = parceled(si);
 
@@ -279,6 +280,7 @@
         assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
         assertEquals("abc", si.getBitmapPath());
         assertEquals(456, si.getIconResourceId());
+        assertEquals("test_uri", si.getIconUri());
 
         assertEquals(0, si.getTitleResId());
         assertEquals(null, si.getTitleResName());
@@ -310,6 +312,7 @@
         si.addFlags(ShortcutInfo.FLAG_PINNED);
         si.setBitmapPath("abc");
         si.setIconResourceId(456);
+        si.setIconUri("test_uri");
 
         lookupAndFillInResourceNames(si);
 
@@ -335,6 +338,7 @@
         assertEquals("abc", si.getBitmapPath());
         assertEquals(456, si.getIconResourceId());
         assertEquals("string/r456", si.getIconResName());
+        assertEquals("test_uri", si.getIconUri());
     }
 
     public void testShortcutInfoClone() {
@@ -359,6 +363,7 @@
         sorig.addFlags(ShortcutInfo.FLAG_PINNED);
         sorig.setBitmapPath("abc");
         sorig.setIconResourceId(456);
+        sorig.setIconUri("test_uri");
 
         lookupAndFillInResourceNames(sorig);
 
@@ -386,6 +391,7 @@
         assertEquals("abc", si.getBitmapPath());
         assertEquals(456, si.getIconResourceId());
         assertEquals("string/r456", si.getIconResName());
+        assertEquals("test_uri", si.getIconUri());
 
         si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
 
@@ -407,6 +413,7 @@
 
         assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
         assertEquals(null, si.getBitmapPath());
+        assertNull(si.getIconUri());
 
         assertEquals(456, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
@@ -428,6 +435,7 @@
 
         assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
         assertEquals(null, si.getBitmapPath());
+        assertNull(si.getIconUri());
 
         assertEquals(456, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
@@ -450,6 +458,7 @@
         assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY
                 | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
         assertEquals(null, si.getBitmapPath());
+        assertNull(si.getIconUri());
 
         assertEquals(456, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
@@ -474,6 +483,7 @@
 
         assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
         assertEquals(null, si.getBitmapPath());
+        assertNull(si.getIconUri());
 
         assertEquals(456, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
@@ -499,6 +509,7 @@
         sorig.addFlags(ShortcutInfo.FLAG_PINNED);
         sorig.setBitmapPath("abc");
         sorig.setIconResourceId(456);
+        sorig.setIconUri("test_uri");
 
         lookupAndFillInResourceNames(sorig);
 
@@ -526,6 +537,7 @@
         assertEquals("abc", si.getBitmapPath());
         assertEquals(456, si.getIconResourceId());
         assertEquals("string/r456", si.getIconResName());
+        assertEquals("test_uri", si.getIconUri());
 
         si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
 
@@ -547,6 +559,7 @@
 
         assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
         assertEquals(null, si.getBitmapPath());
+        assertNull(si.getIconUri());
 
         assertEquals(456, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
@@ -570,6 +583,7 @@
 
         assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
         assertEquals(null, si.getBitmapPath());
+        assertNull(si.getIconUri());
 
         assertEquals(456, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
@@ -593,6 +607,7 @@
 
         assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
         assertEquals(null, si.getBitmapPath());
+        assertNull(si.getIconUri());
 
         assertEquals(456, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
@@ -657,6 +672,7 @@
         sorig.addFlags(ShortcutInfo.FLAG_PINNED);
         sorig.setBitmapPath("abc");
         sorig.setIconResourceId(456);
+        sorig.setIconUri("test_uri");
 
         lookupAndFillInResourceNames(sorig);
 
@@ -677,6 +693,7 @@
         assertEquals(0, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
         assertEquals(null, si.getBitmapPath());
+        assertNull(si.getIconUri());
 
         si = sorig.clone(/* flags=*/ 0);
         si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
@@ -787,6 +804,7 @@
         sorig.addFlags(ShortcutInfo.FLAG_PINNED);
         sorig.setBitmapPath("abc");
         sorig.setIconResourceId(456);
+        sorig.setIconUri("test_uri");
 
         ShortcutInfo si;
 
@@ -804,6 +822,7 @@
         assertEquals(0, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
         assertEquals(null, si.getBitmapPath());
+        assertNull(si.getIconUri());
 
         si = sorig.clone(/* flags=*/ 0);
         si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
@@ -977,6 +996,7 @@
                 | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
         assertNotNull(si.getBitmapPath()); // Something should be set.
         assertEquals(0, si.getIconResourceId());
+        assertNull(si.getIconUri());
         assertTrue(si.getLastChangedTimestamp() < now);
 
         // Make sure ranks are saved too.  Because of the auto-adjusting, we need two shortcuts
@@ -1053,6 +1073,7 @@
             si.getFlags());
         assertNotNull(si.getBitmapPath()); // Something should be set.
         assertEquals(0, si.getIconResourceId());
+        assertNull(si.getIconUri());
         assertTrue(si.getLastChangedTimestamp() < now);
 
         dumpUserFile(USER_10);
@@ -1125,6 +1146,7 @@
         assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_RES
                 | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
         assertNull(si.getBitmapPath());
+        assertNull(si.getIconUri());
         assertEquals(R.drawable.black_32x32, si.getIconResourceId());
         assertTrue(si.getLastChangedTimestamp() < now);
 
@@ -1134,6 +1156,94 @@
         assertEquals(1, si.getRank());
     }
 
+    public void testShortcutInfoSaveAndLoad_uri() throws InterruptedException {
+        mRunningUsers.put(USER_10, true);
+
+        setCaller(CALLING_PACKAGE_1, USER_10);
+
+        final Icon uriIcon = Icon.createWithContentUri("test_uri");
+
+        PersistableBundle pb = new PersistableBundle();
+        pb.putInt("k", 1);
+        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+                .setId("id")
+                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+                .setIcon(uriIcon)
+                .setTitleResId(10)
+                .setTextResId(11)
+                .setDisabledMessageResId(12)
+                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+                .setRank(123)
+                .setExtras(pb)
+                .build();
+        sorig.setTimestamp(mInjectedCurrentTimeMillis);
+
+        final Icon uriMaskableIcon = Icon.createWithAdaptiveBitmapContentUri("uri_maskable");
+
+        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
+                .setId("id2")
+                .setTitle("x")
+                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+                .setRank(456)
+                .setIcon(uriMaskableIcon)
+                .build();
+        sorig2.setTimestamp(mInjectedCurrentTimeMillis);
+
+        mManager.addDynamicShortcuts(list(sorig, sorig2));
+
+        mInjectedCurrentTimeMillis += 1;
+        final long now = mInjectedCurrentTimeMillis;
+        mInjectedCurrentTimeMillis += 1;
+
+        // Save and load.
+        mService.saveDirtyInfo();
+        initService();
+        mService.handleUnlockUser(USER_10);
+
+        ShortcutInfo si;
+        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
+
+        assertEquals(USER_10, si.getUserId());
+        assertEquals(HANDLE_USER_10, si.getUserHandle());
+        assertEquals(CALLING_PACKAGE_1, si.getPackage());
+        assertEquals("id", si.getId());
+        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+        assertEquals(null, si.getIcon());
+        assertEquals(10, si.getTitleResId());
+        assertEquals("r10", si.getTitleResName());
+        assertEquals(11, si.getTextResId());
+        assertEquals("r11", si.getTextResName());
+        assertEquals(12, si.getDisabledMessageResourceId());
+        assertEquals("r12", si.getDisabledMessageResName());
+        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+        assertEquals("action", si.getIntent().getAction());
+        assertEquals("val", si.getIntent().getStringExtra("key"));
+        assertEquals(0, si.getRank());
+        assertEquals(1, si.getExtras().getInt("k"));
+
+        assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_URI
+                | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
+        assertNull(si.getBitmapPath());
+        assertNull(si.getIconResName());
+        assertEquals(0, si.getIconResourceId());
+        assertEquals("test_uri", si.getIconUri());
+        assertTrue(si.getLastChangedTimestamp() < now);
+
+        // Make sure ranks are saved too.  Because of the auto-adjusting, we need two shortcuts
+        // to test it.
+        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
+        assertEquals(1, si.getRank());
+        assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_URI
+                | ShortcutInfo.FLAG_STRINGS_RESOLVED | ShortcutInfo.FLAG_ADAPTIVE_BITMAP,
+                si.getFlags());
+        assertNull(si.getBitmapPath());
+        assertNull(si.getIconResName());
+        assertEquals(0, si.getIconResourceId());
+        assertEquals("uri_maskable", si.getIconUri());
+    }
+
     public void testShortcutInfoSaveAndLoad_forBackup() {
         setCaller(CALLING_PACKAGE_1, USER_0);
 
@@ -1196,6 +1306,7 @@
                 | ShortcutInfo.FLAG_SHADOW , si.getFlags());
         assertNull(si.getBitmapPath()); // No icon.
         assertEquals(0, si.getIconResourceId());
+        assertNull(si.getIconUri());
 
         // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
         si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
@@ -1265,6 +1376,77 @@
         assertNull(si.getBitmapPath()); // No icon.
         assertEquals(0, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
+        assertNull(si.getIconUri());
+
+        // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
+        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
+        assertEquals(0, si.getRank());
+    }
+
+    public void testShortcutInfoSaveAndLoad_forBackup_uri() {
+        setCaller(CALLING_PACKAGE_1, USER_0);
+
+        final Icon uriIcon = Icon.createWithContentUri("test_uri");
+
+        PersistableBundle pb = new PersistableBundle();
+        pb.putInt("k", 1);
+        ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+                .setId("id")
+                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+                .setIcon(uriIcon)
+                .setTitleResId(10)
+                .setTextResId(11)
+                .setDisabledMessageResId(12)
+                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+                .setRank(123)
+                .setExtras(pb)
+                .build();
+
+        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
+                .setId("id2")
+                .setTitle("x")
+                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+                .setRank(456)
+                .build();
+
+        mManager.addDynamicShortcuts(list(sorig, sorig2));
+
+        // Dynamic shortcuts won't be backed up, so we need to pin it.
+        setCaller(LAUNCHER_1, USER_0);
+        mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0);
+
+        // Do backup & restore.
+        backupAndRestore();
+
+        mService.handleUnlockUser(USER_0); // Load user-0.
+
+        ShortcutInfo si;
+        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
+
+        assertEquals(CALLING_PACKAGE_1, si.getPackage());
+        assertEquals("id", si.getId());
+        assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+        assertEquals(null, si.getIcon());
+        assertEquals(10, si.getTitleResId());
+        assertEquals("r10", si.getTitleResName());
+        assertEquals(11, si.getTextResId());
+        assertEquals("r11", si.getTextResName());
+        assertEquals(12, si.getDisabledMessageResourceId());
+        assertEquals("r12", si.getDisabledMessageResName());
+        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+        assertEquals("action", si.getIntent().getAction());
+        assertEquals("val", si.getIntent().getStringExtra("key"));
+        assertEquals(0, si.getRank());
+        assertEquals(1, si.getExtras().getInt("k"));
+
+        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED
+                | ShortcutInfo.FLAG_SHADOW , si.getFlags());
+        assertNull(si.getBitmapPath()); // No icon.
+        assertEquals(0, si.getIconResourceId());
+        assertEquals(null, si.getIconResName());
+        assertNull(si.getIconUri());
 
         // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
         si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 8e78047..010f8ac 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -390,7 +390,7 @@
                 "title", 0, "titleResName", "text", 0, "textResName",
                 "disabledMessage", 0, "disabledMessageResName",
                 null, null, 0, null, 0, 0,
-                0, "iconResName", "bitmapPath", 0,
+                0, "iconResName", "bitmapPath", null, 0,
                 null, null);
         return si;
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
index 5a527a2..551e186 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
@@ -3,10 +3,8 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 
-import android.app.Application;
 import android.content.Intent;
 import android.net.Uri;
 import android.service.notification.Condition;
@@ -47,7 +45,7 @@
                 null,               // ActivityThread not actually used in Service
                 ScheduleConditionProvider.class.getName(),
                 null,               // token not needed when not talking with the activity manager
-                mock(Application.class),
+                null,
                 null                // mocked services don't talk with the activity manager
                 );
         service.onCreate();
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index cdba9a1..6cb8b86 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -20,6 +20,7 @@
         "mockito-target-extended-minus-junit4",
         "platform-test-annotations",
         "servicestests-utils",
+        "testng",
         "truth-prebuilt",
         "testables",
         "ub-uiautomator",
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
index af04f76..fc256b0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java
@@ -246,7 +246,7 @@
     }
 
     @Test
-    public void testWorkChallenge() {
+    public void testLockedManagedProfile() {
         // GIVEN that the user the activity is starting as is currently locked
         when(mAmInternal.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index e2c27ea..7928e76 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -20,6 +20,9 @@
 import static android.view.Gravity.LEFT;
 import static android.view.Gravity.RIGHT;
 import static android.view.Gravity.TOP;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsState.ITYPE_TOP_GESTURES;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
@@ -42,13 +45,17 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
 
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.spy;
+import static org.testng.Assert.expectThrows;
 
 import android.app.WindowConfiguration;
 import android.graphics.Insets;
@@ -154,6 +161,56 @@
     }
 
     @Test
+    public void addingWindow_withInsetsTypes() {
+        WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
+        win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES};
+        win.getFrameLw().set(0, 0, 500, 100);
+
+        addWindow(win);
+        InsetsStateController controller = mDisplayContent.getInsetsStateController();
+        controller.onPostLayout();
+
+        InsetsSourceProvider statusBarProvider = controller.getSourceProvider(ITYPE_STATUS_BAR);
+        assertEquals(new Rect(0, 0, 500, 100), statusBarProvider.getSource().getFrame());
+        assertEquals(Insets.of(0, 100, 0, 0),
+                statusBarProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
+                        false /* ignoreVisibility */));
+
+        InsetsSourceProvider topGesturesProvider = controller.getSourceProvider(ITYPE_TOP_GESTURES);
+        assertEquals(new Rect(0, 0, 500, 100), topGesturesProvider.getSource().getFrame());
+        assertEquals(Insets.of(0, 100, 0, 0),
+                topGesturesProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
+                        false /* ignoreVisibility */));
+
+        InsetsSourceProvider navigationBarProvider = controller.getSourceProvider(
+                ITYPE_NAVIGATION_BAR);
+        assertNotEquals(new Rect(0, 0, 500, 100), navigationBarProvider.getSource().getFrame());
+    }
+
+    @Test
+    public void addingWindow_ignoresInsetsTypes_InWindowTypeWithPredefinedInsets() {
+        mDisplayPolicy.removeWindowLw(mStatusBarWindow);  // Removes the existing one.
+        WindowState win = createWindow(null, TYPE_STATUS_BAR, "StatusBar");
+        win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
+        win.getFrameLw().set(0, 0, 500, 100);
+
+        addWindow(win);
+        mDisplayContent.getInsetsStateController().onPostLayout();
+
+        InsetsSourceProvider provider =
+                mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR);
+        assertNotEquals(new Rect(0, 0, 500, 100), provider.getSource().getFrame());
+    }
+
+    @Test
+    public void addingWindow_throwsException_WithMultipleInsetTypes() {
+        WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
+        win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
+
+        expectThrows(IllegalArgumentException.class, () -> addWindow(win));
+    }
+
+    @Test
     public void layoutWindowLw_fitStatusBars() {
         assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
index bc81d5e..71c837e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
@@ -278,7 +278,7 @@
     }
 
     @Test
-    public void testContainerChanges() {
+    public void testContainerFocusableChanges() {
         removeGlobalMinSizeRestriction();
         final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
                 .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
@@ -288,6 +288,24 @@
         t.setFocusable(stack.mRemoteToken, false);
         mWm.mAtmService.mTaskOrganizerController.applyContainerTransaction(t, null);
         assertFalse(task.isFocusable());
+        t.setFocusable(stack.mRemoteToken, true);
+        mWm.mAtmService.mTaskOrganizerController.applyContainerTransaction(t, null);
+        assertTrue(task.isFocusable());
+    }
+
+    @Test
+    public void testContainerHiddenChanges() {
+        removeGlobalMinSizeRestriction();
+        final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mRoot)
+                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
+        WindowContainerTransaction t = new WindowContainerTransaction();
+        assertTrue(stack.shouldBeVisible(null));
+        t.setHidden(stack.mRemoteToken, true);
+        mWm.mAtmService.mTaskOrganizerController.applyContainerTransaction(t, null);
+        assertFalse(stack.shouldBeVisible(null));
+        t.setHidden(stack.mRemoteToken, false);
+        mWm.mAtmService.mTaskOrganizerController.applyContainerTransaction(t, null);
+        assertTrue(stack.shouldBeVisible(null));
     }
 
     @Test
@@ -532,6 +550,9 @@
         final Task task = createTaskInStack(stackController1, 0 /* userId */);
         final ITaskOrganizer organizer = registerMockOrganizer();
 
+        spyOn(task);
+        doReturn(true).when(task).isVisible();
+
         BLASTSyncEngine bse = new BLASTSyncEngine();
 
         BLASTSyncEngine.TransactionReadyListener transactionListener =
@@ -546,6 +567,35 @@
     }
 
     @Test
+    public void testOverlappingBLASTCallback() throws RemoteException {
+        final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
+        final Task task = createTaskInStack(stackController1, 0 /* userId */);
+        final ITaskOrganizer organizer = registerMockOrganizer();
+
+        spyOn(task);
+        doReturn(true).when(task).isVisible();
+        final WindowState w = createAppWindow(task, TYPE_APPLICATION, "Enlightened Window");
+        makeWindowVisible(w);
+
+        BLASTSyncEngine bse = new BLASTSyncEngine();
+
+        BLASTSyncEngine.TransactionReadyListener transactionListener =
+            mock(BLASTSyncEngine.TransactionReadyListener.class);
+
+        int id = bse.startSyncSet(transactionListener);
+        assertEquals(true, bse.addToSyncSet(id, task));
+        bse.setReady(id);
+
+        int id2 = bse.startSyncSet(transactionListener);
+        // We should be rejected from the second sync since we are already
+        // in one.
+        assertEquals(false, bse.addToSyncSet(id2, task));
+        w.finishDrawing(null);
+        assertEquals(true, bse.addToSyncSet(id2, task));
+        bse.setReady(id2);
+    }
+
+    @Test
     public void testBLASTCallbackWithWindow() {
         final ActivityStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
         final Task task = createTaskInStack(stackController1, 0 /* userId */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
index ce6efdf..926bd8c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerSettingsTests.java
@@ -24,6 +24,9 @@
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 
 import android.content.ContentResolver;
 import android.net.Uri;
@@ -60,11 +63,35 @@
     public void testFreeformWindow() {
         try (SettingsSession freeformWindowSession = new
                 SettingsSession(DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT)) {
-            final boolean freeformWindow = !freeformWindowSession.getSetting();
-            final Uri freeformWindowUri = freeformWindowSession.setSetting(freeformWindow);
+            final boolean curFreeformWindow = freeformWindowSession.getSetting();
+            final boolean newFreeformWindow = !curFreeformWindow;
+            final Uri freeformWindowUri = freeformWindowSession.setSetting(newFreeformWindow);
+            mWm.mAtmService.mSupportsFreeformWindowManagement = curFreeformWindow;
             mWm.mSettingsObserver.onChange(false, freeformWindowUri);
 
-            assertEquals(mWm.mAtmService.mSupportsFreeformWindowManagement, freeformWindow);
+            assertEquals(mWm.mAtmService.mSupportsFreeformWindowManagement, newFreeformWindow);
+        }
+    }
+
+    @Test
+    public void testFreeformWindow_valueChanged_updatesDisplaySettings() {
+        try (SettingsSession freeformWindowSession = new
+                SettingsSession(DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT)) {
+            final boolean curFreeformWindow = freeformWindowSession.getSetting();
+            final boolean newFreeformWindow = !curFreeformWindow;
+            final Uri freeformWindowUri = freeformWindowSession.setSetting(newFreeformWindow);
+            mWm.mAtmService.mSupportsFreeformWindowManagement = curFreeformWindow;
+            clearInvocations(mWm.mRoot);
+            mWm.mSettingsObserver.onChange(false, freeformWindowUri);
+
+            // Changed value should update display settings.
+            verify(mWm.mRoot).onSettingsRetrieved();
+
+            clearInvocations(mWm.mRoot);
+            mWm.mSettingsObserver.onChange(false, freeformWindowUri);
+
+            // Unchanged value should not update display settings.
+            verify(mWm.mRoot, never()).onSettingsRetrieved();
         }
     }
 
@@ -73,7 +100,8 @@
         try (SettingsSession forceResizableSession = new
                 SettingsSession(DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES)) {
             final boolean forceResizableMode = !forceResizableSession.getSetting();
-            final Uri forceResizableUri =  forceResizableSession.setSetting(forceResizableMode);
+            final Uri forceResizableUri = forceResizableSession.setSetting(forceResizableMode);
+
             mWm.mSettingsObserver.onChange(false, forceResizableUri);
 
             assertEquals(mWm.mAtmService.mForceResizableActivities, forceResizableMode);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 8e85bb2..747c8d9 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -445,7 +445,6 @@
     abstract static class UsbHandler extends Handler {
 
         // current USB state
-        private boolean mConnected;
         private boolean mHostConnected;
         private boolean mSourcePower;
         private boolean mSinkPower;
@@ -473,6 +472,7 @@
         private final UsbPermissionManager mPermissionManager;
         private NotificationManager mNotificationManager;
 
+        protected boolean mConnected;
         protected long mScreenUnlockedFunctions;
         protected boolean mBootCompleted;
         protected boolean mCurrentFunctionsApplied;
@@ -1794,7 +1794,8 @@
                 case MSG_SET_FUNCTIONS_TIMEOUT:
                     Slog.e(TAG, "Set functions timed out! no reply from usb hal");
                     if (msg.arg1 != 1) {
-                        setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+                        // Set this since default function may be selected from Developer options
+                        setEnabledFunctions(mScreenUnlockedFunctions, false);
                     }
                     break;
                 case MSG_GET_CURRENT_USB_FUNCTIONS:
@@ -1816,7 +1817,8 @@
                      * Dont force to default when the configuration is already set to default.
                      */
                     if (msg.arg1 != 1) {
-                        setEnabledFunctions(UsbManager.FUNCTION_NONE, !isAdbEnabled());
+                        // Set this since default function may be selected from Developer options
+                        setEnabledFunctions(mScreenUnlockedFunctions, false);
                     }
                     break;
                 case MSG_GADGET_HAL_REGISTERED:
@@ -1936,8 +1938,11 @@
                             SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS);
                     sendMessageDelayed(MSG_SET_FUNCTIONS_TIMEOUT, chargingFunctions,
                             SET_FUNCTIONS_TIMEOUT_MS);
-                    sendMessageDelayed(MSG_FUNCTION_SWITCH_TIMEOUT, chargingFunctions,
-                            SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS);
+                    if (mConnected) {
+                        // Only queue timeout of enumeration when the USB is connected
+                        sendMessageDelayed(MSG_FUNCTION_SWITCH_TIMEOUT, chargingFunctions,
+                                SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS);
+                    }
                     if (DEBUG) Slog.d(TAG, "timeout message queued");
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Remoteexception while calling setCurrentUsbFunctions", e);
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 767010a..3196758 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -19,6 +19,7 @@
 import static android.Manifest.permission.BIND_SOUND_TRIGGER_DETECTION_SERVICE;
 import static android.content.Context.BIND_AUTO_CREATE;
 import static android.content.Context.BIND_FOREGROUND_SERVICE;
+import static android.content.Context.BIND_INCLUDE_CAPABILITIES;
 import static android.content.pm.PackageManager.GET_META_DATA;
 import static android.content.pm.PackageManager.GET_SERVICES;
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
@@ -1133,7 +1134,8 @@
                 }
 
                 mIsBound = mContext.bindServiceAsUser(i, this,
-                        BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE, mUser);
+                        BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_INCLUDE_CAPABILITIES,
+                        mUser);
 
                 if (mIsBound) {
                     mRemoteServiceWakeLock.acquire();
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
new file mode 100644
index 0000000..092cb7f
--- /dev/null
+++ b/telephony/api/system-current.txt
@@ -0,0 +1,2145 @@
+// Signature format: 2.0
+package android.telephony {
+
+  public final class AccessNetworkConstants {
+    field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
+  }
+
+  public static final class AccessNetworkConstants.NgranBands {
+    method public static int getFrequencyRangeGroup(int);
+    field public static final int FREQUENCY_RANGE_GROUP_1 = 1; // 0x1
+    field public static final int FREQUENCY_RANGE_GROUP_2 = 2; // 0x2
+    field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0
+  }
+
+  public final class BarringInfo implements android.os.Parcelable {
+    ctor public BarringInfo();
+    method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy();
+  }
+
+  public final class CallAttributes implements android.os.Parcelable {
+    ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
+    method public int describeContents();
+    method @NonNull public android.telephony.CallQuality getCallQuality();
+    method public int getNetworkType();
+    method @NonNull public android.telephony.PreciseCallState getPreciseCallState();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
+  }
+
+  public final class CallQuality implements android.os.Parcelable {
+    ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
+    ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean);
+    method public int describeContents();
+    method public int getAverageRelativeJitter();
+    method public int getAverageRoundTripTime();
+    method public int getCallDuration();
+    method public int getCodecType();
+    method public int getDownlinkCallQualityLevel();
+    method public int getMaxRelativeJitter();
+    method public int getNumRtpPacketsNotReceived();
+    method public int getNumRtpPacketsReceived();
+    method public int getNumRtpPacketsTransmitted();
+    method public int getNumRtpPacketsTransmittedLost();
+    method public int getUplinkCallQualityLevel();
+    method public boolean isIncomingSilenceDetected();
+    method public boolean isOutgoingSilenceDetected();
+    method public boolean isRtpInactivityDetected();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CALL_QUALITY_BAD = 4; // 0x4
+    field public static final int CALL_QUALITY_EXCELLENT = 0; // 0x0
+    field public static final int CALL_QUALITY_FAIR = 2; // 0x2
+    field public static final int CALL_QUALITY_GOOD = 1; // 0x1
+    field public static final int CALL_QUALITY_NOT_AVAILABLE = 5; // 0x5
+    field public static final int CALL_QUALITY_POOR = 3; // 0x3
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
+  }
+
+  public class CarrierConfigManager {
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName();
+    method @NonNull public static android.os.PersistableBundle getDefaultConfig();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void updateConfigForPhoneId(int, String);
+    field public static final String KEY_CARRIER_SETUP_APP_STRING = "carrier_setup_app_string";
+    field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
+  }
+
+  public static final class CarrierConfigManager.Wifi {
+    field public static final String KEY_HOTSPOT_MAX_CLIENT_COUNT = "wifi.hotspot_maximum_client_count";
+    field public static final String KEY_PREFIX = "wifi.";
+  }
+
+  public final class CarrierRestrictionRules implements android.os.Parcelable {
+    method @NonNull public java.util.List<java.lang.Boolean> areCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
+    method public int describeContents();
+    method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers();
+    method public int getDefaultCarrierRestriction();
+    method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getExcludedCarriers();
+    method public int getMultiSimPolicy();
+    method public boolean isAllCarriersAllowed();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1; // 0x1
+    field public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CarrierRestrictionRules> CREATOR;
+    field public static final int MULTISIM_POLICY_NONE = 0; // 0x0
+    field public static final int MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT = 1; // 0x1
+  }
+
+  public static final class CarrierRestrictionRules.Builder {
+    ctor public CarrierRestrictionRules.Builder();
+    method @NonNull public android.telephony.CarrierRestrictionRules build();
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed();
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setDefaultCarrierRestriction(int);
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setExcludedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int);
+  }
+
+  public class CbGeoUtils {
+  }
+
+  public static class CbGeoUtils.Circle implements android.telephony.CbGeoUtils.Geometry {
+    ctor public CbGeoUtils.Circle(@NonNull android.telephony.CbGeoUtils.LatLng, double);
+    method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
+    method @NonNull public android.telephony.CbGeoUtils.LatLng getCenter();
+    method public double getRadius();
+  }
+
+  public static interface CbGeoUtils.Geometry {
+    method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
+  }
+
+  public static class CbGeoUtils.LatLng {
+    ctor public CbGeoUtils.LatLng(double, double);
+    method public double distance(@NonNull android.telephony.CbGeoUtils.LatLng);
+    method @NonNull public android.telephony.CbGeoUtils.LatLng subtract(@NonNull android.telephony.CbGeoUtils.LatLng);
+    field public final double lat;
+    field public final double lng;
+  }
+
+  public static class CbGeoUtils.Polygon implements android.telephony.CbGeoUtils.Geometry {
+    ctor public CbGeoUtils.Polygon(@NonNull java.util.List<android.telephony.CbGeoUtils.LatLng>);
+    method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
+    method @NonNull public java.util.List<android.telephony.CbGeoUtils.LatLng> getVertices();
+  }
+
+  public abstract class CellBroadcastService extends android.app.Service {
+    ctor public CellBroadcastService();
+    method @NonNull @WorkerThread public abstract CharSequence getCellBroadcastAreaInfo(int);
+    method public android.os.IBinder onBind(@Nullable android.content.Intent);
+    method public abstract void onCdmaCellBroadcastSms(int, @NonNull byte[], int);
+    method public abstract void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>);
+    method public abstract void onGsmCellBroadcastSms(int, @NonNull byte[]);
+    field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
+  }
+
+  public abstract class CellIdentity implements android.os.Parcelable {
+    method @NonNull public abstract android.telephony.CellLocation asCellLocation();
+    method @NonNull public abstract android.telephony.CellIdentity sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityCdma extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityGsm extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityGsm sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityLte extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityLte sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityNr extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.CellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityNr sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityTdscdma extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityTdscdma sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityWcdma extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityWcdma sanitizeLocationInfo();
+  }
+
+  public final class DataFailCause {
+    field @Deprecated public static final int VSNCP_APN_UNATHORIZED = 2238; // 0x8be
+  }
+
+  public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
+  }
+
+  public final class DisconnectCause {
+    field public static final int ALREADY_DIALING = 72; // 0x48
+    field public static final int ANSWERED_ELSEWHERE = 52; // 0x34
+    field public static final int BUSY = 4; // 0x4
+    field public static final int CALLING_DISABLED = 74; // 0x4a
+    field public static final int CALL_BARRED = 20; // 0x14
+    field public static final int CALL_PULLED = 51; // 0x33
+    field public static final int CANT_CALL_WHILE_RINGING = 73; // 0x49
+    field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23
+    field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20
+    field public static final int CDMA_ALREADY_ACTIVATED = 49; // 0x31
+    field public static final int CDMA_DROP = 27; // 0x1b
+    field public static final int CDMA_INTERCEPT = 28; // 0x1c
+    field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a
+    field public static final int CDMA_NOT_EMERGENCY = 34; // 0x22
+    field public static final int CDMA_PREEMPTED = 33; // 0x21
+    field public static final int CDMA_REORDER = 29; // 0x1d
+    field public static final int CDMA_RETRY_ORDER = 31; // 0x1f
+    field public static final int CDMA_SO_REJECT = 30; // 0x1e
+    field public static final int CONGESTION = 5; // 0x5
+    field public static final int CS_RESTRICTED = 22; // 0x16
+    field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18
+    field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17
+    field public static final int DATA_DISABLED = 54; // 0x36
+    field public static final int DATA_LIMIT_REACHED = 55; // 0x37
+    field public static final int DIALED_CALL_FORWARDING_WHILE_ROAMING = 57; // 0x39
+    field public static final int DIALED_MMI = 39; // 0x27
+    field public static final int DIAL_LOW_BATTERY = 62; // 0x3e
+    field public static final int DIAL_MODIFIED_TO_DIAL = 48; // 0x30
+    field public static final int DIAL_MODIFIED_TO_DIAL_VIDEO = 66; // 0x42
+    field public static final int DIAL_MODIFIED_TO_SS = 47; // 0x2f
+    field public static final int DIAL_MODIFIED_TO_USSD = 46; // 0x2e
+    field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL = 69; // 0x45
+    field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 70; // 0x46
+    field public static final int DIAL_VIDEO_MODIFIED_TO_SS = 67; // 0x43
+    field public static final int DIAL_VIDEO_MODIFIED_TO_USSD = 68; // 0x44
+    field public static final int EMERGENCY_PERM_FAILURE = 64; // 0x40
+    field public static final int EMERGENCY_TEMP_FAILURE = 63; // 0x3f
+    field public static final int ERROR_UNSPECIFIED = 36; // 0x24
+    field public static final int FDN_BLOCKED = 21; // 0x15
+    field public static final int ICC_ERROR = 19; // 0x13
+    field public static final int IMEI_NOT_ACCEPTED = 58; // 0x3a
+    field public static final int IMS_ACCESS_BLOCKED = 60; // 0x3c
+    field public static final int IMS_MERGED_SUCCESSFULLY = 45; // 0x2d
+    field public static final int IMS_SIP_ALTERNATE_EMERGENCY_CALL = 71; // 0x47
+    field public static final int INCOMING_AUTO_REJECTED = 81; // 0x51
+    field public static final int INCOMING_MISSED = 1; // 0x1
+    field public static final int INCOMING_REJECTED = 16; // 0x10
+    field public static final int INVALID_CREDENTIALS = 10; // 0xa
+    field public static final int INVALID_NUMBER = 7; // 0x7
+    field public static final int LIMIT_EXCEEDED = 15; // 0xf
+    field public static final int LOCAL = 3; // 0x3
+    field public static final int LOST_SIGNAL = 14; // 0xe
+    field public static final int LOW_BATTERY = 61; // 0x3d
+    field public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53; // 0x35
+    field public static final int MMI = 6; // 0x6
+    field public static final int NORMAL = 2; // 0x2
+    field public static final int NORMAL_UNSPECIFIED = 65; // 0x41
+    field public static final int NOT_DISCONNECTED = 0; // 0x0
+    field public static final int NOT_VALID = -1; // 0xffffffff
+    field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26
+    field public static final int NUMBER_UNREACHABLE = 8; // 0x8
+    field public static final int OTASP_PROVISIONING_IN_PROCESS = 76; // 0x4c
+    field public static final int OUTGOING_CANCELED = 44; // 0x2c
+    field public static final int OUTGOING_EMERGENCY_CALL_PLACED = 80; // 0x50
+    field public static final int OUTGOING_FAILURE = 43; // 0x2b
+    field public static final int OUT_OF_NETWORK = 11; // 0xb
+    field public static final int OUT_OF_SERVICE = 18; // 0x12
+    field public static final int POWER_OFF = 17; // 0x11
+    field public static final int SERVER_ERROR = 12; // 0xc
+    field public static final int SERVER_UNREACHABLE = 9; // 0x9
+    field public static final int TIMED_OUT = 13; // 0xd
+    field public static final int TOO_MANY_ONGOING_CALLS = 75; // 0x4b
+    field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
+    field public static final int VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED = 50; // 0x32
+    field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
+    field public static final int WIFI_LOST = 59; // 0x3b
+  }
+
+  public final class ImsiEncryptionInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public String getKeyIdentifier();
+    method @Nullable public java.security.PublicKey getPublicKey();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ImsiEncryptionInfo> CREATOR;
+  }
+
+  public final class LteVopsSupportInfo implements android.os.Parcelable {
+    ctor public LteVopsSupportInfo(int, int);
+    method public int describeContents();
+    method public int getEmcBearerSupport();
+    method public int getVopsSupport();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR;
+    field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
+    field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3
+    field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2
+  }
+
+  public class MbmsDownloadSession implements java.lang.AutoCloseable {
+    field public static final String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload";
+  }
+
+  public class MbmsGroupCallSession implements java.lang.AutoCloseable {
+    field public static final String MBMS_GROUP_CALL_SERVICE_ACTION = "android.telephony.action.EmbmsGroupCall";
+  }
+
+  public class MbmsStreamingSession implements java.lang.AutoCloseable {
+    field public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming";
+  }
+
+  public final class ModemActivityInfo implements android.os.Parcelable {
+    ctor public ModemActivityInfo(long, int, int, @NonNull int[], int);
+    method public int describeContents();
+    method public int getIdleTimeMillis();
+    method public int getReceiveTimeMillis();
+    method public int getSleepTimeMillis();
+    method public long getTimestamp();
+    method @NonNull public java.util.List<android.telephony.ModemActivityInfo.TransmitPower> getTransmitPowerInfo();
+    method public boolean isValid();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR;
+    field public static final int TX_POWER_LEVELS = 5; // 0x5
+    field public static final int TX_POWER_LEVEL_0 = 0; // 0x0
+    field public static final int TX_POWER_LEVEL_1 = 1; // 0x1
+    field public static final int TX_POWER_LEVEL_2 = 2; // 0x2
+    field public static final int TX_POWER_LEVEL_3 = 3; // 0x3
+    field public static final int TX_POWER_LEVEL_4 = 4; // 0x4
+  }
+
+  public class ModemActivityInfo.TransmitPower {
+    method @NonNull public android.util.Range<java.lang.Integer> getPowerRangeInDbm();
+    method public int getTimeInMillis();
+  }
+
+  public final class NetworkRegistrationInfo implements android.os.Parcelable {
+    method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
+    method public int getRegistrationState();
+    method public int getRejectCause();
+    method public int getRoamingType();
+    method public boolean isEmergencyEnabled();
+    method public void writeToParcel(android.os.Parcel, int);
+    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
+  }
+
+  public static final class NetworkRegistrationInfo.Builder {
+    ctor public NetworkRegistrationInfo.Builder();
+    method @NonNull public android.telephony.NetworkRegistrationInfo build();
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List<java.lang.Integer>);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
+  }
+
+  public abstract class NetworkService extends android.app.Service {
+    ctor public NetworkService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method @Nullable public abstract android.telephony.NetworkService.NetworkServiceProvider onCreateNetworkServiceProvider(int);
+    field public static final String SERVICE_INTERFACE = "android.telephony.NetworkService";
+  }
+
+  public abstract class NetworkService.NetworkServiceProvider implements java.lang.AutoCloseable {
+    ctor public NetworkService.NetworkServiceProvider(int);
+    method public abstract void close();
+    method public final int getSlotIndex();
+    method public final void notifyNetworkRegistrationInfoChanged();
+    method public void requestNetworkRegistrationInfo(int, @NonNull android.telephony.NetworkServiceCallback);
+  }
+
+  public class NetworkServiceCallback {
+    method public void onRequestNetworkRegistrationInfoComplete(int, @Nullable android.telephony.NetworkRegistrationInfo);
+    field public static final int RESULT_ERROR_BUSY = 3; // 0x3
+    field public static final int RESULT_ERROR_FAILED = 5; // 0x5
+    field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
+    field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2
+    field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+  }
+
+  public interface NumberVerificationCallback {
+    method public default void onCallReceived(@NonNull String);
+    method public default void onVerificationFailed(int);
+    field public static final int REASON_CONCURRENT_REQUESTS = 4; // 0x4
+    field public static final int REASON_IN_ECBM = 5; // 0x5
+    field public static final int REASON_IN_EMERGENCY_CALL = 6; // 0x6
+    field public static final int REASON_NETWORK_NOT_AVAILABLE = 2; // 0x2
+    field public static final int REASON_TIMED_OUT = 1; // 0x1
+    field public static final int REASON_TOO_MANY_CALLS = 3; // 0x3
+    field public static final int REASON_UNSPECIFIED = 0; // 0x0
+  }
+
+  public final class PhoneNumberRange implements android.os.Parcelable {
+    ctor public PhoneNumberRange(@NonNull String, @NonNull String, @NonNull String, @NonNull String);
+    method public int describeContents();
+    method public boolean matches(@NonNull String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR;
+  }
+
+  public class PhoneNumberUtils {
+    method @NonNull public static String getUsernameFromUriNumber(@NonNull String);
+    method public static boolean isUriNumber(@Nullable String);
+    method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
+  }
+
+  public final class PreciseCallState implements android.os.Parcelable {
+    ctor public PreciseCallState(int, int, int, int, int);
+    method public int describeContents();
+    method public int getBackgroundCallState();
+    method public int getForegroundCallState();
+    method public int getRingingCallState();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseCallState> CREATOR;
+    field public static final int PRECISE_CALL_STATE_ACTIVE = 1; // 0x1
+    field public static final int PRECISE_CALL_STATE_ALERTING = 4; // 0x4
+    field public static final int PRECISE_CALL_STATE_DIALING = 3; // 0x3
+    field public static final int PRECISE_CALL_STATE_DISCONNECTED = 7; // 0x7
+    field public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; // 0x8
+    field public static final int PRECISE_CALL_STATE_HOLDING = 2; // 0x2
+    field public static final int PRECISE_CALL_STATE_IDLE = 0; // 0x0
+    field public static final int PRECISE_CALL_STATE_INCOMING = 5; // 0x5
+    field public static final int PRECISE_CALL_STATE_NOT_VALID = -1; // 0xffffffff
+    field public static final int PRECISE_CALL_STATE_WAITING = 6; // 0x6
+  }
+
+  public final class PreciseDataConnectionState implements android.os.Parcelable {
+    method @Deprecated @NonNull public String getDataConnectionApn();
+    method @Deprecated public int getDataConnectionApnTypeBitMask();
+    method @Deprecated public int getDataConnectionFailCause();
+    method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties();
+    method @Deprecated public int getDataConnectionNetworkType();
+    method @Deprecated public int getDataConnectionState();
+  }
+
+  public final class PreciseDisconnectCause {
+    field public static final int ACCESS_CLASS_BLOCKED = 260; // 0x104
+    field public static final int ACCESS_INFORMATION_DISCARDED = 43; // 0x2b
+    field public static final int ACM_LIMIT_EXCEEDED = 68; // 0x44
+    field public static final int BEARER_CAPABILITY_NOT_AUTHORIZED = 57; // 0x39
+    field public static final int BEARER_NOT_AVAIL = 58; // 0x3a
+    field public static final int BEARER_SERVICE_NOT_IMPLEMENTED = 65; // 0x41
+    field public static final int BUSY = 17; // 0x11
+    field public static final int CALL_BARRED = 240; // 0xf0
+    field public static final int CALL_REJECTED = 21; // 0x15
+    field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
+    field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
+    field public static final int CDMA_DROP = 1001; // 0x3e9
+    field public static final int CDMA_INTERCEPT = 1002; // 0x3ea
+    field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
+    field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
+    field public static final int CDMA_PREEMPTED = 1007; // 0x3ef
+    field public static final int CDMA_REORDER = 1003; // 0x3eb
+    field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
+    field public static final int CDMA_SO_REJECT = 1004; // 0x3ec
+    field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c
+    field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6
+    field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64
+    field public static final int DESTINATION_OUT_OF_ORDER = 27; // 0x1b
+    field public static final int ERROR_UNSPECIFIED = 65535; // 0xffff
+    field public static final int FACILITY_REJECTED = 29; // 0x1d
+    field public static final int FDN_BLOCKED = 241; // 0xf1
+    field public static final int IMEI_NOT_ACCEPTED = 243; // 0xf3
+    field public static final int IMSI_UNKNOWN_IN_VLR = 242; // 0xf2
+    field public static final int INCOMING_CALLS_BARRED_WITHIN_CUG = 55; // 0x37
+    field public static final int INCOMPATIBLE_DESTINATION = 88; // 0x58
+    field public static final int INFORMATION_ELEMENT_NON_EXISTENT = 99; // 0x63
+    field public static final int INTERWORKING_UNSPECIFIED = 127; // 0x7f
+    field public static final int INVALID_MANDATORY_INFORMATION = 96; // 0x60
+    field public static final int INVALID_NUMBER_FORMAT = 28; // 0x1c
+    field public static final int INVALID_TRANSACTION_IDENTIFIER = 81; // 0x51
+    field public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101; // 0x65
+    field public static final int MESSAGE_TYPE_NON_IMPLEMENTED = 97; // 0x61
+    field public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98; // 0x62
+    field public static final int NETWORK_DETACH = 261; // 0x105
+    field public static final int NETWORK_OUT_OF_ORDER = 38; // 0x26
+    field public static final int NETWORK_REJECT = 252; // 0xfc
+    field public static final int NETWORK_RESP_TIMEOUT = 251; // 0xfb
+    field public static final int NORMAL = 16; // 0x10
+    field public static final int NORMAL_UNSPECIFIED = 31; // 0x1f
+    field public static final int NOT_VALID = -1; // 0xffffffff
+    field public static final int NO_ANSWER_FROM_USER = 19; // 0x13
+    field public static final int NO_CIRCUIT_AVAIL = 34; // 0x22
+    field public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0; // 0x0
+    field public static final int NO_ROUTE_TO_DESTINATION = 3; // 0x3
+    field public static final int NO_USER_RESPONDING = 18; // 0x12
+    field public static final int NO_VALID_SIM = 249; // 0xf9
+    field public static final int NUMBER_CHANGED = 22; // 0x16
+    field public static final int OEM_CAUSE_1 = 61441; // 0xf001
+    field public static final int OEM_CAUSE_10 = 61450; // 0xf00a
+    field public static final int OEM_CAUSE_11 = 61451; // 0xf00b
+    field public static final int OEM_CAUSE_12 = 61452; // 0xf00c
+    field public static final int OEM_CAUSE_13 = 61453; // 0xf00d
+    field public static final int OEM_CAUSE_14 = 61454; // 0xf00e
+    field public static final int OEM_CAUSE_15 = 61455; // 0xf00f
+    field public static final int OEM_CAUSE_2 = 61442; // 0xf002
+    field public static final int OEM_CAUSE_3 = 61443; // 0xf003
+    field public static final int OEM_CAUSE_4 = 61444; // 0xf004
+    field public static final int OEM_CAUSE_5 = 61445; // 0xf005
+    field public static final int OEM_CAUSE_6 = 61446; // 0xf006
+    field public static final int OEM_CAUSE_7 = 61447; // 0xf007
+    field public static final int OEM_CAUSE_8 = 61448; // 0xf008
+    field public static final int OEM_CAUSE_9 = 61449; // 0xf009
+    field public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70; // 0x46
+    field public static final int OPERATOR_DETERMINED_BARRING = 8; // 0x8
+    field public static final int OUT_OF_SRV = 248; // 0xf8
+    field public static final int PREEMPTION = 25; // 0x19
+    field public static final int PROTOCOL_ERROR_UNSPECIFIED = 111; // 0x6f
+    field public static final int QOS_NOT_AVAIL = 49; // 0x31
+    field public static final int RADIO_ACCESS_FAILURE = 253; // 0xfd
+    field public static final int RADIO_INTERNAL_ERROR = 250; // 0xfa
+    field public static final int RADIO_LINK_FAILURE = 254; // 0xfe
+    field public static final int RADIO_LINK_LOST = 255; // 0xff
+    field public static final int RADIO_OFF = 247; // 0xf7
+    field public static final int RADIO_RELEASE_ABNORMAL = 259; // 0x103
+    field public static final int RADIO_RELEASE_NORMAL = 258; // 0x102
+    field public static final int RADIO_SETUP_FAILURE = 257; // 0x101
+    field public static final int RADIO_UPLINK_FAILURE = 256; // 0x100
+    field public static final int RECOVERY_ON_TIMER_EXPIRED = 102; // 0x66
+    field public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED = 69; // 0x45
+    field public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED = 50; // 0x32
+    field public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47; // 0x2f
+    field public static final int SEMANTICALLY_INCORRECT_MESSAGE = 95; // 0x5f
+    field public static final int SERVICE_OPTION_NOT_AVAILABLE = 63; // 0x3f
+    field public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79; // 0x4f
+    field public static final int STATUS_ENQUIRY = 30; // 0x1e
+    field public static final int SWITCHING_CONGESTION = 42; // 0x2a
+    field public static final int TEMPORARY_FAILURE = 41; // 0x29
+    field public static final int UNOBTAINABLE_NUMBER = 1; // 0x1
+    field public static final int USER_NOT_MEMBER_OF_CUG = 87; // 0x57
+  }
+
+  public class ServiceState implements android.os.Parcelable {
+    method public void fillInNotifierBundle(@NonNull android.os.Bundle);
+    method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
+    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
+    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
+    method @NonNull public static android.telephony.ServiceState newFromBundle(@NonNull android.os.Bundle);
+    field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2
+    field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3
+    field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0
+    field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1
+  }
+
+  public class SignalStrength implements android.os.Parcelable {
+    ctor public SignalStrength(@NonNull android.telephony.SignalStrength);
+  }
+
+  public final class SmsCbCmasInfo implements android.os.Parcelable {
+    ctor public SmsCbCmasInfo(int, int, int, int, int, int);
+    method public int describeContents();
+    method public int getCategory();
+    method public int getCertainty();
+    method public int getMessageClass();
+    method public int getResponseType();
+    method public int getSeverity();
+    method public int getUrgency();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CMAS_CATEGORY_CBRNE = 10; // 0xa
+    field public static final int CMAS_CATEGORY_ENV = 7; // 0x7
+    field public static final int CMAS_CATEGORY_FIRE = 5; // 0x5
+    field public static final int CMAS_CATEGORY_GEO = 0; // 0x0
+    field public static final int CMAS_CATEGORY_HEALTH = 6; // 0x6
+    field public static final int CMAS_CATEGORY_INFRA = 9; // 0x9
+    field public static final int CMAS_CATEGORY_MET = 1; // 0x1
+    field public static final int CMAS_CATEGORY_OTHER = 11; // 0xb
+    field public static final int CMAS_CATEGORY_RESCUE = 4; // 0x4
+    field public static final int CMAS_CATEGORY_SAFETY = 2; // 0x2
+    field public static final int CMAS_CATEGORY_SECURITY = 3; // 0x3
+    field public static final int CMAS_CATEGORY_TRANSPORT = 8; // 0x8
+    field public static final int CMAS_CATEGORY_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_CERTAINTY_LIKELY = 1; // 0x1
+    field public static final int CMAS_CERTAINTY_OBSERVED = 0; // 0x0
+    field public static final int CMAS_CERTAINTY_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 3; // 0x3
+    field public static final int CMAS_CLASS_CMAS_EXERCISE = 5; // 0x5
+    field public static final int CMAS_CLASS_EXTREME_THREAT = 1; // 0x1
+    field public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 6; // 0x6
+    field public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0; // 0x0
+    field public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 4; // 0x4
+    field public static final int CMAS_CLASS_SEVERE_THREAT = 2; // 0x2
+    field public static final int CMAS_CLASS_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_RESPONSE_TYPE_ASSESS = 6; // 0x6
+    field public static final int CMAS_RESPONSE_TYPE_AVOID = 5; // 0x5
+    field public static final int CMAS_RESPONSE_TYPE_EVACUATE = 1; // 0x1
+    field public static final int CMAS_RESPONSE_TYPE_EXECUTE = 3; // 0x3
+    field public static final int CMAS_RESPONSE_TYPE_MONITOR = 4; // 0x4
+    field public static final int CMAS_RESPONSE_TYPE_NONE = 7; // 0x7
+    field public static final int CMAS_RESPONSE_TYPE_PREPARE = 2; // 0x2
+    field public static final int CMAS_RESPONSE_TYPE_SHELTER = 0; // 0x0
+    field public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_SEVERITY_EXTREME = 0; // 0x0
+    field public static final int CMAS_SEVERITY_SEVERE = 1; // 0x1
+    field public static final int CMAS_SEVERITY_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_URGENCY_EXPECTED = 1; // 0x1
+    field public static final int CMAS_URGENCY_IMMEDIATE = 0; // 0x0
+    field public static final int CMAS_URGENCY_UNKNOWN = -1; // 0xffffffff
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbCmasInfo> CREATOR;
+  }
+
+  public final class SmsCbEtwsInfo implements android.os.Parcelable {
+    ctor public SmsCbEtwsInfo(int, boolean, boolean, boolean, @Nullable byte[]);
+    method public int describeContents();
+    method @Nullable public byte[] getPrimaryNotificationSignature();
+    method public long getPrimaryNotificationTimestamp();
+    method public int getWarningType();
+    method public boolean isEmergencyUserAlert();
+    method public boolean isPopupAlert();
+    method public boolean isPrimary();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbEtwsInfo> CREATOR;
+    field public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0; // 0x0
+    field public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 2; // 0x2
+    field public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 4; // 0x4
+    field public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 3; // 0x3
+    field public static final int ETWS_WARNING_TYPE_TSUNAMI = 1; // 0x1
+    field public static final int ETWS_WARNING_TYPE_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public final class SmsCbLocation implements android.os.Parcelable {
+    ctor public SmsCbLocation(@NonNull String, int, int);
+    method public int describeContents();
+    method public int getCid();
+    method public int getLac();
+    method @NonNull public String getPlmn();
+    method public boolean isInLocationArea(@NonNull android.telephony.SmsCbLocation);
+    method public boolean isInLocationArea(@Nullable String, int, int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbLocation> CREATOR;
+  }
+
+  public final class SmsCbMessage implements android.os.Parcelable {
+    ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, int, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int, @Nullable java.util.List<android.telephony.CbGeoUtils.Geometry>, long, int, int);
+    method @NonNull public static android.telephony.SmsCbMessage createFromCursor(@NonNull android.database.Cursor);
+    method public int describeContents();
+    method @Nullable public android.telephony.SmsCbCmasInfo getCmasWarningInfo();
+    method @NonNull public android.content.ContentValues getContentValues();
+    method public int getDataCodingScheme();
+    method @Nullable public android.telephony.SmsCbEtwsInfo getEtwsWarningInfo();
+    method public int getGeographicalScope();
+    method @NonNull public java.util.List<android.telephony.CbGeoUtils.Geometry> getGeometries();
+    method @Nullable public String getLanguageCode();
+    method @NonNull public android.telephony.SmsCbLocation getLocation();
+    method public int getMaximumWaitingDuration();
+    method @Nullable public String getMessageBody();
+    method public int getMessageFormat();
+    method public int getMessagePriority();
+    method public long getReceivedTime();
+    method public int getSerialNumber();
+    method public int getServiceCategory();
+    method public int getSlotIndex();
+    method public int getSubscriptionId();
+    method public boolean isCmasMessage();
+    method public boolean isEmergencyMessage();
+    method public boolean isEtwsMessage();
+    method public boolean needGeoFencingCheck();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbMessage> CREATOR;
+    field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3; // 0x3
+    field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; // 0x0
+    field public static final int GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2; // 0x2
+    field public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; // 0x1
+    field public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; // 0xff
+    field public static final int MESSAGE_FORMAT_3GPP = 1; // 0x1
+    field public static final int MESSAGE_FORMAT_3GPP2 = 2; // 0x2
+    field public static final int MESSAGE_PRIORITY_EMERGENCY = 3; // 0x3
+    field public static final int MESSAGE_PRIORITY_INTERACTIVE = 1; // 0x1
+    field public static final int MESSAGE_PRIORITY_NORMAL = 0; // 0x0
+    field public static final int MESSAGE_PRIORITY_URGENT = 2; // 0x2
+  }
+
+  public final class SmsManager {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean copyMessageToIcc(@Nullable byte[], @NonNull byte[], int);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean deleteMessageFromIcc(int);
+    method public boolean disableCellBroadcastRange(int, int, int);
+    method public boolean enableCellBroadcastRange(int, int, int);
+    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 @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
+    field public static final int PREMIUM_SMS_CONSENT_ASK_USER = 1; // 0x1
+    field public static final int PREMIUM_SMS_CONSENT_NEVER_ALLOW = 2; // 0x2
+    field public static final int PREMIUM_SMS_CONSENT_UNKNOWN = 0; // 0x0
+  }
+
+  public class SmsMessage {
+    method @Nullable public static android.telephony.SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[], boolean);
+    method @Nullable public static android.telephony.SmsMessage.SubmitPdu getSmsPdu(int, int, @Nullable String, @NonNull String, @NonNull String, long);
+    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static byte[] getSubmitPduEncodedMessage(boolean, @NonNull String, @NonNull String, int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0, to=255) int, @IntRange(from=1, to=255) int, @IntRange(from=1, to=255) int);
+  }
+
+  public class SubscriptionInfo implements android.os.Parcelable {
+    method public boolean areUiccApplicationsEnabled();
+    method @Nullable public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+    method public int getProfileClass();
+    method public boolean isGroupDisabled();
+  }
+
+  public class SubscriptionManager {
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean canDisablePhysicalSubscription();
+    method public boolean canManageSubscription(@NonNull android.telephony.SubscriptionInfo, @NonNull String);
+    method @NonNull public int[] getActiveAndHiddenSubscriptionIdList();
+    method @NonNull public int[] getActiveSubscriptionIdList();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String);
+    method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEnabledSubscriptionId(int);
+    method @NonNull public static android.content.res.Resources getResourcesForSubId(@NonNull android.content.Context, int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSubscriptionEnabled(int);
+    method public void requestEmbeddedSubscriptionInfoListRefresh();
+    method public void requestEmbeddedSubscriptionInfoListRefresh(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setDisplayName(@Nullable String, int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setIconTint(int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(int, boolean);
+    field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
+    field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
+    field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff
+    field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2
+    field public static final int PROFILE_CLASS_PROVISIONING = 1; // 0x1
+    field public static final int PROFILE_CLASS_TESTING = 0; // 0x0
+    field public static final int PROFILE_CLASS_UNSET = -1; // 0xffffffff
+    field @NonNull public static final android.net.Uri VT_ENABLED_CONTENT_URI;
+    field @NonNull public static final android.net.Uri WFC_ENABLED_CONTENT_URI;
+    field @NonNull public static final android.net.Uri WFC_MODE_CONTENT_URI;
+    field @NonNull public static final android.net.Uri WFC_ROAMING_ENABLED_CONTENT_URI;
+    field @NonNull public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI;
+  }
+
+  public class TelephonyFrameworkInitializer {
+    method public static void registerServiceWrappers();
+    method public static void setTelephonyServiceManager(@NonNull android.os.TelephonyServiceManager);
+  }
+
+  public final class TelephonyHistogram implements android.os.Parcelable {
+    ctor public TelephonyHistogram(int, int, int);
+    ctor public TelephonyHistogram(android.telephony.TelephonyHistogram);
+    ctor public TelephonyHistogram(android.os.Parcel);
+    method public void addTimeTaken(int);
+    method public int describeContents();
+    method public int getAverageTime();
+    method public int getBucketCount();
+    method public int[] getBucketCounters();
+    method public int[] getBucketEndPoints();
+    method public int getCategory();
+    method public int getId();
+    method public int getMaxTime();
+    method public int getMinTime();
+    method public int getSampleCount();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.TelephonyHistogram> CREATOR;
+    field public static final int TELEPHONY_CATEGORY_RIL = 1; // 0x1
+  }
+
+  public class TelephonyManager {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
+    method public int checkCarrierPrivilegesForPackage(String);
+    method public int checkCarrierPrivilegesForPackageAnyPhone(String);
+    method public void dial(String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean disableDataConnectivity();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableDataConnectivity();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableModemForSlot(int, boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean);
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes();
+    method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
+    method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
+    method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCarrierPrivilegeStatus(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPrivilegedPackagesForAllActiveSubscriptions();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
+    method public String getCdmaPrlVersion();
+    method public int getCurrentPhoneType();
+    method public int getCurrentPhoneType(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState();
+    method @Deprecated public boolean getDataEnabled();
+    method @Deprecated public boolean getDataEnabled(int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getDefaultRespondViaMessageApplication();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
+    method public int getMaxNumberOfSimultaneouslyActiveSims();
+    method public static long getMaxNumberVerificationTimeoutMillis();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String[] getMergedImsisFromGroup();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask();
+    method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState();
+    method public int getSimApplicationState();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimApplicationState(int);
+    method public int getSimCardState();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimCardState(int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Locale getSimLocale();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getSupportedRadioAccessFamily();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.UiccSlotInfo[] getUiccSlotsInfo();
+    method @Nullable public android.os.Bundle getVisualVoicemailSettings();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int);
+    method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String);
+    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApnMetered(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionAllowed();
+    method public boolean isDataConnectivityPossible();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isTetheringApnRequired();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean matchesCurrentSimOperator(@NonNull String, int, @Nullable String);
+    method public boolean needsOtaServiceProvisioning();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyUserActivity();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
+    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
+    method public void requestModemActivityInfo(@NonNull android.os.ResultReceiver);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int);
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
+    method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAlwaysAllowMmsData(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRadioEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadioPower(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerState(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerStateForSlot(int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>);
+    method @Deprecated public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
+    method public void updateServiceLocation();
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED";
+    field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
+    field public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE";
+    field public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED";
+    field public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED";
+    field public static final String ACTION_CARRIER_SIGNAL_RESET = "com.android.internal.telephony.CARRIER_SIGNAL_RESET";
+    field public static final String ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED";
+    field public static final String ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED";
+    field public static final String ACTION_EMERGENCY_ASSISTANCE = "android.telephony.action.EMERGENCY_ASSISTANCE";
+    field public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED";
+    field public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED = "android.intent.action.EMERGENCY_CALL_STATE_CHANGED";
+    field public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE = "com.android.omadm.service.CONFIGURATION_UPDATE";
+    field public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS = "android.telephony.action.SHOW_NOTICE_ECM_BLOCK_OTHERS";
+    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
+    field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
+    field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION";
+    field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID";
+    field @Deprecated public static final String EXTRA_APN_PROTOCOL = "apnProto";
+    field public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt";
+    field @Deprecated public static final String EXTRA_APN_TYPE = "apnType";
+    field public static final String EXTRA_APN_TYPE_INT = "apnTypeInt";
+    field public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable";
+    field public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE = "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE";
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4; // 0x4
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA = 1; // 0x1
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE = 0; // 0x0
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_SMS = 3; // 0x3
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_VOICE = 2; // 0x2
+    field public static final String EXTRA_ERROR_CODE = "errorCode";
+    field public static final String EXTRA_PCO_ID = "pcoId";
+    field public static final String EXTRA_PCO_VALUE = "pcoValue";
+    field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE";
+    field public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = "android.telephony.extra.PHONE_IN_EMERGENCY_CALL";
+    field public static final String EXTRA_REDIRECTION_URL = "redirectionUrl";
+    field public static final String EXTRA_SIM_COMBINATION_NAMES = "android.telephony.extra.SIM_COMBINATION_NAMES";
+    field public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE = "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
+    field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1; // 0x1
+    field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0; // 0x0
+    field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
+    field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
+    field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+    field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff
+    field public static final int KEY_TYPE_EPDG = 1; // 0x1
+    field public static final int KEY_TYPE_WLAN = 2; // 0x2
+    field public static final String MODEM_ACTIVITY_RESULT_KEY = "controller_activity";
+    field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
+    field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
+    field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
+    field public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L
+    field public static final long NETWORK_TYPE_BITMASK_EVDO_0 = 16L; // 0x10L
+    field public static final long NETWORK_TYPE_BITMASK_EVDO_A = 32L; // 0x20L
+    field public static final long NETWORK_TYPE_BITMASK_EVDO_B = 2048L; // 0x800L
+    field public static final long NETWORK_TYPE_BITMASK_GPRS = 1L; // 0x1L
+    field public static final long NETWORK_TYPE_BITMASK_GSM = 32768L; // 0x8000L
+    field public static final long NETWORK_TYPE_BITMASK_HSDPA = 128L; // 0x80L
+    field public static final long NETWORK_TYPE_BITMASK_HSPA = 512L; // 0x200L
+    field public static final long NETWORK_TYPE_BITMASK_HSPAP = 16384L; // 0x4000L
+    field public static final long NETWORK_TYPE_BITMASK_HSUPA = 256L; // 0x100L
+    field public static final long NETWORK_TYPE_BITMASK_IWLAN = 131072L; // 0x20000L
+    field public static final long NETWORK_TYPE_BITMASK_LTE = 4096L; // 0x1000L
+    field public static final long NETWORK_TYPE_BITMASK_LTE_CA = 262144L; // 0x40000L
+    field public static final long NETWORK_TYPE_BITMASK_NR = 524288L; // 0x80000L
+    field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L
+    field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L
+    field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L
+    field public static final int RADIO_POWER_OFF = 0; // 0x0
+    field public static final int RADIO_POWER_ON = 1; // 0x1
+    field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2
+    field public static final int SET_CARRIER_RESTRICTION_ERROR = 2; // 0x2
+    field public static final int SET_CARRIER_RESTRICTION_NOT_SUPPORTED = 1; // 0x1
+    field public static final int SET_CARRIER_RESTRICTION_SUCCESS = 0; // 0x0
+    field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2
+    field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1
+    field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3
+    field public static final int SIM_ACTIVATION_STATE_RESTRICTED = 4; // 0x4
+    field public static final int SIM_ACTIVATION_STATE_UNKNOWN = 0; // 0x0
+    field public static final int SIM_STATE_LOADED = 10; // 0xa
+    field public static final int SIM_STATE_PRESENT = 11; // 0xb
+    field public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; // 0x3
+    field public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; // 0x1
+    field public static final int SRVCC_STATE_HANDOVER_FAILED = 2; // 0x2
+    field public static final int SRVCC_STATE_HANDOVER_NONE = -1; // 0xffffffff
+    field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0
+  }
+
+  public final class UiccAccessRule implements android.os.Parcelable {
+    ctor public UiccAccessRule(byte[], @Nullable String, long);
+    method public int describeContents();
+    method public int getCarrierPrivilegeStatus(android.content.pm.PackageInfo);
+    method public int getCarrierPrivilegeStatus(android.content.pm.Signature, String);
+    method public String getCertificateHexString();
+    method @Nullable public String getPackageName();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR;
+  }
+
+  public class UiccSlotInfo implements android.os.Parcelable {
+    ctor @Deprecated public UiccSlotInfo(boolean, boolean, String, int, int, boolean);
+    method public int describeContents();
+    method public String getCardId();
+    method public int getCardStateInfo();
+    method public boolean getIsActive();
+    method public boolean getIsEuicc();
+    method public boolean getIsExtendedApduSupported();
+    method public int getLogicalSlotIdx();
+    method public boolean isRemovable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CARD_STATE_INFO_ABSENT = 1; // 0x1
+    field public static final int CARD_STATE_INFO_ERROR = 3; // 0x3
+    field public static final int CARD_STATE_INFO_PRESENT = 2; // 0x2
+    field public static final int CARD_STATE_INFO_RESTRICTED = 4; // 0x4
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccSlotInfo> CREATOR;
+  }
+
+  public abstract class VisualVoicemailService extends android.app.Service {
+    method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, String, short, String, android.app.PendingIntent);
+    method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
+  }
+
+}
+
+package android.telephony.cdma {
+
+  public final class CdmaSmsCbProgramData implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getCategory();
+    method public int getOperation();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003
+    field public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001
+    field public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff
+    field public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000
+    field public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002
+    field public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR;
+    field public static final int OPERATION_ADD_CATEGORY = 1; // 0x1
+    field public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2
+    field public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0
+  }
+
+}
+
+package android.telephony.data {
+
+  public final class DataCallResponse implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
+    method public int getCause();
+    method @NonNull public java.util.List<java.net.InetAddress> getDnsAddresses();
+    method @NonNull public java.util.List<java.net.InetAddress> getGatewayAddresses();
+    method public int getId();
+    method @NonNull public String getInterfaceName();
+    method public int getLinkStatus();
+    method @Deprecated public int getMtu();
+    method public int getMtuV4();
+    method public int getMtuV6();
+    method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses();
+    method public int getProtocolType();
+    method public int getSuggestedRetryTime();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR;
+    field public static final int LINK_STATUS_ACTIVE = 2; // 0x2
+    field public static final int LINK_STATUS_DORMANT = 1; // 0x1
+    field public static final int LINK_STATUS_INACTIVE = 0; // 0x0
+    field public static final int LINK_STATUS_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class DataCallResponse.Builder {
+    ctor public DataCallResponse.Builder();
+    method @NonNull public android.telephony.data.DataCallResponse build();
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setAddresses(@NonNull java.util.List<android.net.LinkAddress>);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setCause(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setDnsAddresses(@NonNull java.util.List<java.net.InetAddress>);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setGatewayAddresses(@NonNull java.util.List<java.net.InetAddress>);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setId(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setInterfaceName(@NonNull String);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setLinkStatus(int);
+    method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV4(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int);
+  }
+
+  public final class DataProfile implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public String getApn();
+    method public int getAuthType();
+    method public int getBearerBitmask();
+    method @Deprecated public int getMtu();
+    method public int getMtuV4();
+    method public int getMtuV6();
+    method @Nullable public String getPassword();
+    method public int getProfileId();
+    method public int getProtocolType();
+    method public int getRoamingProtocolType();
+    method public int getSupportedApnTypesBitmask();
+    method public int getType();
+    method @Nullable public String getUserName();
+    method public boolean isEnabled();
+    method public boolean isPersistent();
+    method public boolean isPreferred();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataProfile> CREATOR;
+    field public static final int TYPE_3GPP = 1; // 0x1
+    field public static final int TYPE_3GPP2 = 2; // 0x2
+    field public static final int TYPE_COMMON = 0; // 0x0
+  }
+
+  public static final class DataProfile.Builder {
+    ctor public DataProfile.Builder();
+    method @NonNull public android.telephony.data.DataProfile build();
+    method @NonNull public android.telephony.data.DataProfile.Builder enable(boolean);
+    method @NonNull public android.telephony.data.DataProfile.Builder setApn(@NonNull String);
+    method @NonNull public android.telephony.data.DataProfile.Builder setAuthType(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setBearerBitmask(int);
+    method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setMtu(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setMtuV4(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setMtuV6(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setPassword(@NonNull String);
+    method @NonNull public android.telephony.data.DataProfile.Builder setPersistent(boolean);
+    method @NonNull public android.telephony.data.DataProfile.Builder setPreferred(boolean);
+    method @NonNull public android.telephony.data.DataProfile.Builder setProfileId(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setProtocolType(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setRoamingProtocolType(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setSupportedApnTypesBitmask(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setType(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setUserName(@NonNull String);
+  }
+
+  public abstract class DataService extends android.app.Service {
+    ctor public DataService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method @Nullable public abstract android.telephony.data.DataService.DataServiceProvider onCreateDataServiceProvider(int);
+    field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3
+    field public static final int REQUEST_REASON_NORMAL = 1; // 0x1
+    field public static final int REQUEST_REASON_SHUTDOWN = 2; // 0x2
+    field public static final int REQUEST_REASON_UNKNOWN = 0; // 0x0
+    field public static final String SERVICE_INTERFACE = "android.telephony.data.DataService";
+  }
+
+  public abstract class DataService.DataServiceProvider implements java.lang.AutoCloseable {
+    ctor public DataService.DataServiceProvider(int);
+    method public abstract void close();
+    method public void deactivateDataCall(int, int, @Nullable android.telephony.data.DataServiceCallback);
+    method public final int getSlotIndex();
+    method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
+    method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback);
+    method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback);
+    method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback);
+    method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback);
+  }
+
+  public class DataServiceCallback {
+    method public void onDataCallListChanged(@NonNull java.util.List<android.telephony.data.DataCallResponse>);
+    method public void onDeactivateDataCallComplete(int);
+    method public void onRequestDataCallListComplete(int, @NonNull java.util.List<android.telephony.data.DataCallResponse>);
+    method public void onSetDataProfileComplete(int);
+    method public void onSetInitialAttachApnComplete(int);
+    method public void onSetupDataCallComplete(int, @Nullable android.telephony.data.DataCallResponse);
+    field public static final int RESULT_ERROR_BUSY = 3; // 0x3
+    field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
+    field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2
+    field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+  }
+
+  public abstract class QualifiedNetworksService extends android.app.Service {
+    ctor public QualifiedNetworksService();
+    method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int);
+    field public static final String QUALIFIED_NETWORKS_SERVICE_INTERFACE = "android.telephony.data.QualifiedNetworksService";
+  }
+
+  public abstract class QualifiedNetworksService.NetworkAvailabilityProvider implements java.lang.AutoCloseable {
+    ctor public QualifiedNetworksService.NetworkAvailabilityProvider(int);
+    method public abstract void close();
+    method public final int getSlotIndex();
+    method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>);
+  }
+
+}
+
+package android.telephony.euicc {
+
+  public final class DownloadableSubscription implements android.os.Parcelable {
+    method public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+    method @Nullable public String getCarrierName();
+  }
+
+  public static final class DownloadableSubscription.Builder {
+    ctor public DownloadableSubscription.Builder();
+    ctor public DownloadableSubscription.Builder(android.telephony.euicc.DownloadableSubscription);
+    method public android.telephony.euicc.DownloadableSubscription build();
+    method public android.telephony.euicc.DownloadableSubscription.Builder setAccessRules(java.util.List<android.telephony.UiccAccessRule>);
+    method public android.telephony.euicc.DownloadableSubscription.Builder setCarrierName(String);
+    method public android.telephony.euicc.DownloadableSubscription.Builder setConfirmationCode(String);
+    method public android.telephony.euicc.DownloadableSubscription.Builder setEncodedActivationCode(String);
+  }
+
+  public class EuiccCardManager {
+    method public void authenticateServer(String, String, byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void cancelSession(String, byte[], @android.telephony.euicc.EuiccCardManager.CancelReason int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void deleteProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void disableProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void listNotifications(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
+    method public void loadBoundProfilePackage(String, byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void prepareDownload(String, @Nullable byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void removeNotificationFromList(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void requestAllProfiles(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo[]>);
+    method public void requestDefaultSmdpAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
+    method public void requestEuiccChallenge(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void requestEuiccInfo1(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void requestEuiccInfo2(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void requestProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
+    method public void requestRulesAuthTable(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccRulesAuthTable>);
+    method public void requestSmdsAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
+    method public void resetMemory(String, @android.telephony.euicc.EuiccCardManager.ResetOption int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void retrieveNotification(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification>);
+    method public void retrieveNotificationList(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
+    method public void setDefaultSmdpAddress(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void setNickname(String, String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void switchToProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
+    field public static final int CANCEL_REASON_END_USER_REJECTED = 0; // 0x0
+    field public static final int CANCEL_REASON_POSTPONED = 1; // 0x1
+    field public static final int CANCEL_REASON_PPR_NOT_ALLOWED = 3; // 0x3
+    field public static final int CANCEL_REASON_TIMEOUT = 2; // 0x2
+    field public static final int RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 2; // 0x2
+    field public static final int RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1; // 0x1
+    field public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 4; // 0x4
+    field public static final int RESULT_CALLER_NOT_ALLOWED = -3; // 0xfffffffd
+    field public static final int RESULT_EUICC_NOT_FOUND = -2; // 0xfffffffe
+    field public static final int RESULT_OK = 0; // 0x0
+    field public static final int RESULT_UNKNOWN_ERROR = -1; // 0xffffffff
+  }
+
+  @IntDef(prefix={"CANCEL_REASON_"}, value={android.telephony.euicc.EuiccCardManager.CANCEL_REASON_END_USER_REJECTED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_POSTPONED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_TIMEOUT, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_PPR_NOT_ALLOWED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.CancelReason {
+  }
+
+  @IntDef(flag=true, prefix={"RESET_OPTION_"}, value={android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.ResetOption {
+  }
+
+  public static interface EuiccCardManager.ResultCallback<T> {
+    method public void onComplete(int, T);
+  }
+
+  public class EuiccManager {
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void continueOperation(android.content.Intent, android.os.Bundle);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@NonNull android.app.PendingIntent);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@android.telephony.euicc.EuiccCardManager.ResetOption int, @NonNull android.app.PendingIntent);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDefaultDownloadableSubscriptionList(android.app.PendingIntent);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDownloadableSubscriptionMetadata(android.telephony.euicc.DownloadableSubscription, android.app.PendingIntent);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public int getOtaStatus();
+    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getSupportedCountries();
+    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getUnsupportedCountries();
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public boolean isSupportedCountry(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setSupportedCountries(@NonNull java.util.List<java.lang.String>);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setUnsupportedCountries(@NonNull java.util.List<java.lang.String>);
+    field public static final String ACTION_DELETE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED";
+    field @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public static final String ACTION_OTA_STATUS_CHANGED = "android.telephony.euicc.action.OTA_STATUS_CHANGED";
+    field public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+    field public static final String ACTION_RENAME_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED";
+    field public static final String ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED";
+    field public static final int EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED = 4; // 0x4
+    field public static final int EUICC_ACTIVATION_TYPE_BACKUP = 2; // 0x2
+    field public static final int EUICC_ACTIVATION_TYPE_DEFAULT = 1; // 0x1
+    field public static final int EUICC_ACTIVATION_TYPE_TRANSFER = 3; // 0x3
+    field public static final int EUICC_OTA_FAILED = 2; // 0x2
+    field public static final int EUICC_OTA_IN_PROGRESS = 1; // 0x1
+    field public static final int EUICC_OTA_NOT_NEEDED = 4; // 0x4
+    field public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; // 0x5
+    field public static final int EUICC_OTA_SUCCEEDED = 3; // 0x3
+    field public static final String EXTRA_ACTIVATION_TYPE = "android.telephony.euicc.extra.ACTIVATION_TYPE";
+    field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
+    field public static final String EXTRA_ENABLE_SUBSCRIPTION = "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION";
+    field public static final String EXTRA_FORCE_PROVISION = "android.telephony.euicc.extra.FORCE_PROVISION";
+    field public static final String EXTRA_FROM_SUBSCRIPTION_ID = "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID";
+    field public static final String EXTRA_PHYSICAL_SLOT_ID = "android.telephony.euicc.extra.PHYSICAL_SLOT_ID";
+    field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.euicc.extra.SUBSCRIPTION_ID";
+    field public static final String EXTRA_SUBSCRIPTION_NICKNAME = "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME";
+  }
+
+  @IntDef(prefix={"EUICC_OTA_"}, value={android.telephony.euicc.EuiccManager.EUICC_OTA_IN_PROGRESS, android.telephony.euicc.EuiccManager.EUICC_OTA_FAILED, android.telephony.euicc.EuiccManager.EUICC_OTA_SUCCEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_NOT_NEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccManager.OtaStatus {
+  }
+
+  public final class EuiccNotification implements android.os.Parcelable {
+    ctor public EuiccNotification(int, String, @android.telephony.euicc.EuiccNotification.Event int, @Nullable byte[]);
+    method public int describeContents();
+    method @Nullable public byte[] getData();
+    method @android.telephony.euicc.EuiccNotification.Event public int getEvent();
+    method public int getSeq();
+    method public String getTargetAddr();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @android.telephony.euicc.EuiccNotification.Event public static final int ALL_EVENTS = 15; // 0xf
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccNotification> CREATOR;
+    field public static final int EVENT_DELETE = 8; // 0x8
+    field public static final int EVENT_DISABLE = 4; // 0x4
+    field public static final int EVENT_ENABLE = 2; // 0x2
+    field public static final int EVENT_INSTALL = 1; // 0x1
+  }
+
+  @IntDef(flag=true, prefix={"EVENT_"}, value={android.telephony.euicc.EuiccNotification.EVENT_INSTALL, android.telephony.euicc.EuiccNotification.EVENT_ENABLE, android.telephony.euicc.EuiccNotification.EVENT_DISABLE, android.telephony.euicc.EuiccNotification.EVENT_DELETE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccNotification.Event {
+  }
+
+  public final class EuiccRulesAuthTable implements android.os.Parcelable {
+    method public int describeContents();
+    method public int findIndex(@android.service.euicc.EuiccProfileInfo.PolicyRule int, android.service.carrier.CarrierIdentifier);
+    method public boolean hasPolicyRuleFlag(int, @android.telephony.euicc.EuiccRulesAuthTable.PolicyRuleFlag int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccRulesAuthTable> CREATOR;
+    field public static final int POLICY_RULE_FLAG_CONSENT_REQUIRED = 1; // 0x1
+  }
+
+  public static final class EuiccRulesAuthTable.Builder {
+    ctor public EuiccRulesAuthTable.Builder(int);
+    method public android.telephony.euicc.EuiccRulesAuthTable.Builder add(int, java.util.List<android.service.carrier.CarrierIdentifier>, int);
+    method public android.telephony.euicc.EuiccRulesAuthTable build();
+  }
+
+  @IntDef(flag=true, prefix={"POLICY_RULE_FLAG_"}, value={android.telephony.euicc.EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccRulesAuthTable.PolicyRuleFlag {
+  }
+
+}
+
+package android.telephony.ims {
+
+  public final class ImsCallForwardInfo implements android.os.Parcelable {
+    ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int);
+    method public int describeContents();
+    method public int getCondition();
+    method public String getNumber();
+    method public int getServiceClass();
+    method public int getStatus();
+    method public int getTimeSeconds();
+    method public int getToA();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CDIV_CF_REASON_ALL = 4; // 0x4
+    field public static final int CDIV_CF_REASON_ALL_CONDITIONAL = 5; // 0x5
+    field public static final int CDIV_CF_REASON_BUSY = 1; // 0x1
+    field public static final int CDIV_CF_REASON_NOT_LOGGED_IN = 6; // 0x6
+    field public static final int CDIV_CF_REASON_NOT_REACHABLE = 3; // 0x3
+    field public static final int CDIV_CF_REASON_NO_REPLY = 2; // 0x2
+    field public static final int CDIV_CF_REASON_UNCONDITIONAL = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallForwardInfo> CREATOR;
+    field public static final int STATUS_ACTIVE = 1; // 0x1
+    field public static final int STATUS_NOT_ACTIVE = 0; // 0x0
+    field public static final int TYPE_OF_ADDRESS_INTERNATIONAL = 145; // 0x91
+    field public static final int TYPE_OF_ADDRESS_UNKNOWN = 129; // 0x81
+  }
+
+  public final class ImsCallProfile implements android.os.Parcelable {
+    ctor public ImsCallProfile();
+    ctor public ImsCallProfile(int, int);
+    ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
+    method public int describeContents();
+    method public String getCallExtra(String);
+    method public String getCallExtra(String, String);
+    method public boolean getCallExtraBoolean(String);
+    method public boolean getCallExtraBoolean(String, boolean);
+    method public int getCallExtraInt(String);
+    method public int getCallExtraInt(String, int);
+    method public android.os.Bundle getCallExtras();
+    method public int getCallType();
+    method public static int getCallTypeFromVideoState(int);
+    method public int getCallerNumberVerificationStatus();
+    method public int getEmergencyCallRouting();
+    method public int getEmergencyServiceCategories();
+    method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
+    method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @NonNull public android.os.Bundle getProprietaryCallExtras();
+    method public int getRestrictCause();
+    method public int getServiceType();
+    method public static int getVideoStateFromCallType(int);
+    method public static int getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile);
+    method public boolean hasKnownUserIntentEmergency();
+    method public boolean isEmergencyCallTesting();
+    method public boolean isVideoCall();
+    method public boolean isVideoPaused();
+    method public static int presentationToOir(int);
+    method public void setCallExtra(String, String);
+    method public void setCallExtraBoolean(String, boolean);
+    method public void setCallExtraInt(String, int);
+    method public void setCallRestrictCause(int);
+    method public void setCallerNumberVerificationStatus(int);
+    method public void setEmergencyCallRouting(int);
+    method public void setEmergencyCallTesting(boolean);
+    method public void setEmergencyServiceCategories(int);
+    method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
+    method public void setHasKnownUserIntentEmergency(boolean);
+    method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
+    method public void updateCallType(android.telephony.ims.ImsCallProfile);
+    method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; // 0x2
+    field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3
+    field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0
+    field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1
+    field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3
+    field public static final int CALL_TYPE_VOICE = 2; // 0x2
+    field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1
+    field public static final int CALL_TYPE_VS = 8; // 0x8
+    field public static final int CALL_TYPE_VS_RX = 10; // 0xa
+    field public static final int CALL_TYPE_VS_TX = 9; // 0x9
+    field public static final int CALL_TYPE_VT = 4; // 0x4
+    field public static final int CALL_TYPE_VT_NODIR = 7; // 0x7
+    field public static final int CALL_TYPE_VT_RX = 6; // 0x6
+    field public static final int CALL_TYPE_VT_TX = 5; // 0x5
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallProfile> CREATOR;
+    field public static final int DIALSTRING_NORMAL = 0; // 0x0
+    field public static final int DIALSTRING_SS_CONF = 1; // 0x1
+    field public static final int DIALSTRING_USSD = 2; // 0x2
+    field public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
+    field public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS";
+    field public static final String EXTRA_CALL_DISCONNECT_CAUSE = "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE";
+    field public static final String EXTRA_CALL_NETWORK_TYPE = "android.telephony.ims.extra.CALL_NETWORK_TYPE";
+    field @Deprecated public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
+    field public static final String EXTRA_CHILD_NUMBER = "ChildNum";
+    field public static final String EXTRA_CNA = "cna";
+    field public static final String EXTRA_CNAP = "cnap";
+    field public static final String EXTRA_CODEC = "Codec";
+    field public static final String EXTRA_DIALSTRING = "dialstring";
+    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_FORWARDED_NUMBER = "android.telephony.ims.extra.FORWARDED_NUMBER";
+    field public static final String EXTRA_IS_CALL_PULL = "CallPull";
+    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";
+    field public static final String EXTRA_USSD = "ussd";
+    field public static final int OIR_DEFAULT = 0; // 0x0
+    field public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; // 0x2
+    field public static final int OIR_PRESENTATION_PAYPHONE = 4; // 0x4
+    field public static final int OIR_PRESENTATION_RESTRICTED = 1; // 0x1
+    field public static final int OIR_PRESENTATION_UNKNOWN = 3; // 0x3
+    field public static final int SERVICE_TYPE_EMERGENCY = 2; // 0x2
+    field public static final int SERVICE_TYPE_NONE = 0; // 0x0
+    field public static final int SERVICE_TYPE_NORMAL = 1; // 0x1
+    field public static final int VERIFICATION_STATUS_FAILED = 2; // 0x2
+    field public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0; // 0x0
+    field public static final int VERIFICATION_STATUS_PASSED = 1; // 0x1
+  }
+
+  public class ImsCallSessionListener {
+    method public void callQualityChanged(@NonNull android.telephony.CallQuality);
+    method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
+    method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
+    method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
+    method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
+    method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
+    method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
+    method public void callSessionHoldFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionHoldReceived(android.telephony.ims.ImsCallProfile);
+    method public void callSessionInitiated(android.telephony.ims.ImsCallProfile);
+    method public void callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionInviteParticipantsRequestDelivered();
+    method public void callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
+    method @Deprecated public void callSessionMayHandover(int, int);
+    method public void callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase);
+    method public void callSessionMergeFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
+    method public void callSessionMultipartyStateChanged(boolean);
+    method public void callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile);
+    method public void callSessionRemoveParticipantsRequestDelivered();
+    method public void callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
+    method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
+    method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
+    method public void callSessionRttMessageReceived(String);
+    method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
+    method public void callSessionRttModifyResponseReceived(int);
+    method public void callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification);
+    method public void callSessionTerminated(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionTtyModeReceived(int);
+    method public void callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionUpdateReceived(android.telephony.ims.ImsCallProfile);
+    method public void callSessionUpdated(android.telephony.ims.ImsCallProfile);
+    method public void callSessionUssdMessageReceived(int, String);
+    method public void onHandover(int, int, @Nullable android.telephony.ims.ImsReasonInfo);
+    method public void onHandoverFailed(int, int, @NonNull android.telephony.ims.ImsReasonInfo);
+    method public void onMayHandover(int, int);
+  }
+
+  public final class ImsConferenceState implements android.os.Parcelable {
+    method public int describeContents();
+    method public static int getConnectionStateForStatus(String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsConferenceState> CREATOR;
+    field public static final String DISPLAY_TEXT = "display-text";
+    field public static final String ENDPOINT = "endpoint";
+    field public static final String SIP_STATUS_CODE = "sipstatuscode";
+    field public static final String STATUS = "status";
+    field public static final String STATUS_ALERTING = "alerting";
+    field public static final String STATUS_CONNECTED = "connected";
+    field public static final String STATUS_CONNECT_FAIL = "connect-fail";
+    field public static final String STATUS_DIALING_IN = "dialing-in";
+    field public static final String STATUS_DIALING_OUT = "dialing-out";
+    field public static final String STATUS_DISCONNECTED = "disconnected";
+    field public static final String STATUS_DISCONNECTING = "disconnecting";
+    field public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus";
+    field public static final String STATUS_ON_HOLD = "on-hold";
+    field public static final String STATUS_PENDING = "pending";
+    field public static final String STATUS_SEND_ONLY = "sendonly";
+    field public static final String STATUS_SEND_RECV = "sendrecv";
+    field public static final String USER = "user";
+    field public final java.util.HashMap<java.lang.String,android.os.Bundle> mParticipants;
+  }
+
+  public final class ImsException extends java.lang.Exception {
+    ctor public ImsException(@Nullable String);
+    ctor public ImsException(@Nullable String, int);
+    ctor public ImsException(@Nullable String, int, @Nullable Throwable);
+  }
+
+  public final class ImsExternalCallState implements android.os.Parcelable {
+    ctor public ImsExternalCallState(@NonNull String, @NonNull android.net.Uri, @Nullable android.net.Uri, boolean, int, int, boolean);
+    method public int describeContents();
+    method @NonNull public android.net.Uri getAddress();
+    method public int getCallId();
+    method public int getCallState();
+    method public int getCallType();
+    method @Nullable public android.net.Uri getLocalAddress();
+    method public boolean isCallHeld();
+    method public boolean isCallPullable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CALL_STATE_CONFIRMED = 1; // 0x1
+    field public static final int CALL_STATE_TERMINATED = 2; // 0x2
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsExternalCallState> CREATOR;
+  }
+
+  public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
+    method @Deprecated @NonNull @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAvailable(int, int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isCapable(int, int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void isSupported(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>) throws android.telephony.ims.ImsException;
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiModeSetting(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiNonPersistent(boolean, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingModeSetting(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingSettingEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback);
+  }
+
+  @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback {
+    ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
+  }
+
+  public final class ImsReasonInfo implements android.os.Parcelable {
+    field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service";
+  }
+
+  public class ImsService extends android.app.Service {
+    ctor public ImsService();
+    method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
+    method public android.telephony.ims.feature.RcsFeature createRcsFeature(int);
+    method public void disableIms(int);
+    method public void enableIms(int);
+    method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int);
+    method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int);
+    method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException;
+    method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures();
+    method public void readyForFeatureCreation();
+  }
+
+  public final class ImsSsData implements android.os.Parcelable {
+    ctor public ImsSsData(int, int, int, int, int);
+    method public int describeContents();
+    method @Nullable public java.util.List<android.telephony.ims.ImsCallForwardInfo> getCallForwardInfo();
+    method public int getRequestType();
+    method public int getResult();
+    method public int getServiceClass();
+    method public int getServiceType();
+    method @NonNull public java.util.List<android.telephony.ims.ImsSsInfo> getSuppServiceInfo();
+    method public int getTeleserviceType();
+    method public boolean isTypeBarring();
+    method public boolean isTypeCf();
+    method public boolean isTypeClip();
+    method public boolean isTypeClir();
+    method public boolean isTypeColp();
+    method public boolean isTypeColr();
+    method public boolean isTypeCw();
+    method public boolean isTypeIcb();
+    method public boolean isTypeInterrogation();
+    method public boolean isTypeUnConditional();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsData> CREATOR;
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+    field public static final int SERVICE_CLASS_DATA = 2; // 0x2
+    field public static final int SERVICE_CLASS_DATA_CIRCUIT_ASYNC = 32; // 0x20
+    field public static final int SERVICE_CLASS_DATA_CIRCUIT_SYNC = 16; // 0x10
+    field public static final int SERVICE_CLASS_DATA_PACKET_ACCESS = 64; // 0x40
+    field public static final int SERVICE_CLASS_DATA_PAD = 128; // 0x80
+    field public static final int SERVICE_CLASS_FAX = 4; // 0x4
+    field public static final int SERVICE_CLASS_NONE = 0; // 0x0
+    field public static final int SERVICE_CLASS_SMS = 8; // 0x8
+    field public static final int SERVICE_CLASS_VOICE = 1; // 0x1
+    field public static final int SS_ACTIVATION = 0; // 0x0
+    field public static final int SS_ALL_BARRING = 18; // 0x12
+    field public static final int SS_ALL_DATA_TELESERVICES = 3; // 0x3
+    field public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; // 0x5
+    field public static final int SS_ALL_TELESEVICES = 1; // 0x1
+    field public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; // 0x0
+    field public static final int SS_BAIC = 16; // 0x10
+    field public static final int SS_BAIC_ROAMING = 17; // 0x11
+    field public static final int SS_BAOC = 13; // 0xd
+    field public static final int SS_BAOIC = 14; // 0xe
+    field public static final int SS_BAOIC_EXC_HOME = 15; // 0xf
+    field public static final int SS_CFU = 0; // 0x0
+    field public static final int SS_CFUT = 6; // 0x6
+    field public static final int SS_CF_ALL = 4; // 0x4
+    field public static final int SS_CF_ALL_CONDITIONAL = 5; // 0x5
+    field public static final int SS_CF_BUSY = 1; // 0x1
+    field public static final int SS_CF_NOT_REACHABLE = 3; // 0x3
+    field public static final int SS_CF_NO_REPLY = 2; // 0x2
+    field public static final int SS_CLIP = 7; // 0x7
+    field public static final int SS_CLIR = 8; // 0x8
+    field public static final int SS_CNAP = 11; // 0xb
+    field public static final int SS_COLP = 9; // 0x9
+    field public static final int SS_COLR = 10; // 0xa
+    field public static final int SS_DEACTIVATION = 1; // 0x1
+    field public static final int SS_ERASURE = 4; // 0x4
+    field public static final int SS_INCOMING_BARRING = 20; // 0x14
+    field public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; // 0x16
+    field public static final int SS_INCOMING_BARRING_DN = 21; // 0x15
+    field public static final int SS_INTERROGATION = 2; // 0x2
+    field public static final int SS_OUTGOING_BARRING = 19; // 0x13
+    field public static final int SS_REGISTRATION = 3; // 0x3
+    field public static final int SS_SMS_SERVICES = 4; // 0x4
+    field public static final int SS_TELEPHONY = 2; // 0x2
+    field public static final int SS_WAIT = 12; // 0xc
+  }
+
+  public static final class ImsSsData.Builder {
+    ctor public ImsSsData.Builder(int, int, int, int, int);
+    method @NonNull public android.telephony.ims.ImsSsData build();
+    method @NonNull public android.telephony.ims.ImsSsData.Builder setCallForwardingInfo(@NonNull java.util.List<android.telephony.ims.ImsCallForwardInfo>);
+    method @NonNull public android.telephony.ims.ImsSsData.Builder setSuppServiceInfo(@NonNull java.util.List<android.telephony.ims.ImsSsInfo>);
+  }
+
+  public final class ImsSsInfo implements android.os.Parcelable {
+    ctor @Deprecated public ImsSsInfo(int, @Nullable String);
+    method public int describeContents();
+    method public int getClirInterrogationStatus();
+    method public int getClirOutgoingState();
+    method @Deprecated public String getIcbNum();
+    method @Nullable public String getIncomingCommunicationBarringNumber();
+    method public int getProvisionStatus();
+    method public int getStatus();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CLIR_OUTGOING_DEFAULT = 0; // 0x0
+    field public static final int CLIR_OUTGOING_INVOCATION = 1; // 0x1
+    field public static final int CLIR_OUTGOING_SUPPRESSION = 2; // 0x2
+    field public static final int CLIR_STATUS_NOT_PROVISIONED = 0; // 0x0
+    field public static final int CLIR_STATUS_PROVISIONED_PERMANENT = 1; // 0x1
+    field public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4; // 0x4
+    field public static final int CLIR_STATUS_TEMPORARILY_RESTRICTED = 3; // 0x3
+    field public static final int CLIR_STATUS_UNKNOWN = 2; // 0x2
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsInfo> CREATOR;
+    field public static final int DISABLED = 0; // 0x0
+    field public static final int ENABLED = 1; // 0x1
+    field public static final int NOT_REGISTERED = -1; // 0xffffffff
+    field public static final int SERVICE_NOT_PROVISIONED = 0; // 0x0
+    field public static final int SERVICE_PROVISIONED = 1; // 0x1
+    field public static final int SERVICE_PROVISIONING_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class ImsSsInfo.Builder {
+    ctor public ImsSsInfo.Builder(int);
+    method @NonNull public android.telephony.ims.ImsSsInfo build();
+    method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirInterrogationStatus(int);
+    method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirOutgoingState(int);
+    method @NonNull public android.telephony.ims.ImsSsInfo.Builder setIncomingCommunicationBarringNumber(@NonNull String);
+    method @NonNull public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int);
+  }
+
+  public final class ImsStreamMediaProfile implements android.os.Parcelable {
+    ctor public ImsStreamMediaProfile(int, int, int, int, int);
+    method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
+    method public int describeContents();
+    method public int getAudioDirection();
+    method public int getAudioQuality();
+    method public int getRttMode();
+    method public int getVideoDirection();
+    method public int getVideoQuality();
+    method public boolean isReceivingRttAudio();
+    method public boolean isRttCall();
+    method public void setReceivingRttAudio(boolean);
+    method public void setRttMode(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int AUDIO_QUALITY_AMR = 1; // 0x1
+    field public static final int AUDIO_QUALITY_AMR_WB = 2; // 0x2
+    field public static final int AUDIO_QUALITY_EVRC = 4; // 0x4
+    field public static final int AUDIO_QUALITY_EVRC_B = 5; // 0x5
+    field public static final int AUDIO_QUALITY_EVRC_NW = 7; // 0x7
+    field public static final int AUDIO_QUALITY_EVRC_WB = 6; // 0x6
+    field public static final int AUDIO_QUALITY_EVS_FB = 20; // 0x14
+    field public static final int AUDIO_QUALITY_EVS_NB = 17; // 0x11
+    field public static final int AUDIO_QUALITY_EVS_SWB = 19; // 0x13
+    field public static final int AUDIO_QUALITY_EVS_WB = 18; // 0x12
+    field public static final int AUDIO_QUALITY_G711A = 13; // 0xd
+    field public static final int AUDIO_QUALITY_G711AB = 15; // 0xf
+    field public static final int AUDIO_QUALITY_G711U = 11; // 0xb
+    field public static final int AUDIO_QUALITY_G722 = 14; // 0xe
+    field public static final int AUDIO_QUALITY_G723 = 12; // 0xc
+    field public static final int AUDIO_QUALITY_G729 = 16; // 0x10
+    field public static final int AUDIO_QUALITY_GSM_EFR = 8; // 0x8
+    field public static final int AUDIO_QUALITY_GSM_FR = 9; // 0x9
+    field public static final int AUDIO_QUALITY_GSM_HR = 10; // 0xa
+    field public static final int AUDIO_QUALITY_NONE = 0; // 0x0
+    field public static final int AUDIO_QUALITY_QCELP13K = 3; // 0x3
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsStreamMediaProfile> CREATOR;
+    field public static final int DIRECTION_INACTIVE = 0; // 0x0
+    field public static final int DIRECTION_INVALID = -1; // 0xffffffff
+    field public static final int DIRECTION_RECEIVE = 1; // 0x1
+    field public static final int DIRECTION_SEND = 2; // 0x2
+    field public static final int DIRECTION_SEND_RECEIVE = 3; // 0x3
+    field public static final int RTT_MODE_DISABLED = 0; // 0x0
+    field public static final int RTT_MODE_FULL = 1; // 0x1
+    field public static final int VIDEO_QUALITY_NONE = 0; // 0x0
+    field public static final int VIDEO_QUALITY_QCIF = 1; // 0x1
+    field public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = 2; // 0x2
+    field public static final int VIDEO_QUALITY_QVGA_PORTRAIT = 4; // 0x4
+    field public static final int VIDEO_QUALITY_VGA_LANDSCAPE = 8; // 0x8
+    field public static final int VIDEO_QUALITY_VGA_PORTRAIT = 16; // 0x10
+  }
+
+  public final class ImsSuppServiceNotification implements android.os.Parcelable {
+    ctor public ImsSuppServiceNotification(int, int, int, int, String, String[]);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSuppServiceNotification> CREATOR;
+    field public final int code;
+    field public final String[] history;
+    field public final int index;
+    field public final int notificationType;
+    field public final String number;
+    field public final int type;
+  }
+
+  public class ImsUtListener {
+    method public void onLineIdentificationSupplementaryServiceResponse(int, @NonNull android.telephony.ims.ImsSsInfo);
+    method public void onSupplementaryServiceIndication(android.telephony.ims.ImsSsData);
+    method public void onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]);
+    method public void onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]);
+    method public void onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]);
+    method @Deprecated public void onUtConfigurationQueried(int, android.os.Bundle);
+    method public void onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo);
+    method public void onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo);
+    method public void onUtConfigurationUpdated(int);
+    field @Deprecated public static final String BUNDLE_KEY_CLIR = "queryClir";
+    field @Deprecated public static final String BUNDLE_KEY_SSINFO = "imsSsInfo";
+  }
+
+  public abstract class ImsVideoCallProvider {
+    ctor public ImsVideoCallProvider();
+    method public void changeCallDataUsage(long);
+    method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
+    method public void changePeerDimensions(int, int);
+    method public void changeVideoQuality(int);
+    method public void handleCallSessionEvent(int);
+    method public abstract void onRequestCallDataUsage();
+    method public abstract void onRequestCameraCapabilities();
+    method public abstract void onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile);
+    method public abstract void onSendSessionModifyResponse(android.telecom.VideoProfile);
+    method public abstract void onSetCamera(String);
+    method public void onSetCamera(String, int);
+    method public abstract void onSetDeviceOrientation(int);
+    method public abstract void onSetDisplaySurface(android.view.Surface);
+    method public abstract void onSetPauseImage(android.net.Uri);
+    method public abstract void onSetPreviewSurface(android.view.Surface);
+    method public abstract void onSetZoom(float);
+    method public void receiveSessionModifyRequest(android.telecom.VideoProfile);
+    method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile);
+  }
+
+  public class ProvisioningManager {
+    method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getProvisioningIntValue(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getProvisioningStatusForCapability(int, int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getRcsProvisioningStatusForCapability(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(int, int, boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
+    field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
+    field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
+    field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
+    field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1
+    field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC";
+    field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY";
+  }
+
+  public static class ProvisioningManager.Callback {
+    ctor public ProvisioningManager.Callback();
+    method public void onProvisioningIntChanged(int, int);
+    method public void onProvisioningStringChanged(int, @NonNull String);
+  }
+
+  public class RcsUceAdapter {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
+  }
+
+}
+
+package android.telephony.ims.feature {
+
+  public final class CapabilityChangeRequest implements android.os.Parcelable {
+    method public void addCapabilitiesToDisableForTech(int, int);
+    method public void addCapabilitiesToEnableForTech(int, int);
+    method public int describeContents();
+    method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToDisable();
+    method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToEnable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.feature.CapabilityChangeRequest> CREATOR;
+  }
+
+  public static class CapabilityChangeRequest.CapabilityPair {
+    ctor public CapabilityChangeRequest.CapabilityPair(int, int);
+    method public int getCapability();
+    method public int getRadioTech();
+  }
+
+  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();
+    method public final void setFeatureState(int);
+    field public static final int CAPABILITY_ERROR_GENERIC = -1; // 0xffffffff
+    field public static final int CAPABILITY_SUCCESS = 0; // 0x0
+    field public static final int FEATURE_EMERGENCY_MMTEL = 0; // 0x0
+    field public static final int FEATURE_MMTEL = 1; // 0x1
+    field public static final int FEATURE_RCS = 2; // 0x2
+    field public static final int STATE_INITIALIZING = 1; // 0x1
+    field public static final int STATE_READY = 2; // 0x2
+    field public static final int STATE_UNAVAILABLE = 0; // 0x0
+  }
+
+  @Deprecated public static class ImsFeature.Capabilities {
+    field @Deprecated protected int mCapabilities;
+  }
+
+  protected static class ImsFeature.CapabilityCallbackProxy {
+    method public void onChangeCapabilityConfigurationError(int, int, int);
+  }
+
+  public class MmTelFeature extends android.telephony.ims.feature.ImsFeature {
+    ctor public MmTelFeature();
+    method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+    method @Nullable public android.telephony.ims.ImsCallProfile createCallProfile(int, int);
+    method @Nullable public android.telephony.ims.stub.ImsCallSessionImplBase createCallSession(@NonNull android.telephony.ims.ImsCallProfile);
+    method @NonNull public android.telephony.ims.stub.ImsEcbmImplBase getEcbm();
+    method @NonNull public android.telephony.ims.stub.ImsMultiEndpointImplBase getMultiEndpoint();
+    method @NonNull public android.telephony.ims.stub.ImsSmsImplBase getSmsImplementation();
+    method @NonNull public android.telephony.ims.stub.ImsUtImplBase getUt();
+    method public final void notifyCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
+    method public final void notifyIncomingCall(@NonNull android.telephony.ims.stub.ImsCallSessionImplBase, @NonNull android.os.Bundle);
+    method public final void notifyRejectedCall(@NonNull android.telephony.ims.ImsCallProfile, @NonNull android.telephony.ims.ImsReasonInfo);
+    method public final void notifyVoiceMessageCountUpdate(int);
+    method public void onFeatureReady();
+    method public void onFeatureRemoved();
+    method public boolean queryCapabilityConfiguration(int, int);
+    method @NonNull public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
+    method public void setUiTtyMode(int, @Nullable android.os.Message);
+    method public int shouldProcessCall(@NonNull String[]);
+    field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
+    field public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD";
+    field public static final int PROCESS_CALL_CSFB = 1; // 0x1
+    field public static final int PROCESS_CALL_IMS = 0; // 0x0
+  }
+
+  public static class MmTelFeature.MmTelCapabilities extends android.telephony.ims.feature.ImsFeature.Capabilities {
+    ctor public MmTelFeature.MmTelCapabilities();
+    ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
+    ctor public MmTelFeature.MmTelCapabilities(int);
+    method public final void addCapabilities(int);
+    method public final boolean isCapable(int);
+    method public final void removeCapabilities(int);
+  }
+
+  public class RcsFeature extends android.telephony.ims.feature.ImsFeature {
+    ctor public RcsFeature();
+    method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+    method public void onFeatureReady();
+    method public void onFeatureRemoved();
+  }
+
+}
+
+package android.telephony.ims.stub {
+
+  public class ImsCallSessionImplBase implements java.lang.AutoCloseable {
+    ctor public ImsCallSessionImplBase();
+    method public void accept(int, android.telephony.ims.ImsStreamMediaProfile);
+    method public void close();
+    method public void deflect(String);
+    method public void extendToConference(String[]);
+    method public String getCallId();
+    method public android.telephony.ims.ImsCallProfile getCallProfile();
+    method public android.telephony.ims.ImsVideoCallProvider getImsVideoCallProvider();
+    method public android.telephony.ims.ImsCallProfile getLocalCallProfile();
+    method public String getProperty(String);
+    method public android.telephony.ims.ImsCallProfile getRemoteCallProfile();
+    method public int getState();
+    method public void hold(android.telephony.ims.ImsStreamMediaProfile);
+    method public void inviteParticipants(String[]);
+    method public boolean isInCall();
+    method public boolean isMultiparty();
+    method public void merge();
+    method public void reject(int);
+    method public void removeParticipants(String[]);
+    method public void resume(android.telephony.ims.ImsStreamMediaProfile);
+    method public void sendDtmf(char, android.os.Message);
+    method public void sendRttMessage(String);
+    method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
+    method public void sendRttModifyResponse(boolean);
+    method public void sendUssd(String);
+    method public void setListener(android.telephony.ims.ImsCallSessionListener);
+    method public void setMute(boolean);
+    method public void start(String, android.telephony.ims.ImsCallProfile);
+    method public void startConference(String[], android.telephony.ims.ImsCallProfile);
+    method public void startDtmf(char);
+    method public void stopDtmf();
+    method public void terminate(int);
+    method public void update(int, android.telephony.ims.ImsStreamMediaProfile);
+    field public static final int USSD_MODE_NOTIFY = 0; // 0x0
+    field public static final int USSD_MODE_REQUEST = 1; // 0x1
+  }
+
+  public static class ImsCallSessionImplBase.State {
+    method public static String toString(int);
+    field public static final int ESTABLISHED = 4; // 0x4
+    field public static final int ESTABLISHING = 3; // 0x3
+    field public static final int IDLE = 0; // 0x0
+    field public static final int INITIATED = 1; // 0x1
+    field public static final int INVALID = -1; // 0xffffffff
+    field public static final int NEGOTIATING = 2; // 0x2
+    field public static final int REESTABLISHING = 6; // 0x6
+    field public static final int RENEGOTIATING = 5; // 0x5
+    field public static final int TERMINATED = 8; // 0x8
+    field public static final int TERMINATING = 7; // 0x7
+  }
+
+  public class ImsConfigImplBase {
+    ctor public ImsConfigImplBase();
+    method public int getConfigInt(int);
+    method public String getConfigString(int);
+    method public final void notifyProvisionedValueChanged(int, int);
+    method public final void notifyProvisionedValueChanged(int, String);
+    method public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
+    method public int setConfig(int, int);
+    method public int setConfig(int, String);
+    field public static final int CONFIG_RESULT_FAILED = 1; // 0x1
+    field public static final int CONFIG_RESULT_SUCCESS = 0; // 0x0
+    field public static final int CONFIG_RESULT_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public class ImsEcbmImplBase {
+    ctor public ImsEcbmImplBase();
+    method public final void enteredEcbm();
+    method public void exitEmergencyCallbackMode();
+    method public final void exitedEcbm();
+  }
+
+  public final class ImsFeatureConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.util.Set<android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair> getServiceFeatures();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.stub.ImsFeatureConfiguration> CREATOR;
+  }
+
+  public static class ImsFeatureConfiguration.Builder {
+    ctor public ImsFeatureConfiguration.Builder();
+    method public android.telephony.ims.stub.ImsFeatureConfiguration.Builder addFeature(int, int);
+    method public android.telephony.ims.stub.ImsFeatureConfiguration build();
+  }
+
+  public static final class ImsFeatureConfiguration.FeatureSlotPair {
+    ctor public ImsFeatureConfiguration.FeatureSlotPair(int, int);
+    field public final int featureType;
+    field public final int slotId;
+  }
+
+  public class ImsMultiEndpointImplBase {
+    ctor public ImsMultiEndpointImplBase();
+    method public final void onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>);
+    method public void requestImsExternalCallStateInfo();
+  }
+
+  public class ImsRegistrationImplBase {
+    ctor public ImsRegistrationImplBase();
+    method public final void onDeregistered(android.telephony.ims.ImsReasonInfo);
+    method public final void onRegistered(int);
+    method public final void onRegistering(int);
+    method public final void onSubscriberAssociatedUriChanged(android.net.Uri[]);
+    method public final void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo);
+    field public static final int REGISTRATION_TECH_IWLAN = 1; // 0x1
+    field public static final int REGISTRATION_TECH_LTE = 0; // 0x0
+    field public static final int REGISTRATION_TECH_NONE = -1; // 0xffffffff
+  }
+
+  public class ImsSmsImplBase {
+    ctor public ImsSmsImplBase();
+    method public void acknowledgeSms(int, @IntRange(from=0, to=65535) int, int);
+    method public void acknowledgeSmsReport(int, @IntRange(from=0, to=65535) int, int);
+    method public String getSmsFormat();
+    method public void onReady();
+    method @Deprecated public final void onSendSmsResult(int, @IntRange(from=0, to=65535) int, int, int) throws java.lang.RuntimeException;
+    method public final void onSendSmsResultError(int, @IntRange(from=0, to=65535) int, int, int, int) throws java.lang.RuntimeException;
+    method public final void onSendSmsResultSuccess(int, @IntRange(from=0, to=65535) int) throws java.lang.RuntimeException;
+    method public final void onSmsReceived(int, String, byte[]) throws java.lang.RuntimeException;
+    method @Deprecated public final void onSmsStatusReportReceived(int, @IntRange(from=0, to=65535) int, String, byte[]) throws java.lang.RuntimeException;
+    method public final void onSmsStatusReportReceived(int, String, byte[]) throws java.lang.RuntimeException;
+    method public void sendSms(int, @IntRange(from=0, to=65535) int, String, String, boolean, byte[]);
+    field public static final int DELIVER_STATUS_ERROR_GENERIC = 2; // 0x2
+    field public static final int DELIVER_STATUS_ERROR_NO_MEMORY = 3; // 0x3
+    field public static final int DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED = 4; // 0x4
+    field public static final int DELIVER_STATUS_OK = 1; // 0x1
+    field public static final int RESULT_NO_NETWORK_ERROR = -1; // 0xffffffff
+    field public static final int SEND_STATUS_ERROR = 2; // 0x2
+    field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4
+    field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3
+    field public static final int SEND_STATUS_OK = 1; // 0x1
+    field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2
+    field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1
+  }
+
+  public class ImsUtImplBase {
+    ctor public ImsUtImplBase();
+    method public void close();
+    method public int queryCallBarring(int);
+    method public int queryCallBarringForServiceClass(int, int);
+    method public int queryCallForward(int, String);
+    method public int queryCallWaiting();
+    method public int queryClip();
+    method public int queryClir();
+    method public int queryColp();
+    method public int queryColr();
+    method public void setListener(android.telephony.ims.ImsUtListener);
+    method public int transact(android.os.Bundle);
+    method public int updateCallBarring(int, int, String[]);
+    method public int updateCallBarringForServiceClass(int, int, String[], int);
+    method public int updateCallForward(int, int, String, int, int);
+    method public int updateCallWaiting(boolean, int);
+    method public int updateClip(boolean);
+    method public int updateClir(int);
+    method public int updateColp(boolean);
+    method public int updateColr(int);
+  }
+
+}
+
+package android.telephony.mbms {
+
+  public static class DownloadRequest.Builder {
+    method public android.telephony.mbms.DownloadRequest.Builder setServiceId(String);
+  }
+
+  public final class FileInfo implements android.os.Parcelable {
+    ctor public FileInfo(android.net.Uri, String);
+  }
+
+  public final class FileServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
+    ctor public FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>);
+  }
+
+  public class MbmsDownloadReceiver extends android.content.BroadcastReceiver {
+    field public static final int RESULT_APP_NOTIFICATION_ERROR = 6; // 0x6
+    field public static final int RESULT_BAD_TEMP_FILE_ROOT = 3; // 0x3
+    field public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4; // 0x4
+    field public static final int RESULT_INVALID_ACTION = 1; // 0x1
+    field public static final int RESULT_MALFORMED_INTENT = 2; // 0x2
+    field public static final int RESULT_OK = 0; // 0x0
+    field public static final int RESULT_TEMP_FILE_GENERATION_ERROR = 5; // 0x5
+  }
+
+  public final class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
+    ctor public StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date);
+  }
+
+  public final class UriPathPair implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.net.Uri getContentUri();
+    method public android.net.Uri getFilePathUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.mbms.UriPathPair> CREATOR;
+  }
+
+}
+
+package android.telephony.mbms.vendor {
+
+  public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface {
+    ctor public MbmsDownloadServiceBase();
+    method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
+    method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
+    method public android.os.IBinder asBinder();
+    method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public void dispose(int) throws android.os.RemoteException;
+    method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException;
+    method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+    method public int removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
+    method public int removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
+    method public int requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
+    method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
+    method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public int setTempFileRootDirectory(int, String) throws android.os.RemoteException;
+  }
+
+  public class MbmsGroupCallServiceBase extends android.app.Service {
+    ctor public MbmsGroupCallServiceBase();
+    method public void dispose(int) throws android.os.RemoteException;
+    method public int initialize(@NonNull android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public int startGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>, @NonNull android.telephony.mbms.GroupCallCallback);
+    method public void stopGroupCall(int, long);
+    method public void updateGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>);
+  }
+
+  public class MbmsStreamingServiceBase extends android.os.Binder implements android.os.IInterface {
+    ctor public MbmsStreamingServiceBase();
+    method public android.os.IBinder asBinder();
+    method public void dispose(int) throws android.os.RemoteException;
+    method @Nullable public android.net.Uri getPlaybackUri(int, String) throws android.os.RemoteException;
+    method public int initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+    method public int requestUpdateStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
+    method public int startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) throws android.os.RemoteException;
+    method public void stopStreaming(int, String) throws android.os.RemoteException;
+  }
+
+  public class VendorUtils {
+    ctor public VendorUtils();
+    method public static android.content.ComponentName getAppReceiverFromPackageName(android.content.Context, String);
+    field public static final String ACTION_CLEANUP = "android.telephony.mbms.action.CLEANUP";
+    field public static final String ACTION_DOWNLOAD_RESULT_INTERNAL = "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL";
+    field public static final String ACTION_FILE_DESCRIPTOR_REQUEST = "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST";
+    field public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT";
+    field public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI";
+    field public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
+    field public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
+    field public static final String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST";
+    field public static final String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID";
+    field public static final String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
+    field public static final String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT";
+    field public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST";
+  }
+
+}
+
diff --git a/telephony/api/system-removed.txt b/telephony/api/system-removed.txt
new file mode 100644
index 0000000..ae46075
--- /dev/null
+++ b/telephony/api/system-removed.txt
@@ -0,0 +1,19 @@
+// Signature format: 2.0
+package android.telephony {
+
+  public class TelephonyManager {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall();
+    method @Deprecated public void silenceRinger();
+  }
+
+}
+
+package android.telephony.data {
+
+  public final class DataCallResponse implements android.os.Parcelable {
+    ctor public DataCallResponse(int, int, int, int, int, @Nullable String, @Nullable java.util.List<android.net.LinkAddress>, @Nullable java.util.List<java.net.InetAddress>, @Nullable java.util.List<java.net.InetAddress>, @Nullable java.util.List<java.net.InetAddress>, int);
+  }
+
+}
+
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index b897725..f0f9721 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -437,8 +437,9 @@
     /**
      * Returns whether the caller can read phone numbers.
      *
-     * <p>Besides apps with the ability to read phone state per {@link #checkReadPhoneState}, the
-     * default SMS app and apps with READ_SMS or READ_PHONE_NUMBERS can also read phone numbers.
+     * <p>Besides apps with the ability to read phone state per {@link #checkReadPhoneState}
+     * (only prior to R), the default SMS app and apps with READ_SMS or READ_PHONE_NUMBERS
+     * can also read phone numbers.
      */
     public static boolean checkCallingOrSelfReadPhoneNumber(
             Context context, int subId, String callingPackage, @Nullable String callingFeatureId,
@@ -451,8 +452,9 @@
     /**
      * Returns whether the caller can read phone numbers.
      *
-     * <p>Besides apps with the ability to read phone state per {@link #checkReadPhoneState}, the
-     * default SMS app and apps with READ_SMS or READ_PHONE_NUMBERS can also read phone numbers.
+     * <p>Besides apps with the ability to read phone state per {@link #checkReadPhoneState}
+     * (only prior to R), the default SMS app and apps with READ_SMS or READ_PHONE_NUMBERS
+     * can also read phone numbers.
      */
     @VisibleForTesting
     public static boolean checkReadPhoneNumber(
@@ -468,12 +470,15 @@
         // NOTE(b/73308711): If an app has one of the following AppOps bits explicitly revoked, they
         // will be denied access, even if they have another permission and AppOps bit if needed.
 
-        // First, check if we can read the phone state.
+        // First, check if we can read the phone state and the SDK version is below R.
         try {
-            return checkReadPhoneState(
-                    context, subId, pid, uid, callingPackage, callingFeatureId,
-                    message);
-        } catch (SecurityException readPhoneStateSecurityException) {
+            ApplicationInfo info = context.getPackageManager().getApplicationInfoAsUser(
+                    callingPackage, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid()));
+            if (info.targetSdkVersion <= Build.VERSION_CODES.Q) {
+                return checkReadPhoneState(
+                        context, subId, pid, uid, callingPackage, callingFeatureId, message);
+            }
+        } catch (SecurityException | PackageManager.NameNotFoundException e) {
         }
         // Can be read with READ_SMS too.
         try {
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index dcd4eb5..b8a74d2 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -571,6 +571,19 @@
     public @interface PreciseDisconnectCauses {
     }
 
+    /**
+     * Carrier Privilege Status.
+     */
+    @IntDef(prefix = { "CARRIER_PRIVILEGE_STATUS_" }, value = {
+        TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS,
+        TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS,
+        TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED,
+        TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CarrierPrivilegeStatus {
+    }
+
     @IntDef({
             Connection.AUDIO_CODEC_NONE,
             Connection.AUDIO_CODEC_AMR,
@@ -598,48 +611,6 @@
     }
 
     /**
-     * Call forwarding function status
-     */
-    @IntDef(prefix = { "STATUS_" }, value = {
-        CallForwardingInfo.STATUS_ACTIVE,
-        CallForwardingInfo.STATUS_INACTIVE,
-        CallForwardingInfo.STATUS_UNKNOWN_ERROR,
-        CallForwardingInfo.STATUS_NOT_SUPPORTED,
-        CallForwardingInfo.STATUS_FDN_CHECK_FAILURE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CallForwardingStatus {
-    }
-
-    /**
-     * Call forwarding reason types
-     */
-    @IntDef(flag = true, prefix = { "REASON_" }, value = {
-        CallForwardingInfo.REASON_UNCONDITIONAL,
-        CallForwardingInfo.REASON_BUSY,
-        CallForwardingInfo.REASON_NO_REPLY,
-        CallForwardingInfo.REASON_NOT_REACHABLE,
-        CallForwardingInfo.REASON_ALL,
-        CallForwardingInfo.REASON_ALL_CONDITIONAL
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CallForwardingReason {
-    }
-
-    /**
-     * Call waiting function status
-     */
-    @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = {
-        TelephonyManager.CALL_WAITING_STATUS_ACTIVE,
-        TelephonyManager.CALL_WAITING_STATUS_INACTIVE,
-        TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED,
-        TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CallWaitingStatus {
-    }
-
-    /**
      * UICC SIM Application Types
      */
     @IntDef(prefix = { "APPTYPE_" }, value = {
diff --git a/telephony/java/android/telephony/CallForwardingInfo.java b/telephony/java/android/telephony/CallForwardingInfo.java
index 1dd7539..7e777fa 100644
--- a/telephony/java/android/telephony/CallForwardingInfo.java
+++ b/telephony/java/android/telephony/CallForwardingInfo.java
@@ -15,24 +15,24 @@
  */
 
 package android.telephony;
+
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.telephony.Annotation.CallForwardingReason;
-import android.telephony.Annotation.CallForwardingStatus;
 
 import com.android.telephony.Rlog;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
  * Defines the call forwarding information.
  * @hide
  */
-@SystemApi
 public final class CallForwardingInfo implements Parcelable {
     private static final String TAG = "CallForwardingInfo";
 
@@ -41,7 +41,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_INACTIVE = 0;
 
     /**
@@ -49,7 +48,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_ACTIVE = 1;
 
     /**
@@ -58,7 +56,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_FDN_CHECK_FAILURE = 2;
 
     /**
@@ -66,7 +63,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_UNKNOWN_ERROR = 3;
 
     /**
@@ -74,7 +70,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_NOT_SUPPORTED = 4;
 
     /**
@@ -83,7 +78,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_UNCONDITIONAL = 0;
 
     /**
@@ -92,7 +86,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_BUSY = 1;
 
     /**
@@ -101,7 +94,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_NO_REPLY = 2;
 
     /**
@@ -110,7 +102,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_NOT_REACHABLE = 3;
 
     /**
@@ -120,7 +111,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_ALL = 4;
 
     /**
@@ -130,20 +120,48 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_ALL_CONDITIONAL = 5;
 
     /**
+     * Call forwarding function status
+     */
+    @IntDef(prefix = { "STATUS_" }, value = {
+        STATUS_ACTIVE,
+        STATUS_INACTIVE,
+        STATUS_UNKNOWN_ERROR,
+        STATUS_NOT_SUPPORTED,
+        STATUS_FDN_CHECK_FAILURE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallForwardingStatus {
+    }
+
+    /**
+     * Call forwarding reason types
+     */
+    @IntDef(flag = true, prefix = { "REASON_" }, value = {
+        REASON_UNCONDITIONAL,
+        REASON_BUSY,
+        REASON_NO_REPLY,
+        REASON_NOT_REACHABLE,
+        REASON_ALL,
+        REASON_ALL_CONDITIONAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallForwardingReason {
+    }
+
+    /**
      * The call forwarding status.
      */
-    private @CallForwardingStatus int mStatus;
+    private int mStatus;
 
     /**
      * The call forwarding reason indicates the condition under which calls will be forwarded.
      * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
      *            and conditions +CCFC
      */
-    private @CallForwardingReason int mReason;
+    private int mReason;
 
     /**
      * The phone number to which calls will be forwarded.
@@ -166,7 +184,6 @@
      * @param timeSeconds the timeout (in seconds) before the forwarding is attempted
      * @hide
      */
-    @SystemApi
     public CallForwardingInfo(@CallForwardingStatus int status, @CallForwardingReason int reason,
             @Nullable String number, int timeSeconds) {
         mStatus = status;
@@ -182,7 +199,6 @@
      *
      * @hide
      */
-    @SystemApi
     public @CallForwardingStatus int getStatus() {
         return mStatus;
     }
@@ -196,7 +212,6 @@
      *
      * @hide
      */
-    @SystemApi
     public @CallForwardingReason int getReason() {
         return mReason;
     }
@@ -209,7 +224,6 @@
      *
      * @hide
      */
-    @SystemApi
     @Nullable
     public String getNumber() {
         return mNumber;
@@ -227,7 +241,6 @@
      *
      * @hide
      */
-    @SystemApi
     @SuppressLint("MethodNameUnits")
     public int getTimeoutSeconds() {
         return mTimeSeconds;
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index e37a9b9..c2cfbef 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -95,7 +95,6 @@
      *        if there is no valid APN setting for the specific type, then this will be null
      * @hide
      */
-    @SystemApi
     public PreciseDataConnectionState(@DataState int state,
                                       @NetworkType int networkType,
                                       @ApnType int apnTypes, @NonNull String apn,
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index f6a305f..6aea5ee 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -2894,7 +2894,7 @@
                         getSubscriptionId(), null);
             }
         } catch (RemoteException ex) {
-            // ignore it
+            throw new RuntimeException(ex);
         }
         return smsc;
     }
@@ -2916,7 +2916,7 @@
      * </p>
      *
      * @param smsc the SMSC address string.
-     * @return true for success, false otherwise.
+     * @return true for success, false otherwise. Failure can be due modem returning an error.
      */
     @SuppressAutoDoc // for carrier privileges and default SMS application.
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@@ -2928,7 +2928,7 @@
                         smsc, getSubscriptionId(), null);
             }
         } catch (RemoteException ex) {
-            // ignore it
+            throw new RuntimeException(ex);
         }
         return false;
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e559c2a..979554d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -70,13 +70,13 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.Annotation.ApnType;
-import android.telephony.Annotation.CallForwardingReason;
 import android.telephony.Annotation.CallState;
-import android.telephony.Annotation.CallWaitingStatus;
+import android.telephony.Annotation.CarrierPrivilegeStatus;
 import android.telephony.Annotation.NetworkType;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SimActivationState;
 import android.telephony.Annotation.UiccAppType;
+import android.telephony.CallForwardingInfo.CallForwardingReason;
 import android.telephony.VisualVoicemailService.VisualVoicemailTask;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.ApnSetting.MvnoType;
@@ -1279,7 +1279,6 @@
      * <p>Note: this is a protected intent that can only be sent by the system.
      * @hide
      */
-    @SystemApi
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_SERVICE_PROVIDERS_UPDATED =
             "android.telephony.action.SERVICE_PROVIDERS_UPDATED";
@@ -1289,7 +1288,6 @@
      * whether the PLMN should be shown.
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_SHOW_PLMN = "android.telephony.extra.SHOW_PLMN";
 
     /**
@@ -1297,7 +1295,6 @@
      * the operator name of the registered network.
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_PLMN = "android.telephony.extra.PLMN";
 
     /**
@@ -1305,7 +1302,6 @@
      * whether the PLMN should be shown.
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_SHOW_SPN = "android.telephony.extra.SHOW_SPN";
 
     /**
@@ -1313,7 +1309,6 @@
      * the service provider name.
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_SPN = "android.telephony.extra.SPN";
 
     /**
@@ -1321,7 +1316,6 @@
      * the service provider name for data service.
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_DATA_SPN = "android.telephony.extra.DATA_SPN";
 
     /**
@@ -4328,14 +4322,18 @@
 
     /**
      * Returns the phone number string for line 1, for example, the MSISDN
-     * for a GSM phone. Return null if it is unavailable.
+     * for a GSM phone for a particular subscription. Return null if it is unavailable.
+     * <p>
+     * The default SMS app can also use this.
      *
      * <p>Requires Permission:
-     *     {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE},
      *     {@link android.Manifest.permission#READ_SMS READ_SMS},
      *     {@link android.Manifest.permission#READ_PHONE_NUMBERS READ_PHONE_NUMBERS},
      *     that the caller is the default SMS app,
-     *     or that the caller has carrier privileges (see {@link #hasCarrierPrivileges}).
+     *     or that the caller has carrier privileges (see {@link #hasCarrierPrivileges})
+     *     for any API level.
+     *     {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     *     for apps targeting SDK API level 29 and below.
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges or default SMS app
     @RequiresPermission(anyOf = {
@@ -4353,6 +4351,15 @@
      * <p>
      * The default SMS app can also use this.
      *
+     * <p>Requires Permission:
+     *     {@link android.Manifest.permission#READ_SMS READ_SMS},
+     *     {@link android.Manifest.permission#READ_PHONE_NUMBERS READ_PHONE_NUMBERS},
+     *     that the caller is the default SMS app,
+     *     or that the caller has carrier privileges (see {@link #hasCarrierPrivileges})
+     *     for any API level.
+     *     {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     *     for apps targeting SDK API level 29 and below.
+     *
      * @param subId whose phone number for line 1 is returned
      * @hide
      */
@@ -4533,25 +4540,50 @@
     }
 
     /**
-     * Returns the MSISDN string.
-     * for a GSM phone. Return null if it is unavailable.
+     * Returns the MSISDN string for a GSM phone. Return null if it is unavailable.
+     *
+     * <p>Requires Permission:
+     *     {@link android.Manifest.permission#READ_SMS READ_SMS},
+     *     {@link android.Manifest.permission#READ_PHONE_NUMBERS READ_PHONE_NUMBERS},
+     *     that the caller is the default SMS app,
+     *     or that the caller has carrier privileges (see {@link #hasCarrierPrivileges})
+     *     for any API level.
+     *     {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     *     for apps targeting SDK API level 29 and below.
      *
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PHONE_STATE,
+            android.Manifest.permission.READ_SMS,
+            android.Manifest.permission.READ_PHONE_NUMBERS
+    })
     @UnsupportedAppUsage
     public String getMsisdn() {
         return getMsisdn(getSubId());
     }
 
     /**
-     * Returns the MSISDN string.
-     * for a GSM phone. Return null if it is unavailable.
+     * Returns the MSISDN string for a GSM phone. Return null if it is unavailable.
      *
      * @param subId for which msisdn is returned
+     *
+     * <p>Requires Permission:
+     *     {@link android.Manifest.permission#READ_SMS READ_SMS},
+     *     {@link android.Manifest.permission#READ_PHONE_NUMBERS READ_PHONE_NUMBERS},
+     *     that the caller is the default SMS app,
+     *     or that the caller has carrier privileges (see {@link #hasCarrierPrivileges})
+     *     for any API level.
+     *     {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     *     for apps targeting SDK API level 29 and below.
+     *
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PHONE_STATE,
+            android.Manifest.permission.READ_SMS,
+            android.Manifest.permission.READ_PHONE_NUMBERS
+    })
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public String getMsisdn(int subId) {
         try {
@@ -11163,8 +11195,6 @@
                 retVal = telephony.isDataEnabled(subId);
         } catch (RemoteException e) {
             Log.e(TAG, "Error isDataConnectionAllowed", e);
-        } catch (NullPointerException e) {
-            return false;
         }
         return retVal;
     }
@@ -11179,6 +11209,8 @@
      * PackageManager.FEATURE_TELEPHONY system feature, which is available
      * on any device with a telephony radio, even if the device is
      * voice-only.
+     *
+     * @hide
      */
     public boolean isDataCapable() {
         if (mContext == null) return true;
@@ -12449,7 +12481,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public int getCarrierPrivilegeStatus(int uid) {
+    public @CarrierPrivilegeStatus int getCarrierPrivilegeStatus(int uid) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
@@ -12714,7 +12746,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @NonNull
     public CallForwardingInfo getCallForwarding(@CallForwardingReason int callForwardingReason) {
@@ -12761,7 +12792,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setCallForwarding(@NonNull CallForwardingInfo callForwardingInfo) {
         if (callForwardingInfo == null) {
@@ -12802,7 +12832,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_WAITING_STATUS_ACTIVE = 1;
 
     /**
@@ -12810,7 +12839,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_WAITING_STATUS_INACTIVE = 2;
 
     /**
@@ -12818,7 +12846,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3;
 
     /**
@@ -12826,10 +12853,24 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4;
 
     /**
+     * Call waiting function status
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = {
+        CALL_WAITING_STATUS_ACTIVE,
+        CALL_WAITING_STATUS_INACTIVE,
+        CALL_WAITING_STATUS_NOT_SUPPORTED,
+        CALL_WAITING_STATUS_UNKNOWN_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallWaitingStatus {
+    }
+
+    /**
      * Gets the status of voice call waiting function. Call waiting function enables the waiting
      * for the incoming call when it reaches the user who is busy to make another call and allows
      * users to decide whether to switch to the incoming call.
@@ -12837,7 +12878,6 @@
      * @return the status of call waiting function.
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public @CallWaitingStatus int getCallWaitingStatus() {
         try {
@@ -12863,7 +12903,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setCallWaitingStatus(boolean isEnable) {
         try {
diff --git a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java b/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java
index ae20cae..629b6c7 100644
--- a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java
+++ b/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java
@@ -98,7 +98,8 @@
         mDevice = getDevice();
 
         String apkVerityMode = mDevice.getProperty("ro.apk_verity.mode");
-        assumeTrue(APK_VERITY_STANDARD_MODE.equals(apkVerityMode));
+        assumeTrue(mDevice.getLaunchApiLevel() >= 30
+                || APK_VERITY_STANDARD_MODE.equals(apkVerityMode));
 
         mKeyId = expectRemoteCommandToSucceed(
                 "mini-keyctl padd asymmetric fsv_test .fs-verity < " + CERT_PATH).trim();
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index da45d9a..2f9a1c8 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -71,6 +71,7 @@
     // with the app launch
     private static final String KEY_REQUIRED_ACCOUNTS = "required_accounts";
     private static final String KEY_APPS = "apps";
+    private static final String KEY_IORAP_TRIAL_LAUNCH = "iorap_trial_launch";
     private static final String KEY_TRIAL_LAUNCH = "trial_launch";
     private static final String KEY_LAUNCH_ITERATIONS = "launch_iterations";
     private static final String KEY_LAUNCH_ORDER = "launch_order";
@@ -98,6 +99,9 @@
     private static final int BEFORE_KILL_APP_SLEEP_TIMEOUT = 1000; // 1s before killing
     private static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 3000; // 3s between launching apps
     private static final int PROFILE_SAVE_SLEEP_TIMEOUT = 1000; // Allow 1s for the profile to save
+    private static final int IORAP_TRACE_DURATION_TIMEOUT = 7000; // Allow 7s for trace to complete.
+    private static final int IORAP_TRIAL_LAUNCH_ITERATIONS = 3;  // min 3 launches to merge traces.
+    private static final int IORAP_COMPILE_CMD_TIMEOUT = 600;  // in seconds: 10 minutes
     private static final String LAUNCH_SUB_DIRECTORY = "launch_logs";
     private static final String LAUNCH_FILE = "applaunch.txt";
     private static final String TRACE_SUB_DIRECTORY = "atrace_logs";
@@ -106,6 +110,9 @@
     private static final String DEFAULT_TRACE_BUFFER_SIZE = "20000";
     private static final String DEFAULT_TRACE_DUMP_INTERVAL = "10";
     private static final String TRIAL_LAUNCH = "TRIAL_LAUNCH";
+    private static final String IORAP_TRIAL_LAUNCH = "IORAP_TRIAL_LAUNCH";
+    private static final String IORAP_TRIAL_LAUNCH_FIRST = "IORAP_TRIAL_LAUNCH_FIRST";
+    private static final String IORAP_TRIAL_LAUNCH_LAST = "IORAP_TRIAL_LAUNCH_LAST";
     private static final String DELIMITER = ",";
     private static final String DROP_CACHE_SCRIPT = "/data/local/tmp/dropCache.sh";
     private static final String APP_LAUNCH_CMD = "am start -W -n";
@@ -119,6 +126,10 @@
     private static final String LAUNCH_ORDER_CYCLIC = "cyclic";
     private static final String LAUNCH_ORDER_SEQUENTIAL = "sequential";
     private static final String COMPILE_CMD = "cmd package compile -f -m %s %s";
+    private static final String IORAP_COMPILE_CMD = "cmd jobscheduler run -f android 283673059";
+    private static final String IORAP_MAINTENANCE_CMD =
+            "iorap.cmd.maintenance --purge-package %s /data/misc/iorapd/sqlite.db";
+    private static final String IORAP_DUMPSYS_CMD = "dumpsys iorapd";
     private static final String SPEED_PROFILE_FILTER = "speed-profile";
     private static final String VERIFY_FILTER = "verify";
     private static final String LAUNCH_SCRIPT_NAME = "appLaunch";
@@ -138,6 +149,7 @@
     private Bundle mResult = new Bundle();
     private Set<String> mRequiredAccounts;
     private boolean mTrialLaunch = false;
+    private boolean mIorapTrialLaunch = false;
     private BufferedWriter mBufferedWriter = null;
     private boolean mSimplePerfAppOnly = false;
     private String[] mCompilerFilters = null;
@@ -145,6 +157,13 @@
     private boolean mCycleCleanUp = false;
     private boolean mTraceAll = false;
     private boolean mIterationCycle = false;
+
+    enum IorapStatus {
+        UNDEFINED,
+        ENABLED,
+        DISABLED
+    }
+    private IorapStatus mIorapStatus = IorapStatus.UNDEFINED;
     private long mCycleTime = 0;
     private StringBuilder mCycleTimes = new StringBuilder();
 
@@ -243,7 +262,10 @@
             setLaunchOrder();
 
             for (LaunchOrder launch : mLaunchOrderList) {
-                dropCache();
+                toggleIorapStatus(launch.getIorapEnabled());
+                dropCache(/*override*/false);
+
+                Log.v(TAG, "Launch reason: " + launch.getLaunchReason());
 
                 // App launch times for trial launch will not be used for final
                 // launch time calculations.
@@ -289,6 +311,43 @@
                               compileApp(launch.getCompilerFilter(), appPkgName));
                     }
                 }
+                else if (launch.getLaunchReason().startsWith(IORAP_TRIAL_LAUNCH)) {
+                    mIterationCycle = false;
+
+                    // In the "applaunch.txt" file, iorap-trial launches is referenced using
+                    // "IORAP_TRIAL_LAUNCH" or "IORAP_TRIAL_LAUNCH_LAST"
+                    Intent startIntent = mNameToIntent.get(launch.getApp());
+                    if (startIntent == null) {
+                        Log.w(TAG, "App does not exist: " + launch.getApp());
+                        mResult.putString(mNameToResultKey.get(launch.getApp()),
+                            "App does not exist");
+                        continue;
+                    }
+                    String appPkgName = startIntent.getComponent().getPackageName();
+
+                    if (launch.getLaunchReason().equals(IORAP_TRIAL_LAUNCH_FIRST)) {
+                        // delete any iorap-traces associated with this package.
+                        purgeIorapPackage(appPkgName);
+                    }
+                    dropCache(/*override*/true);  // iorap-trial runs must have drop cache.
+
+                    AppLaunchResult launchResult =
+                        startApp(launch.getApp(), launch.getLaunchReason());
+                    if (launchResult.mLaunchTime < 0) {
+                        addLaunchResult(launch, new AppLaunchResult());
+                        // simply pass the app if launch isn't successful
+                        // error should have already been logged by startApp
+                        continue;
+                    }
+                    // wait for slightly more than 5s (iorapd.perfetto.trace_duration_ms) for the trace buffers to complete.
+                    sleep(IORAP_TRACE_DURATION_TIMEOUT);
+
+                    if (launch.getLaunchReason().equals(IORAP_TRIAL_LAUNCH_LAST)) {
+                        // run the iorap job scheduler and wait for iorap to compile fully.
+                        assertTrue(String.format("Not able to iorap-compile the app : %s", appPkgName),
+                                compileAppForIorap(appPkgName));
+                    }
+                }
 
                 // App launch times used for final calculation
                 else if (launch.getLaunchReason().contains(LAUNCH_ITERATION_PREFIX)) {
@@ -440,6 +499,74 @@
     }
 
     /**
+     * Compile the app package using compilerFilter and return true or false
+     * based on status of the compilation command.
+     */
+    private boolean compileAppForIorap(String appPkgName) throws IOException {
+        getInstrumentation().getUiAutomation().
+                executeShellCommand(IORAP_COMPILE_CMD);
+
+        for (int i = 0; i < IORAP_COMPILE_CMD_TIMEOUT; ++i) {
+            IorapCompilationStatus status = waitForIorapCompiled(appPkgName);
+            if (status == IorapCompilationStatus.COMPLETE) {
+                return true;
+            } else if (status == IorapCompilationStatus.INSUFFICIENT_TRACES) {
+                return false;
+            } // else INCOMPLETE. keep asking iorapd if it's done yet.
+            sleep(1000);
+        }
+
+        return false;
+    }
+
+    enum IorapCompilationStatus {
+        INCOMPLETE,
+        COMPLETE,
+        INSUFFICIENT_TRACES,
+    }
+    private IorapCompilationStatus waitForIorapCompiled(String appPkgName) throws IOException {
+        try (ParcelFileDescriptor result = getInstrumentation().getUiAutomation().
+                executeShellCommand(IORAP_DUMPSYS_CMD);
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(result.getFileDescriptor())))) {
+            String line;
+            String prevLine = "";
+            while ((line = bufferedReader.readLine()) != null) {
+                // Match the indented VersionedComponentName string.
+                // "  com.google.android.deskclock/com.android.deskclock.DeskClock@62000712"
+                // Note: spaces are meaningful here.
+                if (prevLine.contains("  " + appPkgName) && prevLine.contains("@")) {
+                    // pre-requisite:
+                    // Compiled Status: Raw traces pending compilation (3)
+                    if (line.contains("Compiled Status: Usable compiled trace")) {
+                        return IorapCompilationStatus.COMPLETE;
+                    } else if (line.contains("Compiled Status: ") &&
+                            line.contains("more traces for compilation")) {
+                        //      Compiled Status: Need 1 more traces for compilation
+                        // No amount of waiting will help here because there were
+                        // insufficient traces made.
+                        return IorapCompilationStatus.INSUFFICIENT_TRACES;
+                    }
+                }
+
+                prevLine = line;
+            }
+            return IorapCompilationStatus.INCOMPLETE;
+        }
+    }
+
+    private String makeReasonForIorapTrialLaunch(int launchCount) {
+        String reason = IORAP_TRIAL_LAUNCH;
+        if (launchCount == 0) {
+            reason = IORAP_TRIAL_LAUNCH_FIRST;
+        }
+        if (launchCount == IORAP_TRIAL_LAUNCH_ITERATIONS - 1) {
+            reason = IORAP_TRIAL_LAUNCH_LAST;
+        }
+        return reason;
+    }
+
+    /**
      * If launch order is "cyclic" then apps will be launched one after the
      * other for each iteration count.
      * If launch order is "sequential" then each app will be launched for given number
@@ -450,20 +577,31 @@
             for (String compilerFilter : mCompilerFilters) {
                 if (mTrialLaunch) {
                     for (String app : mNameToResultKey.keySet()) {
-                        mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH));
+                        mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH, /*iorapEnabled*/false));
+                    }
+                }
+                if (mIorapTrialLaunch) {
+                    for (int launchCount = 0; launchCount < IORAP_TRIAL_LAUNCH_ITERATIONS; ++launchCount) {
+                        for (String app : mNameToResultKey.keySet()) {
+                            String reason = makeReasonForIorapTrialLaunch(launchCount);
+                            mLaunchOrderList.add(
+                                    new LaunchOrder(app, compilerFilter,
+                                            reason,
+                                            /*iorapEnabled*/true));
+                        }
                     }
                 }
                 for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) {
                     for (String app : mNameToResultKey.keySet()) {
                         mLaunchOrderList.add(new LaunchOrder(app, compilerFilter,
-                                  String.format(LAUNCH_ITERATION, launchCount)));
+                                  String.format(LAUNCH_ITERATION, launchCount), mIorapTrialLaunch));
                     }
                 }
                 if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) {
                     for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) {
                         for (String app : mNameToResultKey.keySet()) {
                             mLaunchOrderList.add(new LaunchOrder(app, compilerFilter,
-                                      String.format(TRACE_ITERATION, traceCount)));
+                                      String.format(TRACE_ITERATION, traceCount), mIorapTrialLaunch));
                         }
                     }
                 }
@@ -472,16 +610,25 @@
             for (String compilerFilter : mCompilerFilters) {
                 for (String app : mNameToResultKey.keySet()) {
                     if (mTrialLaunch) {
-                        mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH));
+                        mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH, /*iorapEnabled*/false));
+                    }
+                    if (mIorapTrialLaunch) {
+                        for (int launchCount = 0; launchCount < IORAP_TRIAL_LAUNCH_ITERATIONS; ++launchCount) {
+                            String reason = makeReasonForIorapTrialLaunch(launchCount);
+                            mLaunchOrderList.add(
+                                    new LaunchOrder(app, compilerFilter,
+                                            reason,
+                                            /*iorapEnabled*/true));
+                        }
                     }
                     for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) {
                         mLaunchOrderList.add(new LaunchOrder(app, compilerFilter,
-                                String.format(LAUNCH_ITERATION, launchCount)));
+                                String.format(LAUNCH_ITERATION, launchCount), mIorapTrialLaunch));
                     }
                     if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) {
                         for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) {
                             mLaunchOrderList.add(new LaunchOrder(app, compilerFilter,
-                                    String.format(TRACE_ITERATION, traceCount)));
+                                    String.format(TRACE_ITERATION, traceCount), mIorapTrialLaunch));
                         }
                     }
                 }
@@ -491,14 +638,92 @@
         }
     }
 
-    private void dropCache() {
-        if (mDropCache) {
+    private void dropCache(boolean override) {
+        if (mDropCache || override) {
             assertNotNull("Issue in dropping the cache",
                     getInstrumentation().getUiAutomation()
                             .executeShellCommand(DROP_CACHE_SCRIPT));
         }
     }
 
+    // [[ $(adb shell whoami) == "root" ]]
+    private boolean checkIfRoot() throws IOException {
+        String total = "";
+        try (ParcelFileDescriptor result = getInstrumentation().getUiAutomation().
+                executeShellCommand("whoami");
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(result.getFileDescriptor())))) {
+            String line;
+            while ((line = bufferedReader.readLine()) != null) {
+                total = total + line;
+            }
+        }
+        return total.contains("root");
+    }
+
+    // Delete all db rows and files associated with a package in iorapd.
+    // Effectively deletes any raw or compiled trace files, unoptimizing the package in iorap.
+    private void purgeIorapPackage(String packageName) {
+        try {
+            if (!checkIfRoot()) {
+                throw new AssertionError("must be root to toggle iorapd; try adb root?");
+            }
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
+
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand("stop iorapd");
+        sleep(100);  // give iorapd enough time to stop.
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand(String.format(IORAP_MAINTENANCE_CMD, packageName));
+        Log.v(TAG, "Executed: " + String.format(IORAP_MAINTENANCE_CMD, packageName));
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand("start iorapd");
+        sleep(2000);  // give iorapd enough time to start up.
+    }
+
+    /**
+     * Toggle iorapd-based readahead and trace-collection.
+     * If iorapd is already enabled and enable is true, does nothing.
+     * If iorapd is already disabled and enable is false, does nothing.
+     */
+    private void toggleIorapStatus(boolean enable) {
+        boolean currentlyEnabled = false;
+        Log.v(TAG, "toggleIorapStatus " + Boolean.toString(enable));
+
+        // Do nothing if we are already enabled or disabled.
+        if (mIorapStatus == IorapStatus.ENABLED && enable) {
+            return;
+        } else if (mIorapStatus == IorapStatus.DISABLED && !enable) {
+            return;
+        }
+
+        try {
+            if (!checkIfRoot()) {
+                throw new AssertionError("must be root to toggle iorapd; try adb root?");
+            }
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
+
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand("stop iorapd");
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand(String.format("setprop iorapd.perfetto.enable %b", enable));
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand(String.format("setprop iorapd.readahead.enable %b", enable));
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand("start iorapd");
+        sleep(2000);  // give enough time for iorapd to start back up.
+
+        if (enable) {
+            mIorapStatus = IorapStatus.ENABLED;
+        } else {
+            mIorapStatus = IorapStatus.DISABLED;
+        }
+    }
+
     private void parseArgs(Bundle args) {
         mNameToResultKey = new LinkedHashMap<String, String>();
         mNameToLaunchTime = new HashMap<>();
@@ -562,6 +787,8 @@
         mCycleCleanUp = Boolean.parseBoolean(args.getString(KEY_CYCLE_CLEAN));
         mTraceAll = Boolean.parseBoolean(args.getString(KEY_TRACE_ALL));
         mTrialLaunch = mTrialLaunch || Boolean.parseBoolean(args.getString(KEY_TRIAL_LAUNCH));
+        mIorapTrialLaunch = mIorapTrialLaunch ||
+                Boolean.parseBoolean(args.getString(KEY_IORAP_TRIAL_LAUNCH));
 
         if (mSimplePerfCmd != null && mSimplePerfAppOnly) {
             Log.w(TAG, String.format("Passing both %s and %s is not supported, ignoring %s",
@@ -740,11 +967,13 @@
         private String mApp;
         private String mCompilerFilter;
         private String mLaunchReason;
+        private boolean mIorapEnabled;
 
-        LaunchOrder(String app, String compilerFilter, String launchReason){
+        LaunchOrder(String app, String compilerFilter, String launchReason, boolean iorapEnabled) {
             mApp = app;
             mCompilerFilter = compilerFilter;
             mLaunchReason = launchReason;
+            mIorapEnabled = iorapEnabled;
         }
 
         public String getApp() {
@@ -766,6 +995,14 @@
         public void setLaunchReason(String launchReason) {
             mLaunchReason = launchReason;
         }
+
+        public void setIorapEnabled(boolean iorapEnabled) {
+            mIorapEnabled = iorapEnabled;
+        }
+
+        public boolean getIorapEnabled() {
+            return mIorapEnabled;
+        }
     }
 
     private class AppLaunchResult {
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index dfaac2c..2957192 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -1077,6 +1077,52 @@
         assertThat(observer1.mMitigatedPackages).isEmpty();
     }
 
+    /**
+     * Test to verify that Package Watchdog syncs health check requests with the controller
+     * correctly, and that the requests are only synced when the set of observed packages
+     * changes.
+     */
+    @Test
+    public void testSyncHealthCheckRequests() {
+        TestController testController = spy(TestController.class);
+        testController.setSupportedPackages(List.of(APP_A, APP_B, APP_C));
+        PackageWatchdog watchdog = createWatchdog(testController, true);
+
+        TestObserver testObserver1 = new TestObserver(OBSERVER_NAME_1);
+        watchdog.registerHealthObserver(testObserver1);
+        watchdog.startObservingHealth(testObserver1, List.of(APP_A), LONG_DURATION);
+        mTestLooper.dispatchAll();
+
+        TestObserver testObserver2 = new TestObserver(OBSERVER_NAME_2);
+        watchdog.registerHealthObserver(testObserver2);
+        watchdog.startObservingHealth(testObserver2, List.of(APP_B), LONG_DURATION);
+        mTestLooper.dispatchAll();
+
+        TestObserver testObserver3 = new TestObserver(OBSERVER_NAME_3);
+        watchdog.registerHealthObserver(testObserver3);
+        watchdog.startObservingHealth(testObserver3, List.of(APP_C), LONG_DURATION);
+        mTestLooper.dispatchAll();
+
+        watchdog.unregisterHealthObserver(testObserver1);
+        mTestLooper.dispatchAll();
+
+        watchdog.unregisterHealthObserver(testObserver2);
+        mTestLooper.dispatchAll();
+
+        watchdog.unregisterHealthObserver(testObserver3);
+        mTestLooper.dispatchAll();
+
+        List<Set> expectedSyncRequests = List.of(
+                Set.of(APP_A),
+                Set.of(APP_A, APP_B),
+                Set.of(APP_A, APP_B, APP_C),
+                Set.of(APP_B, APP_C),
+                Set.of(APP_C),
+                Set.of()
+        );
+        assertThat(testController.getSyncRequests()).isEqualTo(expectedSyncRequests);
+    }
+
     private void adoptShellPermissions(String... permissions) {
         InstrumentationRegistry
                 .getInstrumentation()
@@ -1233,6 +1279,7 @@
         private Consumer<String> mPassedConsumer;
         private Consumer<List<PackageConfig>> mSupportedConsumer;
         private Runnable mNotifySyncRunnable;
+        private List<Set> mSyncRequests = new ArrayList<>();
 
         @Override
         public void setEnabled(boolean enabled) {
@@ -1252,6 +1299,7 @@
 
         @Override
         public void syncRequests(Set<String> packages) {
+            mSyncRequests.add(packages);
             mRequestedPackages.clear();
             if (mIsEnabled) {
                 packages.retainAll(mSupportedPackages);
@@ -1282,6 +1330,10 @@
                 return Collections.emptyList();
             }
         }
+
+        public List<Set> getSyncRequests() {
+            return mSyncRequests;
+        }
     }
 
     private static class TestClock implements PackageWatchdog.SystemClock {
diff --git a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java
index f254e4d..548af0c 100644
--- a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java
+++ b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java
@@ -114,7 +114,14 @@
                                         }
 
                                         @Override
-                                        public void onCancelled() {
+                                        public void onFinished(
+                                                WindowInsetsAnimationController controller) {
+                                            mAnimationController = null;
+                                        }
+
+                                        @Override
+                                        public void onCancelled(
+                                                WindowInsetsAnimationController controller) {
                                             mAnimationController = null;
                                         }
                                     });
@@ -230,7 +237,13 @@
                                         }
 
                                         @Override
-                                        public void onCancelled() {
+                                        public void onFinished(
+                                                WindowInsetsAnimationController controller) {
+                                        }
+
+                                        @Override
+                                        public void onCancelled(
+                                                WindowInsetsAnimationController controller) {
                                         }
                                     });
                         }
diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml
index 480b12b..009f817 100644
--- a/tests/net/AndroidManifest.xml
+++ b/tests/net/AndroidManifest.xml
@@ -47,6 +47,7 @@
     <uses-permission android:name="android.permission.NETWORK_STACK" />
     <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" />
     <uses-permission android:name="android.permission.NETWORK_FACTORY" />
+    <uses-permission android:name="android.permission.NETWORK_STATS_PROVIDER" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/net/common/java/android/net/KeepalivePacketDataTest.kt b/tests/net/common/java/android/net/KeepalivePacketDataTest.kt
new file mode 100644
index 0000000..f464ec6
--- /dev/null
+++ b/tests/net/common/java/android/net/KeepalivePacketDataTest.kt
@@ -0,0 +1,120 @@
+/*
+ * 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 android.net
+
+import android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS
+import android.net.InvalidPacketException.ERROR_INVALID_PORT
+import android.os.Build
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import java.net.InetAddress
+import java.util.Arrays
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class KeepalivePacketDataTest {
+    @Rule @JvmField
+    val ignoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule()
+
+    private val INVALID_PORT = 65537
+    private val TEST_DST_PORT = 4244
+    private val TEST_SRC_PORT = 4243
+
+    private val TESTBYTES = byteArrayOf(12, 31, 22, 44)
+    private val TEST_SRC_ADDRV4 = "198.168.0.2".address()
+    private val TEST_DST_ADDRV4 = "198.168.0.1".address()
+    private val TEST_ADDRV6 = "2001:db8::1".address()
+
+    private fun String.address() = InetAddresses.parseNumericAddress(this)
+
+    // Add for test because constructor of KeepalivePacketData is protected.
+    private inner class TestKeepalivePacketData(
+        srcAddress: InetAddress? = TEST_SRC_ADDRV4,
+        srcPort: Int = TEST_SRC_PORT,
+        dstAddress: InetAddress? = TEST_DST_ADDRV4,
+        dstPort: Int = TEST_DST_PORT,
+        data: ByteArray = TESTBYTES
+    ) : KeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, data)
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testConstructor() {
+        var data: TestKeepalivePacketData
+
+        try {
+            data = TestKeepalivePacketData(srcAddress = null)
+            fail("Null src address should cause exception")
+        } catch (e: InvalidPacketException) {
+            assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+        }
+
+        try {
+            data = TestKeepalivePacketData(dstAddress = null)
+            fail("Null dst address should cause exception")
+        } catch (e: InvalidPacketException) {
+            assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+        }
+
+        try {
+            data = TestKeepalivePacketData(dstAddress = TEST_ADDRV6)
+            fail("Ip family mismatched should cause exception")
+        } catch (e: InvalidPacketException) {
+            assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+        }
+
+        try {
+            data = TestKeepalivePacketData(srcPort = INVALID_PORT)
+            fail("Invalid srcPort should cause exception")
+        } catch (e: InvalidPacketException) {
+            assertEquals(e.error, ERROR_INVALID_PORT)
+        }
+
+        try {
+            data = TestKeepalivePacketData(dstPort = INVALID_PORT)
+            fail("Invalid dstPort should cause exception")
+        } catch (e: InvalidPacketException) {
+            assertEquals(e.error, ERROR_INVALID_PORT)
+        }
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testSrcAddress() = assertEquals(TEST_SRC_ADDRV4, TestKeepalivePacketData().srcAddress)
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testDstAddress() = assertEquals(TEST_DST_ADDRV4, TestKeepalivePacketData().dstAddress)
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testSrcPort() = assertEquals(TEST_SRC_PORT, TestKeepalivePacketData().srcPort)
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testDstPort() = assertEquals(TEST_DST_PORT, TestKeepalivePacketData().dstPort)
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testPacket() = assertTrue(Arrays.equals(TESTBYTES, TestKeepalivePacketData().packet))
+}
\ No newline at end of file
diff --git a/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt b/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt
new file mode 100644
index 0000000..46f39dd
--- /dev/null
+++ b/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt
@@ -0,0 +1,114 @@
+/*
+ * 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 android.net
+
+import android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS
+import android.net.InvalidPacketException.ERROR_INVALID_PORT
+import android.net.NattSocketKeepalive.NATT_PORT
+import android.os.Build
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.assertEqualBothWays
+import com.android.testutils.assertFieldCountEquals
+import com.android.testutils.assertParcelSane
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import com.android.testutils.parcelingRoundTrip
+import java.net.InetAddress
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.fail
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NattKeepalivePacketDataTest {
+    @Rule @JvmField
+    val ignoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule()
+
+    /* Refer to the definition in {@code NattKeepalivePacketData} */
+    private val IPV4_HEADER_LENGTH = 20
+    private val UDP_HEADER_LENGTH = 8
+
+    private val TEST_PORT = 4243
+    private val TEST_PORT2 = 4244
+    private val TEST_SRC_ADDRV4 = "198.168.0.2".address()
+    private val TEST_DST_ADDRV4 = "198.168.0.1".address()
+    private val TEST_ADDRV6 = "2001:db8::1".address()
+
+    private fun String.address() = InetAddresses.parseNumericAddress(this)
+    private fun nattKeepalivePacket(
+        srcAddress: InetAddress? = TEST_SRC_ADDRV4,
+        srcPort: Int = TEST_PORT,
+        dstAddress: InetAddress? = TEST_DST_ADDRV4,
+        dstPort: Int = NATT_PORT
+    ) = NattKeepalivePacketData.nattKeepalivePacket(srcAddress, srcPort, dstAddress, dstPort)
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testConstructor() {
+        try {
+            nattKeepalivePacket(dstPort = TEST_PORT)
+            fail("Dst port is not NATT port should cause exception")
+        } catch (e: InvalidPacketException) {
+            assertEquals(e.error, ERROR_INVALID_PORT)
+        }
+
+        try {
+            nattKeepalivePacket(srcAddress = TEST_ADDRV6)
+            fail("A v6 srcAddress should cause exception")
+        } catch (e: InvalidPacketException) {
+            assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+        }
+
+        try {
+            nattKeepalivePacket(dstAddress = TEST_ADDRV6)
+            fail("A v6 dstAddress should cause exception")
+        } catch (e: InvalidPacketException) {
+            assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+        }
+
+        try {
+            parcelingRoundTrip(
+                    NattKeepalivePacketData(TEST_SRC_ADDRV4, TEST_PORT, TEST_DST_ADDRV4, TEST_PORT,
+                    byteArrayOf(12, 31, 22, 44)))
+            fail("Invalid data should cause exception")
+        } catch (e: IllegalArgumentException) { }
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testParcel() {
+        assertParcelSane(nattKeepalivePacket(), 0)
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testEquals() {
+        assertEqualBothWays(nattKeepalivePacket(), nattKeepalivePacket())
+        assertNotEquals(nattKeepalivePacket(dstAddress = TEST_SRC_ADDRV4), nattKeepalivePacket())
+        assertNotEquals(nattKeepalivePacket(srcAddress = TEST_DST_ADDRV4), nattKeepalivePacket())
+        // Test src port only because dst port have to be NATT_PORT
+        assertNotEquals(nattKeepalivePacket(srcPort = TEST_PORT2), nattKeepalivePacket())
+        // Make sure the parceling test is updated if fields are added in the base class.
+        assertFieldCountEquals(5, KeepalivePacketData::class.java)
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testHashCode() {
+        assertEquals(nattKeepalivePacket().hashCode(), nattKeepalivePacket().hashCode())
+    }
+}
\ No newline at end of file
diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java
index 33d77d2..e71d599 100644
--- a/tests/net/java/android/net/NetworkStatsTest.java
+++ b/tests/net/java/android/net/NetworkStatsTest.java
@@ -64,15 +64,15 @@
     @Test
     public void testFindIndex() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 5)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12)
-                .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12);
 
         assertEquals(4, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES,
@@ -94,21 +94,21 @@
     @Test
     public void testFindIndexHinted() {
         final NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1024L, 8L, 0L, 0L, 10)
-                .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12)
-                .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+                .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
                         DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12);
 
         // verify that we correctly find across regardless of hinting
@@ -143,27 +143,27 @@
         assertEquals(0, stats.size());
         assertEquals(4, stats.internalSize());
 
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_YES, 1L, 1L, 2L, 2L, 3);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_NO, 2L, 2L, 2L, 2L, 4);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                 DEFAULT_NETWORK_YES, 3L, 3L, 2L, 2L, 5);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
                 DEFAULT_NETWORK_NO, 3L, 3L, 2L, 2L, 5);
 
         assertEquals(4, stats.size());
         assertEquals(4, stats.internalSize());
 
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_NO, 4L, 40L, 4L, 40L, 7);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_YES, 5L, 50L, 4L, 40L, 8);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_NO, 6L, 60L, 5L, 50L, 10);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                 DEFAULT_NETWORK_YES, 7L, 70L, 5L, 50L, 11);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
                 DEFAULT_NETWORK_NO, 7L, 70L, 5L, 50L, 11);
 
         assertEquals(9, stats.size());
@@ -193,8 +193,8 @@
     public void testCombineExisting() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 10);
 
-        stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10);
-        stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
+        stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10);
+        stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
         stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L,
                 -128L, -1L, -1);
 
@@ -215,12 +215,12 @@
     @Test
     public void testSubtractIdenticalData() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats after = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats result = after.subtract(before);
 
@@ -234,12 +234,12 @@
     @Test
     public void testSubtractIdenticalRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats after = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20);
 
         final NetworkStats result = after.subtract(before);
 
@@ -253,13 +253,13 @@
     @Test
     public void testSubtractNewRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats after = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12)
-                .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12)
+                .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
 
         final NetworkStats result = after.subtract(before);
 
@@ -275,11 +275,11 @@
     @Test
     public void testSubtractMissingRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
-                .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0);
+                .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
+                .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0);
 
         final NetworkStats after = new NetworkStats(TEST_START, 1)
-                .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0);
+                .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0);
 
         final NetworkStats result = after.subtract(before);
 
@@ -293,40 +293,40 @@
     @Test
     public void testTotalBytes() throws Exception {
         final NetworkStats iface = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L);
         assertEquals(384L, iface.getTotalBytes());
 
         final NetworkStats uidSet = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
         assertEquals(96L, uidSet.getTotalBytes());
 
         final NetworkStats uidTag = new NetworkStats(TEST_START, 6)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
         assertEquals(64L, uidTag.getTotalBytes());
 
         final NetworkStats uidMetered = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
         assertEquals(96L, uidMetered.getTotalBytes());
 
         final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
         assertEquals(96L, uidRoaming.getTotalBytes());
     }
@@ -343,11 +343,11 @@
     @Test
     public void testGroupedByIfaceAll() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
-                .addEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES,
+                .insertEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L);
         final NetworkStats grouped = uidStats.groupedByIface();
 
@@ -361,19 +361,19 @@
     @Test
     public void testGroupedByIface() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L);
 
         final NetworkStats grouped = uidStats.groupedByIface();
@@ -390,19 +390,19 @@
     @Test
     public void testAddAllValues() {
         final NetworkStats first = new NetworkStats(TEST_START, 5)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
 
         final NetworkStats second = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
 
         first.combineAllValues(second);
@@ -421,19 +421,19 @@
     @Test
     public void testGetTotal() {
         final NetworkStats stats = new NetworkStats(TEST_START, 7)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 512L,32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                         DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L);
 
         assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L);
@@ -459,7 +459,7 @@
         assertEquals(0, after.size());
 
         // Test 1 item stats.
-        before.addEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L);
+        before.insertEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L);
         after = before.clone();
         after.removeUids(new int[0]);
         assertEquals(1, after.size());
@@ -469,12 +469,12 @@
         assertEquals(0, after.size());
 
         // Append remaining test items.
-        before.addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L);
+        before.insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L);
         assertEquals(7, before.size());
 
         // Test remove with empty uid list.
@@ -505,12 +505,12 @@
     @Test
     public void testClone() throws Exception {
         final NetworkStats original = new NetworkStats(TEST_START, 5)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
 
         // make clone and mutate original
         final NetworkStats clone = original.clone();
-        original.addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L);
+        original.insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L);
 
         assertEquals(3, original.size());
         assertEquals(2, clone.size());
@@ -523,8 +523,8 @@
     public void testAddWhenEmpty() throws Exception {
         final NetworkStats red = new NetworkStats(TEST_START, -1);
         final NetworkStats blue = new NetworkStats(TEST_START, 5)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
 
         // We're mostly checking that we don't crash
         red.combineAllValues(blue);
@@ -537,37 +537,37 @@
         final String underlyingIface = "wlan0";
         final int testTag1 = 8888;
         NetworkStats delta = new NetworkStats(TEST_START, 17)
-                .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 39605L, 46L, 12259L, 55L, 0L)
-                .addEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
-                .addEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 72667L, 197L, 43909L, 241L, 0L)
-                .addEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 9297L, 17L, 4128L, 21L, 0L)
                 // VPN package also uses some traffic through unprotected network.
-                .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 4983L, 10L, 1801L, 12L, 0L)
-                .addEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
                 // Tag entries
-                .addEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 21691L, 41L, 13820L, 51L, 0L)
-                .addEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1281L, 2L, 665L, 2L, 0L)
                 // Irrelevant entries
-                .addEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1685L, 5L, 2070L, 6L, 0L)
                 // Underlying Iface entries
-                .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 5178L, 8L, 2139L, 11L, 0L)
-                .addEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
-                        DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
-                .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO,
+                        ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
+                .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 149873L, 287L, 59217L /* smaller than sum(tun0) */,
                         299L /* smaller than sum(tun0) */, 0L)
-                .addEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
-                        DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
+                .insertEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO,
+                        ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
 
         delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
         assertEquals(20, delta.size());
@@ -635,19 +635,19 @@
         final String underlyingIface = "wlan0";
         NetworkStats delta = new NetworkStats(TEST_START, 9)
                 // 2 different apps sent/receive data via tun0.
-                .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L)
-                .addEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 500L, 2L, 200L, 5L, 0L)
                 // VPN package resends data through the tunnel (with exaggerated overhead)
-                .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 240000, 100L, 120000L, 60L, 0L)
                 // 1 app already has some traffic on the underlying interface, the other doesn't yet
-                .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1000L, 10L, 2000L, 20L, 0L)
                 // Traffic through the underlying interface via the vpn app.
                 // This test should redistribute this data correctly.
-                .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L);
 
         delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
@@ -697,9 +697,9 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3);
 
         stats.filter(UID_ALL, INTERFACES_ALL, TAG_ALL);
         assertEquals(3, stats.size());
@@ -724,9 +724,9 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3);
 
         stats.filter(testUid, INTERFACES_ALL, TAG_ALL);
         assertEquals(2, stats.size());
@@ -755,10 +755,10 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 4)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3)
-                .addEntry(entry4);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3)
+                .insertEntry(entry4);
 
         stats.filter(UID_ALL, new String[] { testIf1, testIf2 }, TAG_ALL);
         assertEquals(3, stats.size());
@@ -778,8 +778,8 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(entry1)
-                .addEntry(entry2);
+                .insertEntry(entry1)
+                .insertEntry(entry2);
 
         stats.filter(UID_ALL, new String[] { }, TAG_ALL);
         assertEquals(0, stats.size());
@@ -802,9 +802,9 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3);
 
         stats.filter(UID_ALL, INTERFACES_ALL, testTag);
         assertEquals(2, stats.size());
@@ -831,10 +831,10 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 4)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3)
-                .addEntry(entry4);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3)
+                .insertEntry(entry4);
 
         stats.filterDebugEntries();
 
@@ -891,14 +891,14 @@
                 0 /* operations */);
 
         final NetworkStats statsXt = new NetworkStats(TEST_START, 3)
-                .addEntry(appEntry)
-                .addEntry(xtRootUidEntry)
-                .addEntry(otherEntry);
+                .insertEntry(appEntry)
+                .insertEntry(xtRootUidEntry)
+                .insertEntry(otherEntry);
 
         final NetworkStats statsEbpf = new NetworkStats(TEST_START, 3)
-                .addEntry(appEntry)
-                .addEntry(ebpfRootUidEntry)
-                .addEntry(otherEntry);
+                .insertEntry(appEntry)
+                .insertEntry(ebpfRootUidEntry)
+                .insertEntry(otherEntry);
 
         statsXt.apply464xlatAdjustments(stackedIface, false);
         statsEbpf.apply464xlatAdjustments(stackedIface, true);
@@ -945,8 +945,8 @@
                 0 /* operations */);
 
         NetworkStats stats = new NetworkStats(TEST_START, 2)
-                .addEntry(firstEntry)
-                .addEntry(secondEntry);
+                .insertEntry(firstEntry)
+                .insertEntry(secondEntry);
 
         // Empty map: no adjustment
         stats.apply464xlatAdjustments(new ArrayMap<>(), false);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index c21772a..c8f9375 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -2464,8 +2464,8 @@
             final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
                     mServiceContext, "testFactory", filter);
             // Register the factory and don't be surprised when the default request arrives.
-            testFactory.register();
             testFactory.expectAddRequestsWithScores(0);
+            testFactory.register();
             testFactory.waitForNetworkRequests(1);
 
             testFactory.setScoreFilter(42);
@@ -6851,7 +6851,7 @@
     @Test
     public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception {
         final NetworkCapabilities nc = new NetworkCapabilities();
-        nc.setAdministratorUids(Arrays.asList(Process.myUid()));
+        nc.setAdministratorUids(new int[] {Process.myUid()});
         final NetworkAgentInfo naiWithUid =
                 new NetworkAgentInfo(
                         null, null, null, null, null, nc, 0, mServiceContext, null, null,
@@ -6873,7 +6873,7 @@
     public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception {
         final NetworkCapabilities nc = new NetworkCapabilities();
         nc.setOwnerUid(Process.myUid());
-        nc.setAdministratorUids(Arrays.asList(Process.myUid()));
+        nc.setAdministratorUids(new int[] {Process.myUid()});
         final NetworkAgentInfo naiWithUid =
                 new NetworkAgentInfo(
                         null, null, null, null, null, nc, 0, mServiceContext, null, null,
@@ -6926,7 +6926,7 @@
                 argThat(report -> {
                     final NetworkCapabilities nc = report.getNetworkCapabilities();
                     return nc.getUids() == null
-                            && nc.getAdministratorUids().isEmpty()
+                            && nc.getAdministratorUids().length == 0
                             && nc.getOwnerUid() == Process.INVALID_UID;
                 }));
     }
@@ -6947,7 +6947,7 @@
                 argThat(report -> {
                     final NetworkCapabilities nc = report.getNetworkCapabilities();
                     return nc.getUids() == null
-                            && nc.getAdministratorUids().isEmpty()
+                            && nc.getAdministratorUids().length == 0
                             && nc.getOwnerUid() == Process.INVALID_UID;
                 }));
     }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
index f0e5774..a6f7a36 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -240,7 +240,7 @@
 
         // Baseline
         NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
+                .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
         NetworkStats uidSnapshot = null;
 
         mStatsObservers.updateStats(
@@ -264,14 +264,14 @@
 
         // Baseline
         NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
+                .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
         NetworkStats uidSnapshot = null;
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L);
+                .insertEntry(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
@@ -294,14 +294,14 @@
 
         // Baseline
         NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
+                .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
         NetworkStats uidSnapshot = null;
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L,
+                .insertEntry(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L,
                         BASE_BYTES + THRESHOLD_BYTES, 22L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
@@ -326,14 +326,14 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
@@ -359,14 +359,14 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
@@ -391,14 +391,14 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
@@ -424,14 +424,14 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
+                .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
                         ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
+                .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
                         ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 36deca3..b346c92 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -263,7 +263,7 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
+                .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -276,7 +276,7 @@
         incrementCurrentTime(DAY_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
+                .insertEntry(TEST_IFACE, 4096L, 4L, 8192L, 8L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -306,13 +306,13 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L));
+                .insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
         mService.setUidForeground(UID_RED, false);
         mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
         mService.setUidForeground(UID_RED, true);
@@ -375,7 +375,7 @@
         incrementCurrentTime(2 * HOUR_IN_MILLIS);
         expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
+                .insertEntry(TEST_IFACE, 512L, 4L, 512L, 4L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -415,11 +415,11 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
+                .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 10);
 
         forcePollAndWaitForIdle();
@@ -437,11 +437,11 @@
         expectDefaultSettings();
         states = new NetworkState[] {buildMobile3gState(IMSI_2)};
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
+                .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
 
         mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
         forcePollAndWaitForIdle();
@@ -451,12 +451,12 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L));
+                .insertEntry(TEST_IFACE, 2176L, 17L, 1536L, 12L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
         mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
 
         forcePollAndWaitForIdle();
@@ -488,12 +488,13 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
+                .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
-                .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+                        4096L, 258L, 512L, 32L, 0L)
+                .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
         mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
 
         forcePollAndWaitForIdle();
@@ -509,12 +510,13 @@
         // special "removed" bucket.
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
+                .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
-                .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+                        4096L, 258L, 512L, 32L, 0L)
+                .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
         final Intent intent = new Intent(ACTION_UID_REMOVED);
         intent.putExtra(EXTRA_UID, UID_BLUE);
         mServiceContext.sendBroadcast(intent);
@@ -546,8 +548,8 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 5);
 
         forcePollAndWaitForIdle();
@@ -562,8 +564,8 @@
         states = new NetworkState[] {buildMobile4gState(TEST_IFACE2)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
 
         mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
         forcePollAndWaitForIdle();
@@ -574,10 +576,10 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
-                .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
+                .insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
         mService.incrementOperationCount(UID_RED, 0xFAAD, 5);
 
         forcePollAndWaitForIdle();
@@ -601,9 +603,9 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
 
         forcePollAndWaitForIdle();
@@ -618,9 +620,10 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+                        2048L, 16L, 1024L, 8L, 0L));
         forcePollAndWaitForIdle();
 
         // first verify entire history present
@@ -664,9 +667,9 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3));
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3));
         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
 
         NetworkStats stats = mService.getDetailedUidStats(INTERFACES_ALL);
@@ -714,11 +717,11 @@
                 .thenReturn(augmentedIfaceFilter);
         when(mStatsFactory.readNetworkStatsDetail(eq(UID_ALL), any(), eq(TAG_ALL)))
                 .thenReturn(new NetworkStats(getElapsedRealtime(), 1)
-                        .addEntry(uidStats));
+                        .insertEntry(uidStats));
         when(mNetManager.getNetworkStatsTethering(STATS_PER_UID))
                 .thenReturn(new NetworkStats(getElapsedRealtime(), 2)
-                        .addEntry(tetheredStats1)
-                        .addEntry(tetheredStats2));
+                        .insertEntry(tetheredStats1)
+                        .insertEntry(tetheredStats2));
 
         NetworkStats stats = mService.getDetailedUidStats(ifaceFilter);
 
@@ -755,8 +758,8 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
 
         forcePollAndWaitForIdle();
@@ -770,10 +773,10 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
         mService.setUidForeground(UID_RED, true);
         mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
 
@@ -814,9 +817,9 @@
         // and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer.
         // We layer them on top by inspecting the iface properties.
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
 
@@ -853,9 +856,9 @@
         // ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it
         // on top by inspecting the iface properties.
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
                         DEFAULT_NETWORK_YES,  128L, 2L, 128L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L));
         forcePollAndWaitForIdle();
 
@@ -888,17 +891,17 @@
 
         // Traffic seen by kernel counters (includes software tethering).
         final NetworkStats ifaceStats = new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 1536L, 12L, 384L, 3L);
+                .insertEntry(TEST_IFACE, 1536L, 12L, 384L, 3L);
         // Hardware tethering traffic, not seen by kernel counters.
         final NetworkStats tetherStatsHardware = new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 512L, 4L, 128L, 1L);
+                .insertEntry(TEST_IFACE, 512L, 4L, 128L, 1L);
 
         // Traffic for UID_RED.
         final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
         // All tethering traffic, both hardware and software.
         final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
+                .insertEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
                         0L);
 
         expectNetworkStatsSummary(ifaceStats, tetherStatsHardware);
@@ -957,7 +960,7 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
+                .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -972,7 +975,7 @@
         incrementCurrentTime(DAY_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
+                .insertEntry(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -1026,18 +1029,18 @@
         mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // Verifies that one requestStatsUpdate will be called during iface update.
-        provider.expectStatsUpdate(0 /* unused */);
+        provider.expectOnRequestStatsUpdate(0 /* unused */);
 
         // Create some initial traffic and report to the service.
         incrementCurrentTime(HOUR_IN_MILLIS);
         final NetworkStats expectedStats = new NetworkStats(0L, 1)
-                .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
                         TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
                         128L, 2L, 128L, 2L, 1L))
-                .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
                         0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
                         64L, 1L, 64L, 1L, 1L));
-        cb.onStatsUpdated(0 /* unused */, expectedStats, expectedStats);
+        cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats);
 
         // Make another empty mutable stats object. This is necessary since the new NetworkStats
         // object will be used to compare with the old one in NetworkStatsRecoder, two of them
@@ -1047,8 +1050,8 @@
         forcePollAndWaitForIdle();
 
         // Verifies that one requestStatsUpdate and setAlert will be called during polling.
-        provider.expectStatsUpdate(0 /* unused */);
-        provider.expectSetAlert(MB_IN_BYTES);
+        provider.expectOnRequestStatsUpdate(0 /* unused */);
+        provider.expectOnSetAlert(MB_IN_BYTES);
 
         // Verifies that service recorded history, does not verify uid tag part.
         assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
@@ -1082,13 +1085,13 @@
         assertNotNull(cb);
 
         // Simulates alert quota of the provider has been reached.
-        cb.onAlertReached();
+        cb.notifyAlertReached();
         HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
 
         // Verifies that polling is triggered by alert reached.
-        provider.expectStatsUpdate(0 /* unused */);
+        provider.expectOnRequestStatsUpdate(0 /* unused */);
         // Verifies that global alert will be re-armed.
-        provider.expectSetAlert(MB_IN_BYTES);
+        provider.expectOnSetAlert(MB_IN_BYTES);
     }
 
     private static File getBaseDir(File statsDir) {
diff --git a/wifi/Android.bp b/wifi/Android.bp
index f4d2881..70c2741 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -72,8 +72,7 @@
 // classes before they are renamed.
 java_library {
     name: "framework-wifi-pre-jarjar",
-    // TODO(b/146757305): sdk_version should be "module_lib_current"
-    sdk_version: "core_current",
+    sdk_version: "module_current",
     static_libs: [
         "framework-wifi-util-lib",
         "android.hardware.wifi-V1.0-java-constants",
@@ -83,9 +82,6 @@
         "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
         "unsupportedappusage-annotation", // for dalvik.annotation.compat.UnsupportedAppUsage
         "framework-telephony-stubs",
-        // TODO(b/146757305): should be unnecessary once
-        // sdk_version="module_lib_current"
-        "android_system_stubs_current",
     ],
     srcs: [
         ":framework-wifi-updatable-sources",
@@ -98,21 +94,12 @@
         "//frameworks/opt/net/wifi/service",
         "//frameworks/opt/net/wifi/tests/wifitests",
     ],
-
-    // TODO(b/146757305): should be unnecessary once
-    // sdk_version="module_lib_current"
-    aidl: {
-        include_dirs: [
-            "frameworks/base/core/java",
-        ],
-    },
 }
 
 // post-jarjar version of framework-wifi
 java_library {
     name: "framework-wifi",
-    // TODO(b/146757305): sdk_version should be "module_lib_current"
-    sdk_version: "core_current",
+    sdk_version: "module_current",
     static_libs: [
         "framework-wifi-pre-jarjar",
     ],
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
new file mode 100644
index 0000000..1b62ec1
--- /dev/null
+++ b/wifi/api/current.txt
@@ -0,0 +1,1199 @@
+// Signature format: 2.0
+package android.net.wifi {
+
+  public abstract class EasyConnectStatusCallback {
+    field public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe
+    field public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5; // 0xfffffffb
+    field public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10; // 0xfffffff6
+    field public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4; // 0xfffffffc
+    field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11; // 0xfffffff5
+    field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12; // 0xfffffff4
+    field public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7; // 0xfffffff9
+    field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; // 0xfffffff7
+    field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1; // 0xffffffff
+    field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE = -3; // 0xfffffffd
+    field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8; // 0xfffffff8
+    field public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6; // 0xfffffffa
+  }
+
+  public class ScanResult implements android.os.Parcelable {
+    ctor public ScanResult(@NonNull android.net.wifi.ScanResult);
+    ctor public ScanResult();
+    method public int describeContents();
+    method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getInformationElements();
+    method public int getWifiStandard();
+    method public boolean is80211mcResponder();
+    method public boolean isPasspointNetwork();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public String BSSID;
+    field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
+    field public static final int CHANNEL_WIDTH_20MHZ = 0; // 0x0
+    field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
+    field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
+    field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.ScanResult> CREATOR;
+    field public String SSID;
+    field public static final int WIFI_STANDARD_11AC = 5; // 0x5
+    field public static final int WIFI_STANDARD_11AX = 6; // 0x6
+    field public static final int WIFI_STANDARD_11N = 4; // 0x4
+    field public static final int WIFI_STANDARD_LEGACY = 1; // 0x1
+    field public static final int WIFI_STANDARD_UNKNOWN = 0; // 0x0
+    field public String capabilities;
+    field public int centerFreq0;
+    field public int centerFreq1;
+    field public int channelWidth;
+    field public int frequency;
+    field public int level;
+    field public CharSequence operatorFriendlyName;
+    field public long timestamp;
+    field public CharSequence venueName;
+  }
+
+  public static class ScanResult.InformationElement {
+    ctor public ScanResult.InformationElement(@NonNull android.net.wifi.ScanResult.InformationElement);
+    method @NonNull public java.nio.ByteBuffer getBytes();
+    method public int getId();
+    method public int getIdExt();
+  }
+
+  public final class SoftApConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.net.MacAddress getBssid();
+    method @Nullable public String getPassphrase();
+    method public int getSecurityType();
+    method @Nullable public String getSsid();
+    method public boolean isHiddenSsid();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApConfiguration> CREATOR;
+    field public static final int SECURITY_TYPE_OPEN = 0; // 0x0
+    field public static final int SECURITY_TYPE_WPA2_PSK = 1; // 0x1
+    field public static final int SECURITY_TYPE_WPA3_SAE = 3; // 0x3
+    field public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; // 0x2
+  }
+
+  public enum SupplicantState implements android.os.Parcelable {
+    method public int describeContents();
+    method public static boolean isValidState(android.net.wifi.SupplicantState);
+    method public void writeToParcel(android.os.Parcel, int);
+    enum_constant public static final android.net.wifi.SupplicantState ASSOCIATED;
+    enum_constant public static final android.net.wifi.SupplicantState ASSOCIATING;
+    enum_constant public static final android.net.wifi.SupplicantState AUTHENTICATING;
+    enum_constant public static final android.net.wifi.SupplicantState COMPLETED;
+    enum_constant public static final android.net.wifi.SupplicantState DISCONNECTED;
+    enum_constant public static final android.net.wifi.SupplicantState DORMANT;
+    enum_constant public static final android.net.wifi.SupplicantState FOUR_WAY_HANDSHAKE;
+    enum_constant public static final android.net.wifi.SupplicantState GROUP_HANDSHAKE;
+    enum_constant public static final android.net.wifi.SupplicantState INACTIVE;
+    enum_constant public static final android.net.wifi.SupplicantState INTERFACE_DISABLED;
+    enum_constant public static final android.net.wifi.SupplicantState INVALID;
+    enum_constant public static final android.net.wifi.SupplicantState SCANNING;
+    enum_constant public static final android.net.wifi.SupplicantState UNINITIALIZED;
+  }
+
+  @Deprecated public class WifiConfiguration implements android.os.Parcelable {
+    ctor @Deprecated public WifiConfiguration();
+    ctor @Deprecated public WifiConfiguration(@NonNull android.net.wifi.WifiConfiguration);
+    method public int describeContents();
+    method @Deprecated public android.net.ProxyInfo getHttpProxy();
+    method @Deprecated @NonNull public String getKey();
+    method @Deprecated @NonNull public android.net.MacAddress getRandomizedMacAddress();
+    method @Deprecated public boolean isPasspoint();
+    method @Deprecated public void setHttpProxy(android.net.ProxyInfo);
+    method @Deprecated public void setSecurityParams(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @Deprecated public String BSSID;
+    field @Deprecated public String FQDN;
+    field @Deprecated public static final int SECURITY_TYPE_EAP = 3; // 0x3
+    field @Deprecated public static final int SECURITY_TYPE_EAP_SUITE_B = 5; // 0x5
+    field @Deprecated public static final int SECURITY_TYPE_OPEN = 0; // 0x0
+    field @Deprecated public static final int SECURITY_TYPE_OWE = 6; // 0x6
+    field @Deprecated public static final int SECURITY_TYPE_PSK = 2; // 0x2
+    field @Deprecated public static final int SECURITY_TYPE_SAE = 4; // 0x4
+    field @Deprecated public static final int SECURITY_TYPE_WAPI_CERT = 8; // 0x8
+    field @Deprecated public static final int SECURITY_TYPE_WAPI_PSK = 7; // 0x7
+    field @Deprecated public static final int SECURITY_TYPE_WEP = 1; // 0x1
+    field @Deprecated public String SSID;
+    field @Deprecated @NonNull public java.util.BitSet allowedAuthAlgorithms;
+    field @Deprecated @NonNull public java.util.BitSet allowedGroupCiphers;
+    field @Deprecated @NonNull public java.util.BitSet allowedGroupManagementCiphers;
+    field @Deprecated @NonNull public java.util.BitSet allowedKeyManagement;
+    field @Deprecated @NonNull public java.util.BitSet allowedPairwiseCiphers;
+    field @Deprecated @NonNull public java.util.BitSet allowedProtocols;
+    field @Deprecated @NonNull public java.util.BitSet allowedSuiteBCiphers;
+    field @Deprecated public android.net.wifi.WifiEnterpriseConfig enterpriseConfig;
+    field @Deprecated public boolean hiddenSSID;
+    field @Deprecated public boolean isHomeProviderNetwork;
+    field @Deprecated public int networkId;
+    field @Deprecated public String preSharedKey;
+    field @Deprecated public int priority;
+    field @Deprecated public String providerFriendlyName;
+    field @Deprecated public long[] roamingConsortiumIds;
+    field @Deprecated public int status;
+    field @Deprecated public String[] wepKeys;
+    field @Deprecated public int wepTxKeyIndex;
+  }
+
+  @Deprecated public static class WifiConfiguration.AuthAlgorithm {
+    field @Deprecated public static final int LEAP = 2; // 0x2
+    field @Deprecated public static final int OPEN = 0; // 0x0
+    field @Deprecated public static final int SAE = 3; // 0x3
+    field @Deprecated public static final int SHARED = 1; // 0x1
+    field @Deprecated public static final String[] strings;
+    field @Deprecated public static final String varName = "auth_alg";
+  }
+
+  @Deprecated public static class WifiConfiguration.GroupCipher {
+    field @Deprecated public static final int CCMP = 3; // 0x3
+    field @Deprecated public static final int GCMP_256 = 5; // 0x5
+    field @Deprecated public static final int SMS4 = 6; // 0x6
+    field @Deprecated public static final int TKIP = 2; // 0x2
+    field @Deprecated public static final int WEP104 = 1; // 0x1
+    field @Deprecated public static final int WEP40 = 0; // 0x0
+    field @Deprecated public static final String[] strings;
+    field @Deprecated public static final String varName = "group";
+  }
+
+  @Deprecated public static class WifiConfiguration.GroupMgmtCipher {
+    field @Deprecated public static final int BIP_CMAC_256 = 0; // 0x0
+    field @Deprecated public static final int BIP_GMAC_128 = 1; // 0x1
+    field @Deprecated public static final int BIP_GMAC_256 = 2; // 0x2
+  }
+
+  @Deprecated public static class WifiConfiguration.KeyMgmt {
+    field @Deprecated public static final int IEEE8021X = 3; // 0x3
+    field @Deprecated public static final int NONE = 0; // 0x0
+    field @Deprecated public static final int OWE = 9; // 0x9
+    field @Deprecated public static final int SAE = 8; // 0x8
+    field @Deprecated public static final int SUITE_B_192 = 10; // 0xa
+    field @Deprecated public static final int WPA_EAP = 2; // 0x2
+    field @Deprecated public static final int WPA_PSK = 1; // 0x1
+    field @Deprecated public static final String[] strings;
+    field @Deprecated public static final String varName = "key_mgmt";
+  }
+
+  @Deprecated public static class WifiConfiguration.PairwiseCipher {
+    field @Deprecated public static final int CCMP = 2; // 0x2
+    field @Deprecated public static final int GCMP_256 = 3; // 0x3
+    field @Deprecated public static final int NONE = 0; // 0x0
+    field @Deprecated public static final int SMS4 = 4; // 0x4
+    field @Deprecated public static final int TKIP = 1; // 0x1
+    field @Deprecated public static final String[] strings;
+    field @Deprecated public static final String varName = "pairwise";
+  }
+
+  @Deprecated public static class WifiConfiguration.Protocol {
+    field @Deprecated public static final int RSN = 1; // 0x1
+    field @Deprecated public static final int WAPI = 3; // 0x3
+    field @Deprecated public static final int WPA = 0; // 0x0
+    field @Deprecated public static final String[] strings;
+    field @Deprecated public static final String varName = "proto";
+  }
+
+  @Deprecated public static class WifiConfiguration.Status {
+    field @Deprecated public static final int CURRENT = 0; // 0x0
+    field @Deprecated public static final int DISABLED = 1; // 0x1
+    field @Deprecated public static final int ENABLED = 2; // 0x2
+    field @Deprecated public static final String[] strings;
+  }
+
+  public class WifiEnterpriseConfig implements android.os.Parcelable {
+    ctor public WifiEnterpriseConfig();
+    ctor public WifiEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig);
+    method public int describeContents();
+    method public String getAltSubjectMatch();
+    method public String getAnonymousIdentity();
+    method @Nullable public java.security.cert.X509Certificate getCaCertificate();
+    method @Nullable public java.security.cert.X509Certificate[] getCaCertificates();
+    method public java.security.cert.X509Certificate getClientCertificate();
+    method @Nullable public java.security.cert.X509Certificate[] getClientCertificateChain();
+    method @Nullable public java.security.PrivateKey getClientPrivateKey();
+    method public String getDomainSuffixMatch();
+    method public int getEapMethod();
+    method public String getIdentity();
+    method public String getPassword();
+    method public int getPhase2Method();
+    method public String getPlmn();
+    method public String getRealm();
+    method @Deprecated public String getSubjectMatch();
+    method public boolean isAuthenticationSimBased();
+    method public void setAltSubjectMatch(String);
+    method public void setAnonymousIdentity(String);
+    method public void setCaCertificate(@Nullable java.security.cert.X509Certificate);
+    method public void setCaCertificates(@Nullable java.security.cert.X509Certificate[]);
+    method public void setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate);
+    method public void setClientKeyEntryWithCertificateChain(java.security.PrivateKey, java.security.cert.X509Certificate[]);
+    method public void setDomainSuffixMatch(String);
+    method public void setEapMethod(int);
+    method public void setIdentity(String);
+    method public void setPassword(String);
+    method public void setPhase2Method(int);
+    method public void setPlmn(String);
+    method public void setRealm(String);
+    method @Deprecated public void setSubjectMatch(String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiEnterpriseConfig> CREATOR;
+    field public static final String EXTRA_WAPI_AS_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_AS_CERTIFICATE_DATA";
+    field public static final String EXTRA_WAPI_AS_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_AS_CERTIFICATE_NAME";
+    field public static final String EXTRA_WAPI_USER_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_DATA";
+    field public static final String EXTRA_WAPI_USER_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_NAME";
+    field public static final String WAPI_AS_CERTIFICATE = "WAPIAS_";
+    field public static final String WAPI_USER_CERTIFICATE = "WAPIUSR_";
+  }
+
+  public static final class WifiEnterpriseConfig.Eap {
+    field public static final int AKA = 5; // 0x5
+    field public static final int AKA_PRIME = 6; // 0x6
+    field public static final int NONE = -1; // 0xffffffff
+    field public static final int PEAP = 0; // 0x0
+    field public static final int PWD = 3; // 0x3
+    field public static final int SIM = 4; // 0x4
+    field public static final int TLS = 1; // 0x1
+    field public static final int TTLS = 2; // 0x2
+    field public static final int UNAUTH_TLS = 7; // 0x7
+    field public static final int WAPI_CERT = 8; // 0x8
+  }
+
+  public static final class WifiEnterpriseConfig.Phase2 {
+    field public static final int AKA = 6; // 0x6
+    field public static final int AKA_PRIME = 7; // 0x7
+    field public static final int GTC = 4; // 0x4
+    field public static final int MSCHAP = 2; // 0x2
+    field public static final int MSCHAPV2 = 3; // 0x3
+    field public static final int NONE = 0; // 0x0
+    field public static final int PAP = 1; // 0x1
+    field public static final int SIM = 5; // 0x5
+  }
+
+  public class WifiInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public String getBSSID();
+    method public static android.net.NetworkInfo.DetailedState getDetailedStateOf(android.net.wifi.SupplicantState);
+    method public int getFrequency();
+    method public boolean getHiddenSSID();
+    method public int getIpAddress();
+    method public int getLinkSpeed();
+    method public String getMacAddress();
+    method public int getMaxSupportedRxLinkSpeedMbps();
+    method public int getMaxSupportedTxLinkSpeedMbps();
+    method public int getNetworkId();
+    method @Nullable public String getPasspointFqdn();
+    method @Nullable public String getPasspointProviderFriendlyName();
+    method public int getRssi();
+    method @IntRange(from=0xffffffff) public int getRxLinkSpeedMbps();
+    method public String getSSID();
+    method public android.net.wifi.SupplicantState getSupplicantState();
+    method @IntRange(from=0xffffffff) public int getTxLinkSpeedMbps();
+    method public int getWifiStandard();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final String FREQUENCY_UNITS = "MHz";
+    field public static final String LINK_SPEED_UNITS = "Mbps";
+    field public static final int LINK_SPEED_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class WifiInfo.Builder {
+    ctor public WifiInfo.Builder();
+    method @NonNull public android.net.wifi.WifiInfo build();
+    method @NonNull public android.net.wifi.WifiInfo.Builder setBssid(@NonNull String);
+    method @NonNull public android.net.wifi.WifiInfo.Builder setNetworkId(int);
+    method @NonNull public android.net.wifi.WifiInfo.Builder setRssi(int);
+    method @NonNull public android.net.wifi.WifiInfo.Builder setSsid(@NonNull byte[]);
+  }
+
+  public class WifiManager {
+    method @Deprecated public int addNetwork(android.net.wifi.WifiConfiguration);
+    method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int addNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
+    method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public void addSuggestionConnectionStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
+    method @Deprecated public static int calculateSignalLevel(int, int);
+    method @IntRange(from=0) public int calculateSignalLevel(int);
+    method @Deprecated public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
+    method public static int compareSignalLevel(int, int);
+    method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(String);
+    method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, String);
+    method @Deprecated public android.net.wifi.WifiManager.WifiLock createWifiLock(String);
+    method @Deprecated public boolean disableNetwork(int);
+    method @Deprecated public boolean disconnect();
+    method @Deprecated public boolean enableNetwork(int, boolean);
+    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
+    method public android.net.wifi.WifiInfo getConnectionInfo();
+    method public android.net.DhcpInfo getDhcpInfo();
+    method public int getMaxNumberOfNetworkSuggestionsPerApp();
+    method @IntRange(from=0) public int getMaxSignalLevel();
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiNetworkSuggestion> getNetworkSuggestions();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
+    method public java.util.List<android.net.wifi.ScanResult> getScanResults();
+    method public int getWifiState();
+    method public boolean is5GHzBandSupported();
+    method public boolean is6GHzBandSupported();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isAutoWakeupEnabled();
+    method @Deprecated public boolean isDeviceToApRttSupported();
+    method public boolean isEasyConnectSupported();
+    method public boolean isEnhancedOpenSupported();
+    method public boolean isEnhancedPowerReportingSupported();
+    method public boolean isP2pSupported();
+    method public boolean isPreferredNetworkOffloadSupported();
+    method @Deprecated public boolean isScanAlwaysAvailable();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isScanThrottleEnabled();
+    method public boolean isStaApConcurrencySupported();
+    method public boolean isTdlsSupported();
+    method public boolean isWapiSupported();
+    method public boolean isWifiEnabled();
+    method public boolean isWifiStandardSupported(int);
+    method public boolean isWpa3SaeSupported();
+    method public boolean isWpa3SuiteBSupported();
+    method @Deprecated public boolean pingSupplicant();
+    method @Deprecated public boolean reassociate();
+    method @Deprecated public boolean reconnect();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void registerScanResultsCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.ScanResultsCallback);
+    method @Deprecated public boolean removeNetwork(int);
+    method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int removeNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>);
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}) public void removePasspointConfiguration(String);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionConnectionStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
+    method @Deprecated public boolean saveConfiguration();
+    method public void setTdlsEnabled(java.net.InetAddress, boolean);
+    method public void setTdlsEnabledWithMacAddress(String, boolean);
+    method @Deprecated public boolean setWifiEnabled(boolean);
+    method @RequiresPermission(allOf={android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, @Nullable android.os.Handler);
+    method @Deprecated public boolean startScan();
+    method @Deprecated public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void unregisterScanResultsCallback(@NonNull android.net.wifi.WifiManager.ScanResultsCallback);
+    method @Deprecated public int updateNetwork(android.net.wifi.WifiConfiguration);
+    field public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
+    field public static final String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
+    field public static final String ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION = "android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION";
+    field public static final String ACTION_WIFI_SCAN_AVAILABILITY_CHANGED = "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED";
+    field @Deprecated public static final int ERROR_AUTHENTICATING = 1; // 0x1
+    field @Deprecated public static final String EXTRA_BSSID = "bssid";
+    field public static final String EXTRA_NETWORK_INFO = "networkInfo";
+    field public static final String EXTRA_NETWORK_SUGGESTION = "android.net.wifi.extra.NETWORK_SUGGESTION";
+    field public static final String EXTRA_NEW_RSSI = "newRssi";
+    field @Deprecated public static final String EXTRA_NEW_STATE = "newState";
+    field public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
+    field public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated";
+    field public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE";
+    field @Deprecated public static final String EXTRA_SUPPLICANT_CONNECTED = "connected";
+    field @Deprecated public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
+    field @Deprecated public static final String EXTRA_WIFI_INFO = "wifiInfo";
+    field public static final String EXTRA_WIFI_STATE = "wifi_state";
+    field public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
+    field public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
+    field public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
+    field public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
+    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3; // 0x3
+    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4; // 0x4
+    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7; // 0x7
+    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6; // 0x6
+    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2; // 0x2
+    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; // 0x1
+    field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; // 0x5
+    field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
+    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1; // 0x1
+    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2; // 0x2
+    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3; // 0x3
+    field public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0; // 0x0
+    field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
+    field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
+    field public static final String UNKNOWN_SSID = "<unknown ssid>";
+    field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1
+    field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3
+    field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4
+    field @Deprecated public static final int WIFI_MODE_SCAN_ONLY = 2; // 0x2
+    field public static final String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED";
+    field public static final int WIFI_STATE_DISABLED = 1; // 0x1
+    field public static final int WIFI_STATE_DISABLING = 0; // 0x0
+    field public static final int WIFI_STATE_ENABLED = 3; // 0x3
+    field public static final int WIFI_STATE_ENABLING = 2; // 0x2
+    field public static final int WIFI_STATE_UNKNOWN = 4; // 0x4
+    field @Deprecated public static final int WPS_AUTH_FAILURE = 6; // 0x6
+    field @Deprecated public static final int WPS_OVERLAP_ERROR = 3; // 0x3
+    field @Deprecated public static final int WPS_TIMED_OUT = 7; // 0x7
+    field @Deprecated public static final int WPS_TKIP_ONLY_PROHIBITED = 5; // 0x5
+    field @Deprecated public static final int WPS_WEP_PROHIBITED = 4; // 0x4
+  }
+
+  public static class WifiManager.LocalOnlyHotspotCallback {
+    ctor public WifiManager.LocalOnlyHotspotCallback();
+    method public void onFailed(int);
+    method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
+    method public void onStopped();
+    field public static final int ERROR_GENERIC = 2; // 0x2
+    field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
+    field public static final int ERROR_NO_CHANNEL = 1; // 0x1
+    field public static final int ERROR_TETHERING_DISALLOWED = 4; // 0x4
+  }
+
+  public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
+    method public void close();
+    method @NonNull public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
+    method @Deprecated @Nullable public android.net.wifi.WifiConfiguration getWifiConfiguration();
+  }
+
+  public class WifiManager.MulticastLock {
+    method public void acquire();
+    method public boolean isHeld();
+    method public void release();
+    method public void setReferenceCounted(boolean);
+  }
+
+  public abstract static class WifiManager.ScanResultsCallback {
+    ctor public WifiManager.ScanResultsCallback();
+    method public abstract void onScanResultsAvailable();
+  }
+
+  public static interface WifiManager.SuggestionConnectionStatusListener {
+    method public void onConnectionStatus(@NonNull android.net.wifi.WifiNetworkSuggestion, int);
+  }
+
+  public class WifiManager.WifiLock {
+    method public void acquire();
+    method public boolean isHeld();
+    method public void release();
+    method public void setReferenceCounted(boolean);
+    method public void setWorkSource(android.os.WorkSource);
+  }
+
+  @Deprecated public abstract static class WifiManager.WpsCallback {
+    ctor @Deprecated public WifiManager.WpsCallback();
+    method @Deprecated public abstract void onFailed(int);
+    method @Deprecated public abstract void onStarted(String);
+    method @Deprecated public abstract void onSucceeded();
+  }
+
+  public final class WifiNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSpecifier> CREATOR;
+  }
+
+  public static final class WifiNetworkSpecifier.Builder {
+    ctor public WifiNetworkSpecifier.Builder();
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier build();
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssid(@NonNull android.net.MacAddress);
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssidPattern(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsEnhancedOpen(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsHiddenSsid(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsid(@NonNull String);
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsidPattern(@NonNull android.os.PatternMatcher);
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2Passphrase(@NonNull String);
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
+    method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa3Passphrase(@NonNull String);
+  }
+
+  public final class WifiNetworkSuggestion implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.net.MacAddress getBssid();
+    method @Nullable public android.net.wifi.WifiEnterpriseConfig getEnterpriseConfig();
+    method @Nullable public String getPassphrase();
+    method @Nullable public android.net.wifi.hotspot2.PasspointConfiguration getPasspointConfig();
+    method @IntRange(from=0) public int getPriority();
+    method @Nullable public String getSsid();
+    method public boolean isAppInteractionRequired();
+    method public boolean isCredentialSharedWithUser();
+    method public boolean isEnhancedOpen();
+    method public boolean isHiddenSsid();
+    method public boolean isInitialAutojoinEnabled();
+    method public boolean isMetered();
+    method public boolean isUntrusted();
+    method public boolean isUserInteractionRequired();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSuggestion> CREATOR;
+  }
+
+  public static final class WifiNetworkSuggestion.Builder {
+    ctor public WifiNetworkSuggestion.Builder();
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion build();
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setBssid(@NonNull android.net.MacAddress);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setCredentialSharedWithUser(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsAppInteractionRequired(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsEnhancedOpen(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsHiddenSsid(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsInitialAutojoinEnabled(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsMetered(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsUserInteractionRequired(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPasspointConfig(@NonNull android.net.wifi.hotspot2.PasspointConfiguration);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(@IntRange(from=0) int);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setSsid(@NonNull String);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setUntrusted(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiEnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiPassphrase(@NonNull String);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2Passphrase(@NonNull String);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa3Passphrase(@NonNull String);
+  }
+
+  public class WpsInfo implements android.os.Parcelable {
+    ctor public WpsInfo();
+    ctor public WpsInfo(android.net.wifi.WpsInfo);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public String BSSID;
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WpsInfo> CREATOR;
+    field public static final int DISPLAY = 1; // 0x1
+    field public static final int INVALID = 4; // 0x4
+    field public static final int KEYPAD = 2; // 0x2
+    field public static final int LABEL = 3; // 0x3
+    field public static final int PBC = 0; // 0x0
+    field public String pin;
+    field public int setup;
+  }
+
+}
+
+package android.net.wifi.aware {
+
+  public class AttachCallback {
+    ctor public AttachCallback();
+    method public void onAttachFailed();
+    method public void onAttached(android.net.wifi.aware.WifiAwareSession);
+  }
+
+  public final class Characteristics implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getMaxMatchFilterLength();
+    method public int getMaxServiceNameLength();
+    method public int getMaxServiceSpecificInfoLength();
+    method public int getSupportedCipherSuites();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.Characteristics> CREATOR;
+    field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1; // 0x1
+    field public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 2; // 0x2
+  }
+
+  public class DiscoverySession implements java.lang.AutoCloseable {
+    method public void close();
+    method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierOpen(@NonNull android.net.wifi.aware.PeerHandle);
+    method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(@NonNull android.net.wifi.aware.PeerHandle, @NonNull String);
+    method public void sendMessage(@NonNull android.net.wifi.aware.PeerHandle, int, @Nullable byte[]);
+  }
+
+  public class DiscoverySessionCallback {
+    ctor public DiscoverySessionCallback();
+    method public void onMessageReceived(android.net.wifi.aware.PeerHandle, byte[]);
+    method public void onMessageSendFailed(int);
+    method public void onMessageSendSucceeded(int);
+    method public void onPublishStarted(@NonNull android.net.wifi.aware.PublishDiscoverySession);
+    method public void onServiceDiscovered(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>);
+    method public void onServiceDiscoveredWithinRange(android.net.wifi.aware.PeerHandle, byte[], java.util.List<byte[]>, int);
+    method public void onSessionConfigFailed();
+    method public void onSessionConfigUpdated();
+    method public void onSessionTerminated();
+    method public void onSubscribeStarted(@NonNull android.net.wifi.aware.SubscribeDiscoverySession);
+  }
+
+  public class IdentityChangedListener {
+    ctor public IdentityChangedListener();
+    method public void onIdentityChanged(byte[]);
+  }
+
+  public final class ParcelablePeerHandle extends android.net.wifi.aware.PeerHandle implements android.os.Parcelable {
+    ctor public ParcelablePeerHandle(@NonNull android.net.wifi.aware.PeerHandle);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.ParcelablePeerHandle> CREATOR;
+  }
+
+  public class PeerHandle {
+  }
+
+  public final class PublishConfig implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.PublishConfig> CREATOR;
+    field public static final int PUBLISH_TYPE_SOLICITED = 1; // 0x1
+    field public static final int PUBLISH_TYPE_UNSOLICITED = 0; // 0x0
+  }
+
+  public static final class PublishConfig.Builder {
+    ctor public PublishConfig.Builder();
+    method public android.net.wifi.aware.PublishConfig build();
+    method public android.net.wifi.aware.PublishConfig.Builder setMatchFilter(@Nullable java.util.List<byte[]>);
+    method public android.net.wifi.aware.PublishConfig.Builder setPublishType(int);
+    method public android.net.wifi.aware.PublishConfig.Builder setRangingEnabled(boolean);
+    method public android.net.wifi.aware.PublishConfig.Builder setServiceName(@NonNull String);
+    method public android.net.wifi.aware.PublishConfig.Builder setServiceSpecificInfo(@Nullable byte[]);
+    method public android.net.wifi.aware.PublishConfig.Builder setTerminateNotificationEnabled(boolean);
+    method public android.net.wifi.aware.PublishConfig.Builder setTtlSec(int);
+  }
+
+  public class PublishDiscoverySession extends android.net.wifi.aware.DiscoverySession {
+    method public void updatePublish(@NonNull android.net.wifi.aware.PublishConfig);
+  }
+
+  public final class SubscribeConfig implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.SubscribeConfig> CREATOR;
+    field public static final int SUBSCRIBE_TYPE_ACTIVE = 1; // 0x1
+    field public static final int SUBSCRIBE_TYPE_PASSIVE = 0; // 0x0
+  }
+
+  public static final class SubscribeConfig.Builder {
+    ctor public SubscribeConfig.Builder();
+    method public android.net.wifi.aware.SubscribeConfig build();
+    method public android.net.wifi.aware.SubscribeConfig.Builder setMatchFilter(@Nullable java.util.List<byte[]>);
+    method public android.net.wifi.aware.SubscribeConfig.Builder setMaxDistanceMm(int);
+    method public android.net.wifi.aware.SubscribeConfig.Builder setMinDistanceMm(int);
+    method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(@NonNull String);
+    method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(@Nullable byte[]);
+    method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
+    method public android.net.wifi.aware.SubscribeConfig.Builder setTerminateNotificationEnabled(boolean);
+    method public android.net.wifi.aware.SubscribeConfig.Builder setTtlSec(int);
+  }
+
+  public class SubscribeDiscoverySession extends android.net.wifi.aware.DiscoverySession {
+    method public void updateSubscribe(@NonNull android.net.wifi.aware.SubscribeConfig);
+  }
+
+  public class WifiAwareManager {
+    method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @Nullable android.os.Handler);
+    method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler);
+    method public android.net.wifi.aware.Characteristics getCharacteristics();
+    method public boolean isAvailable();
+    field public static final String ACTION_WIFI_AWARE_STATE_CHANGED = "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED";
+    field public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; // 0x0
+    field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
+  }
+
+  public final class WifiAwareNetworkInfo implements android.os.Parcelable android.net.TransportInfo {
+    method public int describeContents();
+    method @Nullable public java.net.Inet6Address getPeerIpv6Addr();
+    method public int getPort();
+    method public int getTransportProtocol();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkInfo> CREATOR;
+  }
+
+  public final class WifiAwareNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.WifiAwareNetworkSpecifier> CREATOR;
+  }
+
+  public static final class WifiAwareNetworkSpecifier.Builder {
+    ctor public WifiAwareNetworkSpecifier.Builder(@NonNull android.net.wifi.aware.DiscoverySession, @NonNull android.net.wifi.aware.PeerHandle);
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier build();
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPmk(@NonNull byte[]);
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPort(@IntRange(from=0, to=65535) int);
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPskPassphrase(@NonNull String);
+    method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setTransportProtocol(@IntRange(from=0, to=255) int);
+  }
+
+  public class WifiAwareSession implements java.lang.AutoCloseable {
+    method public void close();
+    method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, @NonNull byte[]);
+    method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, @NonNull byte[], @NonNull String);
+    method public void publish(@NonNull android.net.wifi.aware.PublishConfig, @NonNull android.net.wifi.aware.DiscoverySessionCallback, @Nullable android.os.Handler);
+    method public void subscribe(@NonNull android.net.wifi.aware.SubscribeConfig, @NonNull android.net.wifi.aware.DiscoverySessionCallback, @Nullable android.os.Handler);
+  }
+
+}
+
+package android.net.wifi.hotspot2 {
+
+  public final class ConfigParser {
+    method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(String, byte[]);
+  }
+
+  public final class PasspointConfiguration implements android.os.Parcelable {
+    ctor public PasspointConfiguration();
+    ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+    method public int describeContents();
+    method public android.net.wifi.hotspot2.pps.Credential getCredential();
+    method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
+    method public long getSubscriptionExpirationTimeMillis();
+    method @NonNull public String getUniqueId();
+    method public boolean isOsuProvisioned();
+    method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
+    method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
+  }
+
+}
+
+package android.net.wifi.hotspot2.omadm {
+
+  public final class PpsMoParser {
+    method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(String);
+  }
+
+}
+
+package android.net.wifi.hotspot2.pps {
+
+  public final class Credential implements android.os.Parcelable {
+    ctor public Credential();
+    ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
+    method public int describeContents();
+    method public java.security.cert.X509Certificate getCaCertificate();
+    method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
+    method public java.security.cert.X509Certificate[] getClientCertificateChain();
+    method public java.security.PrivateKey getClientPrivateKey();
+    method public String getRealm();
+    method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
+    method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
+    method public void setCaCertificate(java.security.cert.X509Certificate);
+    method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+    method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
+    method public void setClientPrivateKey(java.security.PrivateKey);
+    method public void setRealm(String);
+    method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+    method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
+  }
+
+  public static final class Credential.CertificateCredential implements android.os.Parcelable {
+    ctor public Credential.CertificateCredential();
+    ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+    method public int describeContents();
+    method public byte[] getCertSha256Fingerprint();
+    method public String getCertType();
+    method public void setCertSha256Fingerprint(byte[]);
+    method public void setCertType(String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
+  }
+
+  public static final class Credential.SimCredential implements android.os.Parcelable {
+    ctor public Credential.SimCredential();
+    ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+    method public int describeContents();
+    method public int getEapType();
+    method public String getImsi();
+    method public void setEapType(int);
+    method public void setImsi(String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
+  }
+
+  public static final class Credential.UserCredential implements android.os.Parcelable {
+    ctor public Credential.UserCredential();
+    ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+    method public int describeContents();
+    method public int getEapType();
+    method public String getNonEapInnerMethod();
+    method public String getPassword();
+    method public String getUsername();
+    method public void setEapType(int);
+    method public void setNonEapInnerMethod(String);
+    method public void setPassword(String);
+    method public void setUsername(String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
+  }
+
+  public final class HomeSp implements android.os.Parcelable {
+    ctor public HomeSp();
+    ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+    method public int describeContents();
+    method public String getFqdn();
+    method public String getFriendlyName();
+    method public long[] getRoamingConsortiumOis();
+    method public void setFqdn(String);
+    method public void setFriendlyName(String);
+    method public void setRoamingConsortiumOis(long[]);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
+  }
+
+}
+
+package android.net.wifi.p2p {
+
+  public class WifiP2pConfig implements android.os.Parcelable {
+    ctor public WifiP2pConfig();
+    ctor public WifiP2pConfig(android.net.wifi.p2p.WifiP2pConfig);
+    method public int describeContents();
+    method public int getGroupOwnerBand();
+    method public int getNetworkId();
+    method @Nullable public String getNetworkName();
+    method @Nullable public String getPassphrase();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pConfig> CREATOR;
+    field public static final int GROUP_OWNER_BAND_2GHZ = 1; // 0x1
+    field public static final int GROUP_OWNER_BAND_5GHZ = 2; // 0x2
+    field public static final int GROUP_OWNER_BAND_AUTO = 0; // 0x0
+    field public static final int GROUP_OWNER_INTENT_AUTO = -1; // 0xffffffff
+    field public static final int GROUP_OWNER_INTENT_MAX = 15; // 0xf
+    field public static final int GROUP_OWNER_INTENT_MIN = 0; // 0x0
+    field public String deviceAddress;
+    field @IntRange(from=0, to=15) public int groupOwnerIntent;
+    field public android.net.wifi.WpsInfo wps;
+  }
+
+  public static final class WifiP2pConfig.Builder {
+    ctor public WifiP2pConfig.Builder();
+    method @NonNull public android.net.wifi.p2p.WifiP2pConfig build();
+    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder enablePersistentMode(boolean);
+    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setDeviceAddress(@Nullable android.net.MacAddress);
+    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingBand(int);
+    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingFrequency(int);
+    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setNetworkName(@NonNull String);
+    method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setPassphrase(@NonNull String);
+  }
+
+  public class WifiP2pDevice implements android.os.Parcelable {
+    ctor public WifiP2pDevice();
+    ctor public WifiP2pDevice(android.net.wifi.p2p.WifiP2pDevice);
+    method public int describeContents();
+    method @Nullable public android.net.wifi.p2p.WifiP2pWfdInfo getWfdInfo();
+    method public boolean isGroupOwner();
+    method public boolean isServiceDiscoveryCapable();
+    method public void update(@NonNull android.net.wifi.p2p.WifiP2pDevice);
+    method public boolean wpsDisplaySupported();
+    method public boolean wpsKeypadSupported();
+    method public boolean wpsPbcSupported();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int AVAILABLE = 3; // 0x3
+    field public static final int CONNECTED = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDevice> CREATOR;
+    field public static final int FAILED = 2; // 0x2
+    field public static final int INVITED = 1; // 0x1
+    field public static final int UNAVAILABLE = 4; // 0x4
+    field public String deviceAddress;
+    field public String deviceName;
+    field public String primaryDeviceType;
+    field public String secondaryDeviceType;
+    field public int status;
+  }
+
+  public class WifiP2pDeviceList implements android.os.Parcelable {
+    ctor public WifiP2pDeviceList();
+    ctor public WifiP2pDeviceList(android.net.wifi.p2p.WifiP2pDeviceList);
+    method public int describeContents();
+    method public android.net.wifi.p2p.WifiP2pDevice get(String);
+    method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getDeviceList();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDeviceList> CREATOR;
+  }
+
+  public class WifiP2pGroup implements android.os.Parcelable {
+    ctor public WifiP2pGroup();
+    ctor public WifiP2pGroup(android.net.wifi.p2p.WifiP2pGroup);
+    method public int describeContents();
+    method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getClientList();
+    method public int getFrequency();
+    method public String getInterface();
+    method public int getNetworkId();
+    method public String getNetworkName();
+    method public android.net.wifi.p2p.WifiP2pDevice getOwner();
+    method public String getPassphrase();
+    method public boolean isGroupOwner();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroup> CREATOR;
+    field public static final int NETWORK_ID_PERSISTENT = -2; // 0xfffffffe
+    field public static final int NETWORK_ID_TEMPORARY = -1; // 0xffffffff
+  }
+
+  public class WifiP2pInfo implements android.os.Parcelable {
+    ctor public WifiP2pInfo();
+    ctor public WifiP2pInfo(android.net.wifi.p2p.WifiP2pInfo);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pInfo> CREATOR;
+    field public boolean groupFormed;
+    field public java.net.InetAddress groupOwnerAddress;
+    field public boolean isGroupOwner;
+  }
+
+  public class WifiP2pManager {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void addLocalService(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method public void addServiceRequest(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceRequest, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method public void cancelConnect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method public void clearLocalServices(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method public void clearServiceRequests(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void connect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void createGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void createGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pConfig, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void discoverPeers(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void discoverServices(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method public android.net.wifi.p2p.WifiP2pManager.Channel initialize(android.content.Context, android.os.Looper, android.net.wifi.p2p.WifiP2pManager.ChannelListener);
+    method public void removeGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method public void removeLocalService(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method public void removeServiceRequest(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceRequest, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method public void requestConnectionInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestDeviceInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.DeviceInfoListener);
+    method public void requestDiscoveryState(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.DiscoveryStateListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestGroupInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.GroupInfoListener);
+    method public void requestNetworkInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.NetworkInfoListener);
+    method public void requestP2pState(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pManager.P2pStateListener);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestPeers(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.PeerListListener);
+    method public void setDnsSdResponseListeners(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.DnsSdServiceResponseListener, android.net.wifi.p2p.WifiP2pManager.DnsSdTxtRecordListener);
+    method public void setServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ServiceResponseListener);
+    method public void setUpnpServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.UpnpServiceResponseListener);
+    method public void stopPeerDiscovery(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    field public static final int BUSY = 2; // 0x2
+    field public static final int ERROR = 0; // 0x0
+    field public static final String EXTRA_DISCOVERY_STATE = "discoveryState";
+    field public static final String EXTRA_NETWORK_INFO = "networkInfo";
+    field public static final String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList";
+    field public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
+    field public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo";
+    field public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
+    field public static final String EXTRA_WIFI_STATE = "wifi_p2p_state";
+    field public static final int NO_SERVICE_REQUESTS = 3; // 0x3
+    field public static final int P2P_UNSUPPORTED = 1; // 0x1
+    field public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION = "android.net.wifi.p2p.CONNECTION_STATE_CHANGE";
+    field public static final String WIFI_P2P_DISCOVERY_CHANGED_ACTION = "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE";
+    field public static final int WIFI_P2P_DISCOVERY_STARTED = 2; // 0x2
+    field public static final int WIFI_P2P_DISCOVERY_STOPPED = 1; // 0x1
+    field public static final String WIFI_P2P_PEERS_CHANGED_ACTION = "android.net.wifi.p2p.PEERS_CHANGED";
+    field public static final String WIFI_P2P_STATE_CHANGED_ACTION = "android.net.wifi.p2p.STATE_CHANGED";
+    field public static final int WIFI_P2P_STATE_DISABLED = 1; // 0x1
+    field public static final int WIFI_P2P_STATE_ENABLED = 2; // 0x2
+    field public static final String WIFI_P2P_THIS_DEVICE_CHANGED_ACTION = "android.net.wifi.p2p.THIS_DEVICE_CHANGED";
+  }
+
+  public static interface WifiP2pManager.ActionListener {
+    method public void onFailure(int);
+    method public void onSuccess();
+  }
+
+  public static class WifiP2pManager.Channel implements java.lang.AutoCloseable {
+    method public void close();
+  }
+
+  public static interface WifiP2pManager.ChannelListener {
+    method public void onChannelDisconnected();
+  }
+
+  public static interface WifiP2pManager.ConnectionInfoListener {
+    method public void onConnectionInfoAvailable(android.net.wifi.p2p.WifiP2pInfo);
+  }
+
+  public static interface WifiP2pManager.DeviceInfoListener {
+    method public void onDeviceInfoAvailable(@Nullable android.net.wifi.p2p.WifiP2pDevice);
+  }
+
+  public static interface WifiP2pManager.DiscoveryStateListener {
+    method public void onDiscoveryStateAvailable(int);
+  }
+
+  public static interface WifiP2pManager.DnsSdServiceResponseListener {
+    method public void onDnsSdServiceAvailable(String, String, android.net.wifi.p2p.WifiP2pDevice);
+  }
+
+  public static interface WifiP2pManager.DnsSdTxtRecordListener {
+    method public void onDnsSdTxtRecordAvailable(String, java.util.Map<java.lang.String,java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
+  }
+
+  public static interface WifiP2pManager.GroupInfoListener {
+    method public void onGroupInfoAvailable(android.net.wifi.p2p.WifiP2pGroup);
+  }
+
+  public static interface WifiP2pManager.NetworkInfoListener {
+    method public void onNetworkInfoAvailable(@NonNull android.net.NetworkInfo);
+  }
+
+  public static interface WifiP2pManager.P2pStateListener {
+    method public void onP2pStateAvailable(int);
+  }
+
+  public static interface WifiP2pManager.PeerListListener {
+    method public void onPeersAvailable(android.net.wifi.p2p.WifiP2pDeviceList);
+  }
+
+  public static interface WifiP2pManager.ServiceResponseListener {
+    method public void onServiceAvailable(int, byte[], android.net.wifi.p2p.WifiP2pDevice);
+  }
+
+  public static interface WifiP2pManager.UpnpServiceResponseListener {
+    method public void onUpnpServiceAvailable(java.util.List<java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
+  }
+
+  public final class WifiP2pWfdInfo implements android.os.Parcelable {
+    ctor public WifiP2pWfdInfo();
+    ctor public WifiP2pWfdInfo(@Nullable android.net.wifi.p2p.WifiP2pWfdInfo);
+    method public int describeContents();
+    method public int getControlPort();
+    method public int getDeviceType();
+    method public int getMaxThroughput();
+    method public boolean isContentProtectionSupported();
+    method public boolean isEnabled();
+    method public boolean isSessionAvailable();
+    method public void setContentProtectionSupported(boolean);
+    method public void setControlPort(@IntRange(from=0) int);
+    method public boolean setDeviceType(int);
+    method public void setEnabled(boolean);
+    method public void setMaxThroughput(@IntRange(from=0) int);
+    method public void setSessionAvailable(boolean);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pWfdInfo> CREATOR;
+    field public static final int DEVICE_TYPE_PRIMARY_SINK = 1; // 0x1
+    field public static final int DEVICE_TYPE_SECONDARY_SINK = 2; // 0x2
+    field public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3; // 0x3
+    field public static final int DEVICE_TYPE_WFD_SOURCE = 0; // 0x0
+  }
+
+}
+
+package android.net.wifi.p2p.nsd {
+
+  public class WifiP2pDnsSdServiceInfo extends android.net.wifi.p2p.nsd.WifiP2pServiceInfo {
+    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo newInstance(String, String, java.util.Map<java.lang.String,java.lang.String>);
+  }
+
+  public class WifiP2pDnsSdServiceRequest extends android.net.wifi.p2p.nsd.WifiP2pServiceRequest {
+    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance();
+    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance(String);
+    method public static android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest newInstance(String, String);
+  }
+
+  public class WifiP2pServiceInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int SERVICE_TYPE_ALL = 0; // 0x0
+    field public static final int SERVICE_TYPE_BONJOUR = 1; // 0x1
+    field public static final int SERVICE_TYPE_UPNP = 2; // 0x2
+    field public static final int SERVICE_TYPE_VENDOR_SPECIFIC = 255; // 0xff
+  }
+
+  public class WifiP2pServiceRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public static android.net.wifi.p2p.nsd.WifiP2pServiceRequest newInstance(int, String);
+    method public static android.net.wifi.p2p.nsd.WifiP2pServiceRequest newInstance(int);
+    method public void writeToParcel(android.os.Parcel, int);
+  }
+
+  public class WifiP2pUpnpServiceInfo extends android.net.wifi.p2p.nsd.WifiP2pServiceInfo {
+    method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo newInstance(String, String, java.util.List<java.lang.String>);
+  }
+
+  public class WifiP2pUpnpServiceRequest extends android.net.wifi.p2p.nsd.WifiP2pServiceRequest {
+    method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest newInstance();
+    method public static android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest newInstance(String);
+  }
+
+}
+
+package android.net.wifi.rtt {
+
+  public class CivicLocationKeys {
+    field public static final int ADDITIONAL_CODE = 32; // 0x20
+    field public static final int APT = 26; // 0x1a
+    field public static final int BOROUGH = 4; // 0x4
+    field public static final int BRANCH_ROAD_NAME = 36; // 0x24
+    field public static final int BUILDING = 25; // 0x19
+    field public static final int CITY = 3; // 0x3
+    field public static final int COUNTY = 2; // 0x2
+    field public static final int DESK = 33; // 0x21
+    field public static final int FLOOR = 27; // 0x1b
+    field public static final int GROUP_OF_STREETS = 6; // 0x6
+    field public static final int HNO = 19; // 0x13
+    field public static final int HNS = 20; // 0x14
+    field public static final int LANGUAGE = 0; // 0x0
+    field public static final int LMK = 21; // 0x15
+    field public static final int LOC = 22; // 0x16
+    field public static final int NAM = 23; // 0x17
+    field public static final int NEIGHBORHOOD = 5; // 0x5
+    field public static final int PCN = 30; // 0x1e
+    field public static final int POD = 17; // 0x11
+    field public static final int POSTAL_CODE = 24; // 0x18
+    field public static final int PO_BOX = 31; // 0x1f
+    field public static final int PRD = 16; // 0x10
+    field public static final int PRIMARY_ROAD_NAME = 34; // 0x22
+    field public static final int ROAD_SECTION = 35; // 0x23
+    field public static final int ROOM = 28; // 0x1c
+    field public static final int SCRIPT = 128; // 0x80
+    field public static final int STATE = 1; // 0x1
+    field public static final int STREET_NAME_POST_MODIFIER = 39; // 0x27
+    field public static final int STREET_NAME_PRE_MODIFIER = 38; // 0x26
+    field public static final int STS = 18; // 0x12
+    field public static final int SUBBRANCH_ROAD_NAME = 37; // 0x25
+    field public static final int TYPE_OF_PLACE = 29; // 0x1d
+  }
+
+  public final class RangingRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public static int getMaxPeers();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingRequest> CREATOR;
+  }
+
+  public static final class RangingRequest.Builder {
+    ctor public RangingRequest.Builder();
+    method public android.net.wifi.rtt.RangingRequest.Builder addAccessPoint(@NonNull android.net.wifi.ScanResult);
+    method public android.net.wifi.rtt.RangingRequest.Builder addAccessPoints(@NonNull java.util.List<android.net.wifi.ScanResult>);
+    method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.MacAddress);
+    method public android.net.wifi.rtt.RangingRequest.Builder addWifiAwarePeer(@NonNull android.net.wifi.aware.PeerHandle);
+    method public android.net.wifi.rtt.RangingRequest build();
+  }
+
+  public final class RangingResult implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getDistanceMm();
+    method public int getDistanceStdDevMm();
+    method @Nullable public android.net.MacAddress getMacAddress();
+    method public int getNumAttemptedMeasurements();
+    method public int getNumSuccessfulMeasurements();
+    method @Nullable public android.net.wifi.aware.PeerHandle getPeerHandle();
+    method public long getRangingTimestampMillis();
+    method public int getRssi();
+    method public int getStatus();
+    method @Nullable public android.net.wifi.rtt.ResponderLocation getUnverifiedResponderLocation();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingResult> CREATOR;
+    field public static final int STATUS_FAIL = 1; // 0x1
+    field public static final int STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC = 2; // 0x2
+    field public static final int STATUS_SUCCESS = 0; // 0x0
+  }
+
+  public abstract class RangingResultCallback {
+    ctor public RangingResultCallback();
+    method public abstract void onRangingFailure(int);
+    method public abstract void onRangingResults(@NonNull java.util.List<android.net.wifi.rtt.RangingResult>);
+    field public static final int STATUS_CODE_FAIL = 1; // 0x1
+    field public static final int STATUS_CODE_FAIL_RTT_NOT_AVAILABLE = 2; // 0x2
+  }
+
+  public final class ResponderLocation implements android.os.Parcelable {
+    method public int describeContents();
+    method public double getAltitude();
+    method public int getAltitudeType();
+    method public double getAltitudeUncertainty();
+    method public java.util.List<android.net.MacAddress> getColocatedBssids();
+    method public int getDatum();
+    method public int getExpectedToMove();
+    method public double getFloorNumber();
+    method public double getHeightAboveFloorMeters();
+    method public double getHeightAboveFloorUncertaintyMeters();
+    method public double getLatitude();
+    method public double getLatitudeUncertainty();
+    method public int getLciVersion();
+    method public double getLongitude();
+    method public double getLongitudeUncertainty();
+    method @Nullable public String getMapImageMimeType();
+    method @Nullable public android.net.Uri getMapImageUri();
+    method public boolean getRegisteredLocationAgreementIndication();
+    method public boolean isLciSubelementValid();
+    method public boolean isZaxisSubelementValid();
+    method @Nullable public android.location.Address toCivicLocationAddress();
+    method @Nullable public android.util.SparseArray<java.lang.String> toCivicLocationSparseArray();
+    method @NonNull public android.location.Location toLocation();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int ALTITUDE_FLOORS = 2; // 0x2
+    field public static final int ALTITUDE_METERS = 1; // 0x1
+    field public static final int ALTITUDE_UNDEFINED = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderLocation> CREATOR;
+    field public static final int DATUM_NAD83_MLLW = 3; // 0x3
+    field public static final int DATUM_NAD83_NAV88 = 2; // 0x2
+    field public static final int DATUM_UNDEFINED = 0; // 0x0
+    field public static final int DATUM_WGS84 = 1; // 0x1
+    field public static final int LCI_VERSION_1 = 1; // 0x1
+    field public static final int LOCATION_FIXED = 0; // 0x0
+    field public static final int LOCATION_MOVEMENT_UNKNOWN = 2; // 0x2
+    field public static final int LOCATION_RESERVED = 3; // 0x3
+    field public static final int LOCATION_VARIABLE = 1; // 0x1
+  }
+
+  public class WifiRttManager {
+    method public boolean isAvailable();
+    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_WIFI_STATE}) public void startRanging(@NonNull android.net.wifi.rtt.RangingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.rtt.RangingResultCallback);
+    field public static final String ACTION_WIFI_RTT_STATE_CHANGED = "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED";
+  }
+
+}
+
diff --git a/wifi/api/module-lib-current.txt b/wifi/api/module-lib-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/wifi/api/module-lib-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/wifi/api/module-lib-removed.txt b/wifi/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/wifi/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/wifi/api/removed.txt b/wifi/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/wifi/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
new file mode 100644
index 0000000..150a650
--- /dev/null
+++ b/wifi/api/system-current.txt
@@ -0,0 +1,939 @@
+// Signature format: 2.0
+package android.net.wifi {
+
+  public abstract class EasyConnectStatusCallback {
+    ctor public EasyConnectStatusCallback();
+    method public abstract void onConfiguratorSuccess(int);
+    method public abstract void onEnrolleeSuccess(int);
+    method public void onFailure(int);
+    method public void onFailure(int, @Nullable String, @NonNull android.util.SparseArray<int[]>, @NonNull int[]);
+    method public abstract void onProgress(int);
+    field public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; // 0x0
+    field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; // 0x3
+    field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2; // 0x2
+    field public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; // 0x1
+    field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; // 0x1
+    field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0
+  }
+
+  @Deprecated public class RttManager {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void disableResponder(android.net.wifi.RttManager.ResponderCallback);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void enableResponder(android.net.wifi.RttManager.ResponderCallback);
+    method @Deprecated public android.net.wifi.RttManager.Capabilities getCapabilities();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.net.wifi.RttManager.RttCapabilities getRttCapabilities();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startRanging(android.net.wifi.RttManager.RttParams[], android.net.wifi.RttManager.RttListener);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopRanging(android.net.wifi.RttManager.RttListener);
+    field @Deprecated public static final int BASE;
+    field @Deprecated public static final int CMD_OP_ABORTED;
+    field @Deprecated public static final int CMD_OP_DISABLE_RESPONDER;
+    field @Deprecated public static final int CMD_OP_ENABLE_RESPONDER;
+    field @Deprecated public static final int CMD_OP_ENALBE_RESPONDER_FAILED;
+    field @Deprecated public static final int CMD_OP_ENALBE_RESPONDER_SUCCEEDED;
+    field @Deprecated public static final int CMD_OP_FAILED;
+    field @Deprecated public static final int CMD_OP_START_RANGING;
+    field @Deprecated public static final int CMD_OP_STOP_RANGING;
+    field @Deprecated public static final int CMD_OP_SUCCEEDED;
+    field @Deprecated public static final String DESCRIPTION_KEY = "android.net.wifi.RttManager.Description";
+    field @Deprecated public static final int PREAMBLE_HT = 2; // 0x2
+    field @Deprecated public static final int PREAMBLE_LEGACY = 1; // 0x1
+    field @Deprecated public static final int PREAMBLE_VHT = 4; // 0x4
+    field @Deprecated public static final int REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON = -6; // 0xfffffffa
+    field @Deprecated public static final int REASON_INVALID_LISTENER = -3; // 0xfffffffd
+    field @Deprecated public static final int REASON_INVALID_REQUEST = -4; // 0xfffffffc
+    field @Deprecated public static final int REASON_NOT_AVAILABLE = -2; // 0xfffffffe
+    field @Deprecated public static final int REASON_PERMISSION_DENIED = -5; // 0xfffffffb
+    field @Deprecated public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
+    field @Deprecated public static final int RTT_BW_10_SUPPORT = 2; // 0x2
+    field @Deprecated public static final int RTT_BW_160_SUPPORT = 32; // 0x20
+    field @Deprecated public static final int RTT_BW_20_SUPPORT = 4; // 0x4
+    field @Deprecated public static final int RTT_BW_40_SUPPORT = 8; // 0x8
+    field @Deprecated public static final int RTT_BW_5_SUPPORT = 1; // 0x1
+    field @Deprecated public static final int RTT_BW_80_SUPPORT = 16; // 0x10
+    field @Deprecated public static final int RTT_CHANNEL_WIDTH_10 = 6; // 0x6
+    field @Deprecated public static final int RTT_CHANNEL_WIDTH_160 = 3; // 0x3
+    field @Deprecated public static final int RTT_CHANNEL_WIDTH_20 = 0; // 0x0
+    field @Deprecated public static final int RTT_CHANNEL_WIDTH_40 = 1; // 0x1
+    field @Deprecated public static final int RTT_CHANNEL_WIDTH_5 = 5; // 0x5
+    field @Deprecated public static final int RTT_CHANNEL_WIDTH_80 = 2; // 0x2
+    field @Deprecated public static final int RTT_CHANNEL_WIDTH_80P80 = 4; // 0x4
+    field @Deprecated public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1; // 0xffffffff
+    field @Deprecated public static final int RTT_PEER_NAN = 5; // 0x5
+    field @Deprecated public static final int RTT_PEER_P2P_CLIENT = 4; // 0x4
+    field @Deprecated public static final int RTT_PEER_P2P_GO = 3; // 0x3
+    field @Deprecated public static final int RTT_PEER_TYPE_AP = 1; // 0x1
+    field @Deprecated public static final int RTT_PEER_TYPE_STA = 2; // 0x2
+    field @Deprecated public static final int RTT_PEER_TYPE_UNSPECIFIED = 0; // 0x0
+    field @Deprecated public static final int RTT_STATUS_ABORTED = 8; // 0x8
+    field @Deprecated public static final int RTT_STATUS_FAILURE = 1; // 0x1
+    field @Deprecated public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; // 0x6
+    field @Deprecated public static final int RTT_STATUS_FAIL_BUSY_TRY_LATER = 12; // 0xc
+    field @Deprecated public static final int RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15; // 0xf
+    field @Deprecated public static final int RTT_STATUS_FAIL_INVALID_TS = 9; // 0x9
+    field @Deprecated public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; // 0x4
+    field @Deprecated public static final int RTT_STATUS_FAIL_NO_CAPABILITY = 7; // 0x7
+    field @Deprecated public static final int RTT_STATUS_FAIL_NO_RSP = 2; // 0x2
+    field @Deprecated public static final int RTT_STATUS_FAIL_PROTOCOL = 10; // 0xa
+    field @Deprecated public static final int RTT_STATUS_FAIL_REJECTED = 3; // 0x3
+    field @Deprecated public static final int RTT_STATUS_FAIL_SCHEDULE = 11; // 0xb
+    field @Deprecated public static final int RTT_STATUS_FAIL_TM_TIMEOUT = 5; // 0x5
+    field @Deprecated public static final int RTT_STATUS_INVALID_REQ = 13; // 0xd
+    field @Deprecated public static final int RTT_STATUS_NO_WIFI = 14; // 0xe
+    field @Deprecated public static final int RTT_STATUS_SUCCESS = 0; // 0x0
+    field @Deprecated public static final int RTT_TYPE_11_MC = 4; // 0x4
+    field @Deprecated public static final int RTT_TYPE_11_V = 2; // 0x2
+    field @Deprecated public static final int RTT_TYPE_ONE_SIDED = 1; // 0x1
+    field @Deprecated public static final int RTT_TYPE_TWO_SIDED = 2; // 0x2
+    field @Deprecated public static final int RTT_TYPE_UNSPECIFIED = 0; // 0x0
+  }
+
+  @Deprecated public class RttManager.Capabilities {
+    ctor @Deprecated public RttManager.Capabilities();
+    field @Deprecated public int supportedPeerType;
+    field @Deprecated public int supportedType;
+  }
+
+  @Deprecated public static class RttManager.ParcelableRttParams implements android.os.Parcelable {
+    field @Deprecated @NonNull public android.net.wifi.RttManager.RttParams[] mParams;
+  }
+
+  @Deprecated public static class RttManager.ParcelableRttResults implements android.os.Parcelable {
+    ctor @Deprecated public RttManager.ParcelableRttResults(android.net.wifi.RttManager.RttResult[]);
+    field @Deprecated public android.net.wifi.RttManager.RttResult[] mResults;
+  }
+
+  @Deprecated public abstract static class RttManager.ResponderCallback {
+    ctor @Deprecated public RttManager.ResponderCallback();
+    method @Deprecated public abstract void onResponderEnableFailure(int);
+    method @Deprecated public abstract void onResponderEnabled(android.net.wifi.RttManager.ResponderConfig);
+  }
+
+  @Deprecated public static class RttManager.ResponderConfig implements android.os.Parcelable {
+    ctor @Deprecated public RttManager.ResponderConfig();
+    method @Deprecated public int describeContents();
+    method @Deprecated public void writeToParcel(android.os.Parcel, int);
+    field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.RttManager.ResponderConfig> CREATOR;
+    field @Deprecated public int centerFreq0;
+    field @Deprecated public int centerFreq1;
+    field @Deprecated public int channelWidth;
+    field @Deprecated public int frequency;
+    field @Deprecated public String macAddress;
+    field @Deprecated public int preamble;
+  }
+
+  @Deprecated public static class RttManager.RttCapabilities implements android.os.Parcelable {
+    ctor @Deprecated public RttManager.RttCapabilities();
+    field @Deprecated public int bwSupported;
+    field @Deprecated public boolean lciSupported;
+    field @Deprecated public boolean lcrSupported;
+    field @Deprecated public int mcVersion;
+    field @Deprecated public boolean oneSidedRttSupported;
+    field @Deprecated public int preambleSupported;
+    field @Deprecated public boolean responderSupported;
+    field @Deprecated public boolean secureRttSupported;
+    field @Deprecated public boolean supportedPeerType;
+    field @Deprecated public boolean supportedType;
+    field @Deprecated public boolean twoSided11McRttSupported;
+  }
+
+  @Deprecated public static interface RttManager.RttListener {
+    method @Deprecated public void onAborted();
+    method @Deprecated public void onFailure(int, String);
+    method @Deprecated public void onSuccess(android.net.wifi.RttManager.RttResult[]);
+  }
+
+  @Deprecated public static class RttManager.RttParams {
+    ctor @Deprecated public RttManager.RttParams();
+    field @Deprecated public boolean LCIRequest;
+    field @Deprecated public boolean LCRRequest;
+    field @Deprecated public int bandwidth;
+    field @Deprecated public String bssid;
+    field @Deprecated public int burstTimeout;
+    field @Deprecated public int centerFreq0;
+    field @Deprecated public int centerFreq1;
+    field @Deprecated public int channelWidth;
+    field @Deprecated public int deviceType;
+    field @Deprecated public int frequency;
+    field @Deprecated public int interval;
+    field @Deprecated public int numRetriesPerFTMR;
+    field @Deprecated public int numRetriesPerMeasurementFrame;
+    field @Deprecated public int numSamplesPerBurst;
+    field @Deprecated public int num_retries;
+    field @Deprecated public int num_samples;
+    field @Deprecated public int numberBurst;
+    field @Deprecated public int preamble;
+    field @Deprecated public int requestType;
+    field @Deprecated public boolean secure;
+  }
+
+  @Deprecated public static class RttManager.RttResult {
+    ctor @Deprecated public RttManager.RttResult();
+    field @Deprecated public android.net.wifi.RttManager.WifiInformationElement LCI;
+    field @Deprecated public android.net.wifi.RttManager.WifiInformationElement LCR;
+    field @Deprecated public String bssid;
+    field @Deprecated public int burstDuration;
+    field @Deprecated public int burstNumber;
+    field @Deprecated public int distance;
+    field @Deprecated public int distanceSpread;
+    field @Deprecated public int distanceStandardDeviation;
+    field @Deprecated public int distance_cm;
+    field @Deprecated public int distance_sd_cm;
+    field @Deprecated public int distance_spread_cm;
+    field @Deprecated public int frameNumberPerBurstPeer;
+    field @Deprecated public int measurementFrameNumber;
+    field @Deprecated public int measurementType;
+    field @Deprecated public int negotiatedBurstNum;
+    field @Deprecated public int requestType;
+    field @Deprecated public int retryAfterDuration;
+    field @Deprecated public int rssi;
+    field @Deprecated public int rssiSpread;
+    field @Deprecated public int rssi_spread;
+    field @Deprecated public long rtt;
+    field @Deprecated public long rttSpread;
+    field @Deprecated public long rttStandardDeviation;
+    field @Deprecated public long rtt_ns;
+    field @Deprecated public long rtt_sd_ns;
+    field @Deprecated public long rtt_spread_ns;
+    field @Deprecated public int rxRate;
+    field @Deprecated public boolean secure;
+    field @Deprecated public int status;
+    field @Deprecated public int successMeasurementFrameNumber;
+    field @Deprecated public long ts;
+    field @Deprecated public int txRate;
+    field @Deprecated public int tx_rate;
+  }
+
+  @Deprecated public static class RttManager.WifiInformationElement {
+    ctor @Deprecated public RttManager.WifiInformationElement();
+    field @Deprecated public byte[] data;
+    field @Deprecated public byte id;
+  }
+
+  public class ScanResult implements android.os.Parcelable {
+    field public static final int CIPHER_CCMP = 3; // 0x3
+    field public static final int CIPHER_GCMP_256 = 4; // 0x4
+    field public static final int CIPHER_NONE = 0; // 0x0
+    field public static final int CIPHER_NO_GROUP_ADDRESSED = 1; // 0x1
+    field public static final int CIPHER_SMS4 = 5; // 0x5
+    field public static final int CIPHER_TKIP = 2; // 0x2
+    field public static final int KEY_MGMT_EAP = 2; // 0x2
+    field public static final int KEY_MGMT_EAP_SHA256 = 6; // 0x6
+    field public static final int KEY_MGMT_EAP_SUITE_B_192 = 10; // 0xa
+    field public static final int KEY_MGMT_FT_EAP = 4; // 0x4
+    field public static final int KEY_MGMT_FT_PSK = 3; // 0x3
+    field public static final int KEY_MGMT_FT_SAE = 11; // 0xb
+    field public static final int KEY_MGMT_NONE = 0; // 0x0
+    field public static final int KEY_MGMT_OSEN = 7; // 0x7
+    field public static final int KEY_MGMT_OWE = 9; // 0x9
+    field public static final int KEY_MGMT_OWE_TRANSITION = 12; // 0xc
+    field public static final int KEY_MGMT_PSK = 1; // 0x1
+    field public static final int KEY_MGMT_PSK_SHA256 = 5; // 0x5
+    field public static final int KEY_MGMT_SAE = 8; // 0x8
+    field public static final int KEY_MGMT_WAPI_CERT = 14; // 0xe
+    field public static final int KEY_MGMT_WAPI_PSK = 13; // 0xd
+    field public static final int PROTOCOL_NONE = 0; // 0x0
+    field public static final int PROTOCOL_OSEN = 3; // 0x3
+    field public static final int PROTOCOL_RSN = 2; // 0x2
+    field public static final int PROTOCOL_WAPI = 4; // 0x4
+    field public static final int PROTOCOL_WPA = 1; // 0x1
+  }
+
+  public final class SoftApCapability implements android.os.Parcelable {
+    method public boolean areFeaturesSupported(long);
+    method public int describeContents();
+    method public int getMaxSupportedClients();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApCapability> CREATOR;
+    field public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1L; // 0x1L
+    field public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 2L; // 0x2L
+    field public static final long SOFTAP_FEATURE_WPA3_SAE = 4L; // 0x4L
+  }
+
+  public final class SoftApConfiguration implements android.os.Parcelable {
+    method @NonNull public java.util.List<android.net.MacAddress> getAllowedClientList();
+    method public int getBand();
+    method @NonNull public java.util.List<android.net.MacAddress> getBlockedClientList();
+    method public int getChannel();
+    method public int getMaxNumberOfClients();
+    method public long getShutdownTimeoutMillis();
+    method public boolean isAutoShutdownEnabled();
+    method public boolean isClientControlByUserEnabled();
+    method @Nullable public android.net.wifi.WifiConfiguration toWifiConfiguration();
+    field public static final int BAND_2GHZ = 1; // 0x1
+    field public static final int BAND_5GHZ = 2; // 0x2
+    field public static final int BAND_6GHZ = 4; // 0x4
+    field public static final int BAND_ANY = 7; // 0x7
+  }
+
+  public static final class SoftApConfiguration.Builder {
+    ctor public SoftApConfiguration.Builder();
+    ctor public SoftApConfiguration.Builder(@NonNull android.net.wifi.SoftApConfiguration);
+    method @NonNull public android.net.wifi.SoftApConfiguration build();
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAllowedClientList(@NonNull java.util.List<android.net.MacAddress>);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setAutoShutdownEnabled(boolean);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBand(int);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBlockedClientList(@NonNull java.util.List<android.net.MacAddress>);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setBssid(@Nullable android.net.MacAddress);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setChannel(int, int);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setClientControlByUserEnabled(boolean);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setHiddenSsid(boolean);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setMaxNumberOfClients(@IntRange(from=0) int);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setPassphrase(@Nullable String, int);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setShutdownTimeoutMillis(@IntRange(from=0) long);
+    method @NonNull public android.net.wifi.SoftApConfiguration.Builder setSsid(@Nullable String);
+  }
+
+  public final class SoftApInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getBandwidth();
+    method public int getFrequency();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int CHANNEL_WIDTH_160MHZ = 6; // 0x6
+    field public static final int CHANNEL_WIDTH_20MHZ = 2; // 0x2
+    field public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1; // 0x1
+    field public static final int CHANNEL_WIDTH_40MHZ = 3; // 0x3
+    field public static final int CHANNEL_WIDTH_80MHZ = 4; // 0x4
+    field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5; // 0x5
+    field public static final int CHANNEL_WIDTH_INVALID = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApInfo> CREATOR;
+  }
+
+  public final class WifiClient implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.MacAddress getMacAddress();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiClient> CREATOR;
+  }
+
+  @Deprecated public class WifiConfiguration implements android.os.Parcelable {
+    method @Deprecated public int getAuthType();
+    method @Deprecated @NonNull public android.net.IpConfiguration getIpConfiguration();
+    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus getNetworkSelectionStatus();
+    method @Deprecated @NonNull public String getPrintableSsid();
+    method @Deprecated public int getRecentFailureReason();
+    method @Deprecated public boolean hasNoInternetAccess();
+    method @Deprecated public boolean isEphemeral();
+    method @Deprecated public static boolean isMetered(@Nullable android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiInfo);
+    method @Deprecated public boolean isNoInternetAccessExpected();
+    method @Deprecated public void setIpConfiguration(@Nullable android.net.IpConfiguration);
+    method @Deprecated public void setNetworkSelectionStatus(@NonNull android.net.wifi.WifiConfiguration.NetworkSelectionStatus);
+    field @Deprecated public static final int INVALID_NETWORK_ID = -1; // 0xffffffff
+    field @Deprecated public static final int METERED_OVERRIDE_METERED = 1; // 0x1
+    field @Deprecated public static final int METERED_OVERRIDE_NONE = 0; // 0x0
+    field @Deprecated public static final int METERED_OVERRIDE_NOT_METERED = 2; // 0x2
+    field @Deprecated public static final int RANDOMIZATION_NONE = 0; // 0x0
+    field @Deprecated public static final int RANDOMIZATION_PERSISTENT = 1; // 0x1
+    field @Deprecated public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17; // 0x11
+    field @Deprecated public static final int RECENT_FAILURE_NONE = 0; // 0x0
+    field @Deprecated public boolean allowAutojoin;
+    field @Deprecated public int carrierId;
+    field @Deprecated public String creatorName;
+    field @Deprecated public int creatorUid;
+    field @Deprecated public boolean fromWifiNetworkSpecifier;
+    field @Deprecated public boolean fromWifiNetworkSuggestion;
+    field @Deprecated public String lastUpdateName;
+    field @Deprecated public int lastUpdateUid;
+    field @Deprecated public int macRandomizationSetting;
+    field @Deprecated public boolean meteredHint;
+    field @Deprecated public int meteredOverride;
+    field @Deprecated public int numAssociation;
+    field @Deprecated public int numScorerOverride;
+    field @Deprecated public int numScorerOverrideAndSwitchedNetwork;
+    field @Deprecated public boolean requirePmf;
+    field @Deprecated public boolean shared;
+    field @Deprecated public boolean useExternalScores;
+  }
+
+  @Deprecated public static class WifiConfiguration.KeyMgmt {
+    field @Deprecated public static final int WAPI_CERT = 14; // 0xe
+    field @Deprecated public static final int WAPI_PSK = 13; // 0xd
+    field @Deprecated public static final int WPA2_PSK = 4; // 0x4
+  }
+
+  @Deprecated public static class WifiConfiguration.NetworkSelectionStatus {
+    method @Deprecated public int getDisableReasonCounter(int);
+    method @Deprecated public long getDisableTime();
+    method @Deprecated public static int getMaxNetworkSelectionDisableReason();
+    method @Deprecated public int getNetworkSelectionDisableReason();
+    method @Deprecated @Nullable public static String getNetworkSelectionDisableReasonString(int);
+    method @Deprecated public int getNetworkSelectionStatus();
+    method @Deprecated @NonNull public String getNetworkStatusString();
+    method @Deprecated public boolean hasEverConnected();
+    field @Deprecated public static final int DISABLED_ASSOCIATION_REJECTION = 1; // 0x1
+    field @Deprecated public static final int DISABLED_AUTHENTICATION_FAILURE = 2; // 0x2
+    field @Deprecated public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 5; // 0x5
+    field @Deprecated public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9; // 0x9
+    field @Deprecated public static final int DISABLED_BY_WIFI_MANAGER = 7; // 0x7
+    field @Deprecated public static final int DISABLED_BY_WRONG_PASSWORD = 8; // 0x8
+    field @Deprecated public static final int DISABLED_DHCP_FAILURE = 3; // 0x3
+    field @Deprecated public static final int DISABLED_NONE = 0; // 0x0
+    field @Deprecated public static final int DISABLED_NO_INTERNET_PERMANENT = 6; // 0x6
+    field @Deprecated public static final int DISABLED_NO_INTERNET_TEMPORARY = 4; // 0x4
+    field @Deprecated public static final int NETWORK_SELECTION_ENABLED = 0; // 0x0
+    field @Deprecated public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; // 0x2
+    field @Deprecated public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; // 0x1
+  }
+
+  @Deprecated public static final class WifiConfiguration.NetworkSelectionStatus.Builder {
+    ctor @Deprecated public WifiConfiguration.NetworkSelectionStatus.Builder();
+    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus build();
+    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus.Builder setNetworkSelectionDisableReason(int);
+    method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus.Builder setNetworkSelectionStatus(int);
+  }
+
+  public class WifiEnterpriseConfig implements android.os.Parcelable {
+    method @Nullable public String[] getCaCertificateAliases();
+    method @NonNull public String getCaPath();
+    method @NonNull public String getClientCertificateAlias();
+    method public int getOcsp();
+    method @NonNull public String getWapiCertSuite();
+    method public void setCaCertificateAliases(@Nullable String[]);
+    method public void setCaPath(@NonNull String);
+    method public void setClientCertificateAlias(@NonNull String);
+    method public void setOcsp(int);
+    method public void setWapiCertSuite(@NonNull String);
+    field public static final int OCSP_NONE = 0; // 0x0
+    field public static final int OCSP_REQUEST_CERT_STATUS = 1; // 0x1
+    field public static final int OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS = 3; // 0x3
+    field public static final int OCSP_REQUIRE_CERT_STATUS = 2; // 0x2
+  }
+
+  public class WifiFrameworkInitializer {
+    method public static void registerServiceWrappers();
+  }
+
+  public class WifiInfo implements android.os.Parcelable {
+    method public double getLostTxPacketsPerSecond();
+    method @Nullable public String getRequestingPackageName();
+    method public double getRetriedTxPacketsPerSecond();
+    method public int getScore();
+    method public double getSuccessfulRxPacketsPerSecond();
+    method public double getSuccessfulTxPacketsPerSecond();
+    method public boolean isEphemeral();
+    method public boolean isOsuAp();
+    method public boolean isPasspointAp();
+    method @Nullable public static String sanitizeSsid(@Nullable String);
+    field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
+    field public static final int INVALID_RSSI = -127; // 0xffffff81
+  }
+
+  public class WifiManager {
+    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinGlobal(boolean);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoinPasspoint(@NonNull String, boolean);
+    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void clearWifiConnectedNetworkScorer();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK}) public void disableEphemeralNetwork(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>);
+    method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCountryCode();
+    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public android.net.Network getCurrentNetwork();
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses();
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>);
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>);
+    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.Map<android.net.wifi.WifiNetworkSuggestion,java.util.List<android.net.wifi.ScanResult>> getMatchingScanResults(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>, @Nullable java.util.List<android.net.wifi.ScanResult>);
+    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void getWifiActivityEnergyInfoAsync(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener);
+    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>);
+    method public boolean isApMacRandomizationSupported();
+    method public boolean isConnectedMacRandomizationSupported();
+    method @Deprecated public boolean isDeviceToDeviceRttSupported();
+    method public boolean isPortableHotspotSupported();
+    method public boolean isVerboseLoggingEnabled();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
+    method public boolean isWifiScannerSupported();
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerNetworkRequestMatchCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerTrafficStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.TrafficStateCallback);
+    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreBackupData(@NonNull byte[]);
+    method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public android.net.wifi.SoftApConfiguration restoreSoftApBackupData(@NonNull byte[]);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreSupplicantBackupData(@NonNull byte[], @NonNull byte[]);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveBackupData();
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveSoftApBackupData();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setAutoWakeupEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(int);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setMacRandomizationSettingPasspointEnabled(@NonNull String, boolean);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setPasspointMeteredOverride(@NonNull String, int);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanAlwaysAvailable(boolean);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanThrottleEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean setSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setVerboseLoggingEnabled(boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
+    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public boolean setWifiConnectedNetworkScorer(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiConnectedNetworkScorer);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback);
+    method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(android.os.WorkSource);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startTetheredHotspot(@Nullable android.net.wifi.SoftApConfiguration);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp();
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterNetworkRequestMatchCallback(@NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterSoftApCallback(@NonNull android.net.wifi.WifiManager.SoftApCallback);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterTrafficStateCallback(@NonNull android.net.wifi.WifiManager.TrafficStateCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int);
+    method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void updateWifiUsabilityScore(int, int, int);
+    field public static final String ACTION_LINK_CONFIGURATION_CHANGED = "android.net.wifi.LINK_CONFIGURATION_CHANGED";
+    field @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public static final String ACTION_NETWORK_SETTINGS_RESET = "android.net.wifi.action.NETWORK_SETTINGS_RESET";
+    field public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW = "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW";
+    field public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE";
+    field public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE";
+    field public static final int CHANGE_REASON_ADDED = 0; // 0x0
+    field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
+    field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
+    field public static final String CONFIGURED_NETWORKS_CHANGED_ACTION = "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
+    field public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1; // 0x1
+    field public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2; // 0x2
+    field public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3; // 0x3
+    field public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0; // 0x0
+    field public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1; // 0x1
+    field public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0; // 0x0
+    field public static final String EXTRA_CHANGE_REASON = "changeReason";
+    field public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES";
+    field public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
+    field public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK";
+    field public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
+    field public static final String EXTRA_URL = "android.net.wifi.extra.URL";
+    field public static final String EXTRA_WIFI_AP_FAILURE_REASON = "android.net.wifi.extra.WIFI_AP_FAILURE_REASON";
+    field public static final String EXTRA_WIFI_AP_INTERFACE_NAME = "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME";
+    field public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE";
+    field public static final String EXTRA_WIFI_AP_STATE = "wifi_state";
+    field public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
+    field public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
+    field public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid";
+    field public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0; // 0x0
+    field public static final int IFACE_IP_MODE_LOCAL_ONLY = 2; // 0x2
+    field public static final int IFACE_IP_MODE_TETHERED = 1; // 0x1
+    field public static final int IFACE_IP_MODE_UNSPECIFIED = -1; // 0xffffffff
+    field public static final int PASSPOINT_HOME_NETWORK = 0; // 0x0
+    field public static final int PASSPOINT_ROAMING_NETWORK = 1; // 0x1
+    field public static final int SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0; // 0x0
+    field public static final int SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1; // 0x1
+    field public static final int SAP_START_FAILURE_GENERAL = 0; // 0x0
+    field public static final int SAP_START_FAILURE_NO_CHANNEL = 1; // 0x1
+    field public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; // 0x2
+    field public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";
+    field public static final int WIFI_AP_STATE_DISABLED = 11; // 0xb
+    field public static final int WIFI_AP_STATE_DISABLING = 10; // 0xa
+    field public static final int WIFI_AP_STATE_ENABLED = 13; // 0xd
+    field public static final int WIFI_AP_STATE_ENABLING = 12; // 0xc
+    field public static final int WIFI_AP_STATE_FAILED = 14; // 0xe
+    field public static final String WIFI_CREDENTIAL_CHANGED_ACTION = "android.net.wifi.WIFI_CREDENTIAL_CHANGED";
+    field public static final int WIFI_CREDENTIAL_FORGOT = 1; // 0x1
+    field public static final int WIFI_CREDENTIAL_SAVED = 0; // 0x0
+  }
+
+  public static interface WifiManager.ActionListener {
+    method public void onFailure(int);
+    method public void onSuccess();
+  }
+
+  public static interface WifiManager.NetworkRequestMatchCallback {
+    method public default void onAbort();
+    method public default void onMatch(@NonNull java.util.List<android.net.wifi.ScanResult>);
+    method public default void onUserSelectionCallbackRegistration(@NonNull android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback);
+    method public default void onUserSelectionConnectFailure(@NonNull android.net.wifi.WifiConfiguration);
+    method public default void onUserSelectionConnectSuccess(@NonNull android.net.wifi.WifiConfiguration);
+  }
+
+  public static interface WifiManager.NetworkRequestUserSelectionCallback {
+    method public default void reject();
+    method public default void select(@NonNull android.net.wifi.WifiConfiguration);
+  }
+
+  public static interface WifiManager.OnWifiActivityEnergyInfoListener {
+    method public void onWifiActivityEnergyInfo(@Nullable android.os.connectivity.WifiActivityEnergyInfo);
+  }
+
+  public static interface WifiManager.OnWifiUsabilityStatsListener {
+    method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry);
+  }
+
+  public static interface WifiManager.ScoreUpdateObserver {
+    method public void notifyScoreUpdate(int, int);
+    method public void triggerUpdateOfWifiUsabilityStats(int);
+  }
+
+  public static interface WifiManager.SoftApCallback {
+    method public default void onBlockedClientConnecting(@NonNull android.net.wifi.WifiClient, int);
+    method public default void onCapabilityChanged(@NonNull android.net.wifi.SoftApCapability);
+    method public default void onConnectedClientsChanged(@NonNull java.util.List<android.net.wifi.WifiClient>);
+    method public default void onInfoChanged(@NonNull android.net.wifi.SoftApInfo);
+    method public default void onStateChanged(int, int);
+  }
+
+  public static interface WifiManager.TrafficStateCallback {
+    method public void onStateChanged(int);
+    field public static final int DATA_ACTIVITY_IN = 1; // 0x1
+    field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
+    field public static final int DATA_ACTIVITY_NONE = 0; // 0x0
+    field public static final int DATA_ACTIVITY_OUT = 2; // 0x2
+  }
+
+  public static interface WifiManager.WifiConnectedNetworkScorer {
+    method public void onSetScoreUpdateObserver(@NonNull android.net.wifi.WifiManager.ScoreUpdateObserver);
+    method public void onStart(int);
+    method public void onStop(int);
+  }
+
+  public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
+    ctor public WifiNetworkConnectionStatistics(int, int);
+    ctor public WifiNetworkConnectionStatistics();
+    ctor public WifiNetworkConnectionStatistics(android.net.wifi.WifiNetworkConnectionStatistics);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkConnectionStatistics> CREATOR;
+    field public int numConnection;
+    field public int numUsage;
+  }
+
+  public final class WifiNetworkSuggestion implements android.os.Parcelable {
+    method @NonNull public android.net.wifi.WifiConfiguration getWifiConfiguration();
+  }
+
+  public static final class WifiNetworkSuggestion.Builder {
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public android.net.wifi.WifiNetworkSuggestion.Builder setCarrierId(int);
+  }
+
+  public class WifiScanner {
+    method @Deprecated public void configureWifiChange(int, int, int, int, int, android.net.wifi.WifiScanner.BssidInfo[]);
+    method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
+    method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<java.lang.Integer> getAvailableChannels(int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults();
+    method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.net.wifi.ScanResult> getSingleScanResults();
+    method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void registerScanListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiScanner.ScanListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setScanningEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
+    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
+    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
+    method @Deprecated public void startTrackingBssids(android.net.wifi.WifiScanner.BssidInfo[], int, android.net.wifi.WifiScanner.BssidListener);
+    method @Deprecated public void startTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopBackgroundScan(android.net.wifi.WifiScanner.ScanListener);
+    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopScan(android.net.wifi.WifiScanner.ScanListener);
+    method @Deprecated public void stopTrackingBssids(android.net.wifi.WifiScanner.BssidListener);
+    method @Deprecated public void stopTrackingWifiChange(android.net.wifi.WifiScanner.WifiChangeListener);
+    method public void unregisterScanListener(@NonNull android.net.wifi.WifiScanner.ScanListener);
+    field public static final int MAX_SCAN_PERIOD_MS = 1024000; // 0xfa000
+    field public static final int MIN_SCAN_PERIOD_MS = 1000; // 0x3e8
+    field public static final int REASON_DUPLICATE_REQEUST = -5; // 0xfffffffb
+    field public static final int REASON_INVALID_LISTENER = -2; // 0xfffffffe
+    field public static final int REASON_INVALID_REQUEST = -3; // 0xfffffffd
+    field public static final int REASON_NOT_AUTHORIZED = -4; // 0xfffffffc
+    field public static final int REASON_SUCCEEDED = 0; // 0x0
+    field public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
+    field @Deprecated public static final int REPORT_EVENT_AFTER_BUFFER_FULL = 0; // 0x0
+    field public static final int REPORT_EVENT_AFTER_EACH_SCAN = 1; // 0x1
+    field public static final int REPORT_EVENT_FULL_SCAN_RESULT = 2; // 0x2
+    field public static final int REPORT_EVENT_NO_BATCH = 4; // 0x4
+    field public static final int SCAN_TYPE_HIGH_ACCURACY = 2; // 0x2
+    field public static final int SCAN_TYPE_LOW_LATENCY = 0; // 0x0
+    field public static final int SCAN_TYPE_LOW_POWER = 1; // 0x1
+    field public static final int WIFI_BAND_24_5_6_GHZ = 11; // 0xb
+    field public static final int WIFI_BAND_24_5_WITH_DFS_6_GHZ = 15; // 0xf
+    field public static final int WIFI_BAND_24_GHZ = 1; // 0x1
+    field public static final int WIFI_BAND_5_GHZ = 2; // 0x2
+    field public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; // 0x4
+    field public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; // 0x6
+    field public static final int WIFI_BAND_6_GHZ = 8; // 0x8
+    field public static final int WIFI_BAND_BOTH = 3; // 0x3
+    field public static final int WIFI_BAND_BOTH_WITH_DFS = 7; // 0x7
+    field public static final int WIFI_BAND_UNSPECIFIED = 0; // 0x0
+  }
+
+  public static interface WifiScanner.ActionListener {
+    method public void onFailure(int, String);
+    method public void onSuccess();
+  }
+
+  @Deprecated public static class WifiScanner.BssidInfo {
+    ctor @Deprecated public WifiScanner.BssidInfo();
+    field @Deprecated public String bssid;
+    field @Deprecated public int frequencyHint;
+    field @Deprecated public int high;
+    field @Deprecated public int low;
+  }
+
+  @Deprecated public static interface WifiScanner.BssidListener extends android.net.wifi.WifiScanner.ActionListener {
+    method @Deprecated public void onFound(android.net.wifi.ScanResult[]);
+    method @Deprecated public void onLost(android.net.wifi.ScanResult[]);
+  }
+
+  public static class WifiScanner.ChannelSpec {
+    ctor public WifiScanner.ChannelSpec(int);
+    field public int frequency;
+  }
+
+  @Deprecated public static class WifiScanner.HotlistSettings implements android.os.Parcelable {
+    ctor @Deprecated public WifiScanner.HotlistSettings();
+    field @Deprecated public int apLostThreshold;
+    field @Deprecated public android.net.wifi.WifiScanner.BssidInfo[] bssidInfos;
+  }
+
+  public static class WifiScanner.ParcelableScanData implements android.os.Parcelable {
+    ctor public WifiScanner.ParcelableScanData(android.net.wifi.WifiScanner.ScanData[]);
+    method public android.net.wifi.WifiScanner.ScanData[] getResults();
+    field public android.net.wifi.WifiScanner.ScanData[] mResults;
+  }
+
+  public static class WifiScanner.ParcelableScanResults implements android.os.Parcelable {
+    ctor public WifiScanner.ParcelableScanResults(android.net.wifi.ScanResult[]);
+    method public android.net.wifi.ScanResult[] getResults();
+    field public android.net.wifi.ScanResult[] mResults;
+  }
+
+  public static class WifiScanner.ScanData implements android.os.Parcelable {
+    ctor public WifiScanner.ScanData(int, int, android.net.wifi.ScanResult[]);
+    ctor public WifiScanner.ScanData(android.net.wifi.WifiScanner.ScanData);
+    method public int getFlags();
+    method public int getId();
+    method public android.net.wifi.ScanResult[] getResults();
+  }
+
+  public static interface WifiScanner.ScanListener extends android.net.wifi.WifiScanner.ActionListener {
+    method public void onFullResult(android.net.wifi.ScanResult);
+    method @Deprecated public void onPeriodChanged(int);
+    method public void onResults(android.net.wifi.WifiScanner.ScanData[]);
+  }
+
+  public static class WifiScanner.ScanSettings implements android.os.Parcelable {
+    ctor public WifiScanner.ScanSettings();
+    field public int band;
+    field public android.net.wifi.WifiScanner.ChannelSpec[] channels;
+    field @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public final java.util.List<android.net.wifi.WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworks;
+    field public boolean hideFromAppOps;
+    field public boolean ignoreLocationSettings;
+    field @Deprecated public int maxPeriodInMs;
+    field @Deprecated public int maxScansToCache;
+    field @Deprecated public int numBssidsPerScan;
+    field @Deprecated public int periodInMs;
+    field @Deprecated public int reportEvents;
+    field @Deprecated public int stepCount;
+    field @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public int type;
+  }
+
+  public static class WifiScanner.ScanSettings.HiddenNetwork {
+    ctor public WifiScanner.ScanSettings.HiddenNetwork(@NonNull String);
+    field @NonNull public final String ssid;
+  }
+
+  @Deprecated public static interface WifiScanner.WifiChangeListener extends android.net.wifi.WifiScanner.ActionListener {
+    method @Deprecated public void onChanging(android.net.wifi.ScanResult[]);
+    method @Deprecated public void onQuiescence(android.net.wifi.ScanResult[]);
+  }
+
+  @Deprecated public static class WifiScanner.WifiChangeSettings implements android.os.Parcelable {
+    ctor @Deprecated public WifiScanner.WifiChangeSettings();
+    field @Deprecated public android.net.wifi.WifiScanner.BssidInfo[] bssidInfos;
+    field @Deprecated public int lostApSampleSize;
+    field @Deprecated public int minApsBreachingThreshold;
+    field @Deprecated public int periodInMs;
+    field @Deprecated public int rssiSampleSize;
+    field @Deprecated public int unchangedSampleSize;
+  }
+
+  public final class WifiUsabilityStatsEntry implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getCellularDataNetworkType();
+    method public int getCellularSignalStrengthDb();
+    method public int getCellularSignalStrengthDbm();
+    method public int getLinkSpeedMbps();
+    method public int getProbeElapsedTimeSinceLastUpdateMillis();
+    method public int getProbeMcsRateSinceLastUpdate();
+    method public int getProbeStatusSinceLastUpdate();
+    method public int getRssi();
+    method public int getRxLinkSpeedMbps();
+    method public long getTimeStampMillis();
+    method public long getTotalBackgroundScanTimeMillis();
+    method public long getTotalBeaconRx();
+    method public long getTotalCcaBusyFreqTimeMillis();
+    method public long getTotalHotspot2ScanTimeMillis();
+    method public long getTotalNanScanTimeMillis();
+    method public long getTotalPnoScanTimeMillis();
+    method public long getTotalRadioOnFreqTimeMillis();
+    method public long getTotalRadioOnTimeMillis();
+    method public long getTotalRadioRxTimeMillis();
+    method public long getTotalRadioTxTimeMillis();
+    method public long getTotalRoamScanTimeMillis();
+    method public long getTotalRxSuccess();
+    method public long getTotalScanTimeMillis();
+    method public long getTotalTxBad();
+    method public long getTotalTxRetries();
+    method public long getTotalTxSuccess();
+    method public boolean isSameRegisteredCell();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiUsabilityStatsEntry> CREATOR;
+    field public static final int PROBE_STATUS_FAILURE = 3; // 0x3
+    field public static final int PROBE_STATUS_NO_PROBE = 1; // 0x1
+    field public static final int PROBE_STATUS_SUCCESS = 2; // 0x2
+    field public static final int PROBE_STATUS_UNKNOWN = 0; // 0x0
+  }
+
+}
+
+package android.net.wifi.aware {
+
+  public class DiscoverySession implements java.lang.AutoCloseable {
+    method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]);
+  }
+
+  public class WifiAwareSession implements java.lang.AutoCloseable {
+    method public android.net.NetworkSpecifier createNetworkSpecifierPmk(int, @NonNull byte[], @NonNull byte[]);
+  }
+
+}
+
+package android.net.wifi.hotspot2 {
+
+  public final class OsuProvider implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public String getFriendlyName();
+    method @Nullable public android.net.Uri getServerUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.OsuProvider> CREATOR;
+  }
+
+  public final class PasspointConfiguration implements android.os.Parcelable {
+    method public int getMeteredOverride();
+    method public boolean isAutojoinEnabled();
+    method public boolean isMacRandomizationEnabled();
+  }
+
+  public abstract class ProvisioningCallback {
+    ctor public ProvisioningCallback();
+    method public abstract void onProvisioningComplete();
+    method public abstract void onProvisioningFailure(int);
+    method public abstract void onProvisioningStatus(int);
+    field public static final int OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION = 22; // 0x16
+    field public static final int OSU_FAILURE_AP_CONNECTION = 1; // 0x1
+    field public static final int OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU = 8; // 0x8
+    field public static final int OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE = 17; // 0x11
+    field public static final int OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE = 21; // 0x15
+    field public static final int OSU_FAILURE_NO_OSU_ACTIVITY_FOUND = 14; // 0xe
+    field public static final int OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE = 19; // 0x13
+    field public static final int OSU_FAILURE_NO_PPS_MO = 16; // 0x10
+    field public static final int OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE = 18; // 0x12
+    field public static final int OSU_FAILURE_OSU_PROVIDER_NOT_FOUND = 23; // 0x17
+    field public static final int OSU_FAILURE_PROVISIONING_ABORTED = 6; // 0x6
+    field public static final int OSU_FAILURE_PROVISIONING_NOT_AVAILABLE = 7; // 0x7
+    field public static final int OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES = 20; // 0x14
+    field public static final int OSU_FAILURE_SERVER_CONNECTION = 3; // 0x3
+    field public static final int OSU_FAILURE_SERVER_URL_INVALID = 2; // 0x2
+    field public static final int OSU_FAILURE_SERVER_VALIDATION = 4; // 0x4
+    field public static final int OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION = 5; // 0x5
+    field public static final int OSU_FAILURE_SOAP_MESSAGE_EXCHANGE = 11; // 0xb
+    field public static final int OSU_FAILURE_START_REDIRECT_LISTENER = 12; // 0xc
+    field public static final int OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER = 13; // 0xd
+    field public static final int OSU_FAILURE_UNEXPECTED_COMMAND_TYPE = 9; // 0x9
+    field public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS = 15; // 0xf
+    field public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE = 10; // 0xa
+    field public static final int OSU_STATUS_AP_CONNECTED = 2; // 0x2
+    field public static final int OSU_STATUS_AP_CONNECTING = 1; // 0x1
+    field public static final int OSU_STATUS_INIT_SOAP_EXCHANGE = 6; // 0x6
+    field public static final int OSU_STATUS_REDIRECT_RESPONSE_RECEIVED = 8; // 0x8
+    field public static final int OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS = 11; // 0xb
+    field public static final int OSU_STATUS_SECOND_SOAP_EXCHANGE = 9; // 0x9
+    field public static final int OSU_STATUS_SERVER_CONNECTED = 5; // 0x5
+    field public static final int OSU_STATUS_SERVER_CONNECTING = 3; // 0x3
+    field public static final int OSU_STATUS_SERVER_VALIDATED = 4; // 0x4
+    field public static final int OSU_STATUS_THIRD_SOAP_EXCHANGE = 10; // 0xa
+    field public static final int OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE = 7; // 0x7
+  }
+
+}
+
+package android.net.wifi.p2p {
+
+  public final class WifiP2pGroupList implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.net.wifi.p2p.WifiP2pGroup> getGroupList();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroupList> CREATOR;
+  }
+
+  public class WifiP2pManager {
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void deletePersistentGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public void requestPersistentGroupInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setDeviceName(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull String, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setMiracastMode(int);
+    method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setWfdInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pWfdInfo, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setWifiP2pChannels(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void startListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void stopListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+    field public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED";
+    field public static final int MIRACAST_DISABLED = 0; // 0x0
+    field public static final int MIRACAST_SINK = 2; // 0x2
+    field public static final int MIRACAST_SOURCE = 1; // 0x1
+  }
+
+  public static interface WifiP2pManager.PersistentGroupInfoListener {
+    method public void onPersistentGroupInfoAvailable(@NonNull android.net.wifi.p2p.WifiP2pGroupList);
+  }
+
+}
+
+package android.net.wifi.rtt {
+
+  public static final class RangingRequest.Builder {
+    method public android.net.wifi.rtt.RangingRequest.Builder addResponder(@NonNull android.net.wifi.rtt.ResponderConfig);
+  }
+
+  public final class RangingResult implements android.os.Parcelable {
+    method @NonNull public byte[] getLci();
+    method @NonNull public byte[] getLcr();
+  }
+
+  public final class ResponderConfig implements android.os.Parcelable {
+    ctor public ResponderConfig(@NonNull android.net.MacAddress, int, boolean, int, int, int, int, int);
+    ctor public ResponderConfig(@NonNull android.net.wifi.aware.PeerHandle, int, boolean, int, int, int, int, int);
+    method public int describeContents();
+    method public static android.net.wifi.rtt.ResponderConfig fromScanResult(android.net.wifi.ScanResult);
+    method public static android.net.wifi.rtt.ResponderConfig fromWifiAwarePeerHandleWithDefaults(android.net.wifi.aware.PeerHandle);
+    method public static android.net.wifi.rtt.ResponderConfig fromWifiAwarePeerMacAddressWithDefaults(android.net.MacAddress);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
+    field public static final int CHANNEL_WIDTH_20MHZ = 0; // 0x0
+    field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1
+    field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
+    field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderConfig> CREATOR;
+    field public static final int PREAMBLE_HE = 3; // 0x3
+    field public static final int PREAMBLE_HT = 1; // 0x1
+    field public static final int PREAMBLE_LEGACY = 0; // 0x0
+    field public static final int PREAMBLE_VHT = 2; // 0x2
+    field public static final int RESPONDER_AP = 0; // 0x0
+    field public static final int RESPONDER_AWARE = 4; // 0x4
+    field public static final int RESPONDER_P2P_CLIENT = 3; // 0x3
+    field public static final int RESPONDER_P2P_GO = 2; // 0x2
+    field public static final int RESPONDER_STA = 1; // 0x1
+    field public final int centerFreq0;
+    field public final int centerFreq1;
+    field public final int channelWidth;
+    field public final int frequency;
+    field public final android.net.MacAddress macAddress;
+    field public final android.net.wifi.aware.PeerHandle peerHandle;
+    field public final int preamble;
+    field public final int responderType;
+    field public final boolean supports80211mc;
+  }
+
+  public final class ResponderLocation implements android.os.Parcelable {
+    method public boolean getExtraInfoOnAssociationIndication();
+  }
+
+  public class WifiRttManager {
+    method @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE}) public void cancelRanging(@Nullable android.os.WorkSource);
+    method @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_WIFI_STATE}) public void startRanging(@Nullable android.os.WorkSource, @NonNull android.net.wifi.rtt.RangingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.rtt.RangingResultCallback);
+  }
+
+}
+
diff --git a/wifi/api/system-removed.txt b/wifi/api/system-removed.txt
new file mode 100644
index 0000000..35f9726
--- /dev/null
+++ b/wifi/api/system-removed.txt
@@ -0,0 +1,16 @@
+// Signature format: 2.0
+package android.net.wifi {
+
+  @Deprecated public class BatchedScanResult implements android.os.Parcelable {
+    ctor public BatchedScanResult();
+    ctor public BatchedScanResult(android.net.wifi.BatchedScanResult);
+    field public final java.util.List<android.net.wifi.ScanResult> scanResults;
+    field public boolean truncated;
+  }
+
+  public class ScanResult implements android.os.Parcelable {
+    field public boolean untrusted;
+  }
+
+}
+
diff --git a/wifi/java/android/net/wifi/WifiMigration.java b/wifi/java/android/net/wifi/WifiMigration.java
index 008b18b..f2a1aec 100755
--- a/wifi/java/android/net/wifi/WifiMigration.java
+++ b/wifi/java/android/net/wifi/WifiMigration.java
@@ -16,25 +16,252 @@
 
 package android.net.wifi;
 
+import static android.os.Environment.getDataMiscCeDirectory;
+import static android.os.Environment.getDataMiscDirectory;
+
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.provider.Settings;
+import android.util.AtomicFile;
+import android.util.SparseArray;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
 
 /**
  * Class used to provide one time hooks for existing OEM devices to migrate their config store
- * data and other settings to the wifi mainline module.
+ * data and other settings to the wifi apex.
  * @hide
  */
 @SystemApi
 public final class WifiMigration {
+    /**
+     * Directory to read the wifi config store files from under.
+     */
+    private static final String LEGACY_WIFI_STORE_DIRECTORY_NAME = "wifi";
+    /**
+     * Config store file for general shared store file.
+     * AOSP Path on Android 10: /data/misc/wifi/WifiConfigStore.xml
+     */
+    public static final int STORE_FILE_SHARED_GENERAL = 0;
+    /**
+     * Config store file for softap shared store file.
+     * AOSP Path on Android 10: /data/misc/wifi/softap.conf
+     */
+    public static final int STORE_FILE_SHARED_SOFTAP = 1;
+    /**
+     * Config store file for general user store file.
+     * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStore.xml
+     */
+    public static final int STORE_FILE_USER_GENERAL = 2;
+    /**
+     * Config store file for network suggestions user store file.
+     * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStoreNetworkSuggestions.xml
+     */
+    public static final int STORE_FILE_USER_NETWORK_SUGGESTIONS = 3;
+
+    /** @hide */
+    @IntDef(prefix = { "STORE_FILE_SHARED_" }, value = {
+            STORE_FILE_SHARED_GENERAL,
+            STORE_FILE_SHARED_SOFTAP,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SharedStoreFileId { }
+
+    /** @hide */
+    @IntDef(prefix = { "STORE_FILE_USER_" }, value = {
+            STORE_FILE_USER_GENERAL,
+            STORE_FILE_USER_NETWORK_SUGGESTIONS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UserStoreFileId { }
+
+    /**
+     * Mapping of Store file Id to Store file names.
+     *
+     * NOTE: This is the default path for the files on AOSP devices. If the OEM has modified
+     * the path or renamed the files, please edit this appropriately.
+     */
+    private static final SparseArray<String> STORE_ID_TO_FILE_NAME =
+            new SparseArray<String>() {{
+                put(STORE_FILE_SHARED_GENERAL, "WifiConfigStore.xml");
+                put(STORE_FILE_SHARED_SOFTAP, "softap.conf");
+                put(STORE_FILE_USER_GENERAL, "WifiConfigStore.xml");
+                put(STORE_FILE_USER_NETWORK_SUGGESTIONS, "WifiConfigStoreNetworkSuggestions.xml");
+            }};
+
+    /**
+     * Pre-apex wifi shared folder.
+     */
+    private static File getLegacyWifiSharedDirectory() {
+        return new File(getDataMiscDirectory(), LEGACY_WIFI_STORE_DIRECTORY_NAME);
+    }
+
+    /**
+     * Pre-apex wifi user folder.
+     */
+    private static File getLegacyWifiUserDirectory(int userId) {
+        return new File(getDataMiscCeDirectory(userId), LEGACY_WIFI_STORE_DIRECTORY_NAME);
+    }
+
+    /**
+     * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
+     * data integrity.
+     */
+    private static AtomicFile getSharedAtomicFile(@SharedStoreFileId int storeFileId) {
+        return new AtomicFile(new File(
+                getLegacyWifiSharedDirectory(),
+                STORE_ID_TO_FILE_NAME.get(storeFileId)));
+    }
+
+    /**
+     * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
+     * data integrity.
+     */
+    private static AtomicFile getUserAtomicFile(@UserStoreFileId  int storeFileId, int userId) {
+        return new AtomicFile(new File(
+                getLegacyWifiUserDirectory(userId),
+                STORE_ID_TO_FILE_NAME.get(storeFileId)));
+    }
 
     private WifiMigration() { }
 
     /**
+     * Load data from legacy shared wifi config store file.
+     * TODO(b/149418926): Add XSD for the AOSP file format for each file from R.
+     * <p>
+     * Note:
+     * <li>OEMs need to change the implementation of
+     * {@link #convertAndRetrieveSharedConfigStoreFile(int)} only if their existing config store
+     * format or file locations differs from the vanilla AOSP implementation.</li>
+     * <li>The wifi apex will invoke
+     * {@link #convertAndRetrieveSharedConfigStoreFile(int)}
+     * method on every bootup, it is the responsibility of the OEM implementation to ensure that
+     * they perform the necessary in place conversion of their config store file to conform to the
+     * AOSP format. The OEM should ensure that the method should only return the
+     * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
+     * <li>Once the migration is done, the apex will invoke
+     * {@link #removeSharedConfigStoreFile(int)} to delete the store file.</li>
+     * <li>The only relevant invocation of {@link #convertAndRetrieveSharedConfigStoreFile(int)}
+     * occurs when a previously released device upgrades to the wifi apex from an OEM
+     * implementation of the wifi stack.
+     * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
+     * permissions, etc). Since the wifi service continues to run inside system_server process, this
+     * method will be called from the same context (so ideally the file should still be accessible).
+     * </li>
+     *
+     * @param storeFileId Identifier for the config store file. One of
+     * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
+     * @return Instance of {@link InputStream} for migrating data, null if no migration is
+     * necessary.
+     * @throws IllegalArgumentException on invalid storeFileId.
+     */
+    @Nullable
+    public static InputStream convertAndRetrieveSharedConfigStoreFile(
+            @SharedStoreFileId int storeFileId) {
+        if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId !=  STORE_FILE_SHARED_SOFTAP) {
+            throw new IllegalArgumentException("Invalid shared store file id");
+        }
+        try {
+            // OEMs should do conversions necessary here before returning the stream.
+            return getSharedAtomicFile(storeFileId).openRead();
+        } catch (FileNotFoundException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Remove the legacy shared wifi config store file.
+     *
+     * @param storeFileId Identifier for the config store file. One of
+     * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
+     * @throws IllegalArgumentException on invalid storeFileId.
+     */
+    public static void removeSharedConfigStoreFile(@SharedStoreFileId int storeFileId) {
+        if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId !=  STORE_FILE_SHARED_SOFTAP) {
+            throw new IllegalArgumentException("Invalid shared store file id");
+        }
+        getSharedAtomicFile(storeFileId).delete();
+    }
+
+    /**
+     * Load data from legacy user wifi config store file.
+     * TODO(b/149418926): Add XSD for the AOSP file format for each file from R.
+     * <p>
+     * Note:
+     * <li>OEMs need to change the implementation of
+     * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} only if their existing config
+     * store format or file locations differs from the vanilla AOSP implementation.</li>
+     * <li>The wifi apex will invoke
+     * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)}
+     * method on every bootup, it is the responsibility of the OEM implementation to ensure that
+     * they perform the necessary in place conversion of their config store file to conform to the
+     * AOSP format. The OEM should ensure that the method should only return the
+     * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
+     * <li>Once the migration is done, the apex will invoke
+     * {@link #removeUserConfigStoreFile(int, UserHandle)} to delete the store file.</li>
+     * <li>The only relevant invocation of
+     * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} occurs when a previously
+     * released device upgrades to the wifi apex from an OEM implementation of the wifi
+     * stack.
+     * </li>
+     * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
+     * permissions, etc). Since the wifi service continues to run inside system_server process, this
+     * method will be called from the same context (so ideally the file should still be accessible).
+     * </li>
+     *
+     * @param storeFileId Identifier for the config store file. One of
+     * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
+     * @param userHandle User handle.
+     * @return Instance of {@link InputStream} for migrating data, null if no migration is
+     * necessary.
+     * @throws IllegalArgumentException on invalid storeFileId or userHandle.
+     */
+    @Nullable
+    public static InputStream convertAndRetrieveUserConfigStoreFile(
+            @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
+        if (storeFileId != STORE_FILE_USER_GENERAL
+                && storeFileId !=  STORE_FILE_USER_NETWORK_SUGGESTIONS) {
+            throw new IllegalArgumentException("Invalid user store file id");
+        }
+        Objects.requireNonNull(userHandle);
+        try {
+            // OEMs should do conversions necessary here before returning the stream.
+            return getUserAtomicFile(storeFileId, userHandle.getIdentifier()).openRead();
+        } catch (FileNotFoundException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Remove the legacy user wifi config store file.
+     *
+     * @param storeFileId Identifier for the config store file. One of
+     * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
+     * @param userHandle User handle.
+     * @throws IllegalArgumentException on invalid storeFileId or userHandle.
+    */
+    public static void removeUserConfigStoreFile(
+            @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
+        if (storeFileId != STORE_FILE_USER_GENERAL
+                && storeFileId !=  STORE_FILE_USER_NETWORK_SUGGESTIONS) {
+            throw new IllegalArgumentException("Invalid user store file id");
+        }
+        Objects.requireNonNull(userHandle);
+        getUserAtomicFile(storeFileId, userHandle.getIdentifier()).delete();
+    }
+
+    /**
      * Container for all the wifi settings data to migrate.
      */
     public static final class SettingsMigrationData implements Parcelable {
@@ -260,7 +487,7 @@
      * <li> This is method is invoked once on the first bootup. OEM can safely delete these settings
      * once the migration is complete. The first & only relevant invocation of
      * {@link #loadFromSettings(Context)} ()} occurs when a previously released
-     * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack.
+     * device upgrades to the wifi apex from an OEM implementation of the wifi stack.
      * </li>
      *
      * @param context Context to use for loading the settings provider.