Merge "Mark ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest#snapshotStartingWindowLayerCoversExactlyOnApp as flaky" into main
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 1b5795f..122e627 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -74,7 +74,15 @@
       ]
     },
     {
-      "name": "ExtServicesUnitTests",
+      "name": "ExtServicesUnitTests-tplus",
+      "options": [
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    },
+    {
+      "name": "ExtServicesUnitTests-sminus",
       "options": [
         {
           "exclude-annotation": "androidx.test.filters.FlakyTest"
@@ -142,7 +150,15 @@
      ]
    },
    {
-     "name": "ExtServicesUnitTests",
+     "name": "ExtServicesUnitTests-tplus",
+     "options": [
+       {
+         "exclude-annotation": "androidx.test.filters.FlakyTest"
+       }
+     ]
+   },
+   {
+     "name": "ExtServicesUnitTests-sminus",
      "options": [
        {
          "exclude-annotation": "androidx.test.filters.FlakyTest"
diff --git a/core/api/current.txt b/core/api/current.txt
index 0d73695..df8f581 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -4616,7 +4616,9 @@
 
   public class ActivityManager {
     method public int addAppTask(@NonNull android.app.Activity, @NonNull android.content.Intent, @Nullable android.app.ActivityManager.TaskDescription, @NonNull android.graphics.Bitmap);
+    method public void addStartInfoTimestamp(@IntRange(from=android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START, to=android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) int, long);
     method public void appNotResponding(@NonNull String);
+    method public void clearApplicationStartInfoCompletionListener();
     method public boolean clearApplicationUserData();
     method public void clearWatchHeapLimit();
     method @RequiresPermission(android.Manifest.permission.DUMP) public void dumpPackageState(java.io.FileDescriptor, String);
@@ -4624,6 +4626,7 @@
     method public java.util.List<android.app.ActivityManager.AppTask> getAppTasks();
     method public android.content.pm.ConfigurationInfo getDeviceConfigurationInfo();
     method @NonNull public java.util.List<android.app.ApplicationExitInfo> getHistoricalProcessExitReasons(@Nullable String, @IntRange(from=0) int, @IntRange(from=0) int);
+    method @NonNull public java.util.List<android.app.ApplicationStartInfo> getHistoricalProcessStartReasons(@IntRange(from=0) int);
     method public int getLargeMemoryClass();
     method public int getLauncherLargeIconDensity();
     method public int getLauncherLargeIconSize();
@@ -4650,6 +4653,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 setApplicationStartInfoCompletionListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.ApplicationStartInfo>);
     method public void setProcessStateSummary(@Nullable byte[]);
     method public static void setVrThread(int);
     method public void setWatchHeapLimit(long);
@@ -5230,6 +5234,57 @@
     field public static final int REASON_USER_STOPPED = 11; // 0xb
   }
 
+  public final class ApplicationStartInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getDefiningUid();
+    method @Nullable public android.content.Intent getIntent();
+    method public int getLaunchMode();
+    method public int getPackageUid();
+    method public int getPid();
+    method @NonNull public String getProcessName();
+    method public int getRealUid();
+    method public int getReason();
+    method public int getStartType();
+    method public int getStartupState();
+    method @NonNull public java.util.Map<java.lang.Integer,java.lang.Long> getStartupTimestamps();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.ApplicationStartInfo> CREATOR;
+    field public static final int LAUNCH_MODE_SINGLE_INSTANCE = 2; // 0x2
+    field public static final int LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK = 4; // 0x4
+    field public static final int LAUNCH_MODE_SINGLE_TASK = 3; // 0x3
+    field public static final int LAUNCH_MODE_SINGLE_TOP = 1; // 0x1
+    field public static final int LAUNCH_MODE_STANDARD = 0; // 0x0
+    field public static final int STARTUP_STATE_ERROR = 1; // 0x1
+    field public static final int STARTUP_STATE_FIRST_FRAME_DRAWN = 2; // 0x2
+    field public static final int STARTUP_STATE_STARTED = 0; // 0x0
+    field public static final int START_REASON_ALARM = 0; // 0x0
+    field public static final int START_REASON_BACKUP = 1; // 0x1
+    field public static final int START_REASON_BOOT_COMPLETE = 2; // 0x2
+    field public static final int START_REASON_BROADCAST = 3; // 0x3
+    field public static final int START_REASON_CONTENT_PROVIDER = 4; // 0x4
+    field public static final int START_REASON_JOB = 5; // 0x5
+    field public static final int START_REASON_LAUNCHER = 6; // 0x6
+    field public static final int START_REASON_LAUNCHER_RECENTS = 7; // 0x7
+    field public static final int START_REASON_OTHER = 8; // 0x8
+    field public static final int START_REASON_PUSH = 9; // 0x9
+    field public static final int START_REASON_SERVICE = 10; // 0xa
+    field public static final int START_REASON_START_ACTIVITY = 11; // 0xb
+    field public static final int START_TIMESTAMP_APPLICATION_ONCREATE = 2; // 0x2
+    field public static final int START_TIMESTAMP_BIND_APPLICATION = 3; // 0x3
+    field public static final int START_TIMESTAMP_FIRST_FRAME = 4; // 0x4
+    field public static final int START_TIMESTAMP_FORK = 1; // 0x1
+    field public static final int START_TIMESTAMP_FULLY_DRAWN = 5; // 0x5
+    field public static final int START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME = 6; // 0x6
+    field public static final int START_TIMESTAMP_LAUNCH = 0; // 0x0
+    field public static final int START_TIMESTAMP_RESERVED_RANGE_DEVELOPER = 30; // 0x1e
+    field public static final int START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START = 21; // 0x15
+    field public static final int START_TIMESTAMP_RESERVED_RANGE_SYSTEM = 20; // 0x14
+    field public static final int START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE = 7; // 0x7
+    field public static final int START_TYPE_COLD = 0; // 0x0
+    field public static final int START_TYPE_HOT = 2; // 0x2
+    field public static final int START_TYPE_WARM = 1; // 0x1
+  }
+
   public final class AsyncNotedAppOp implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public String getAttributionTag();
@@ -12764,6 +12819,7 @@
     field public static final String FEATURE_TELEPHONY_RADIO_ACCESS = "android.hardware.telephony.radio.access";
     field public static final String FEATURE_TELEPHONY_SUBSCRIPTION = "android.hardware.telephony.subscription";
     field @Deprecated public static final String FEATURE_TELEVISION = "android.hardware.type.television";
+    field public static final String FEATURE_THREADNETWORK = "android.hardware.threadnetwork";
     field public static final String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen";
     field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch";
     field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct";
@@ -42154,6 +42210,7 @@
     method public android.telecom.GatewayInfo getGatewayInfo();
     method public android.net.Uri getHandle();
     method public int getHandlePresentation();
+    method @NonNull public String getId();
     method public android.os.Bundle getIntentExtras();
     method public final int getState();
     method public android.telecom.StatusHints getStatusHints();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index b18584b..77168e3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -535,6 +535,7 @@
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
     method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public void forceStopPackage(String);
     method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public static int getCurrentUser();
+    method @NonNull @RequiresPermission(android.Manifest.permission.DUMP) public java.util.List<android.app.ApplicationStartInfo> getExternalHistoricalProcessStartReasons(@NonNull String, @IntRange(from=0) int);
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getPackageImportance(String);
     method @NonNull public java.util.Collection<java.util.Locale> getSupportedLocales();
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
@@ -13730,6 +13731,7 @@
     method public void requestStreamingState(int);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telecom.StreamingCall> CREATOR;
+    field public static final String EXTRA_CALL_ID = "android.telecom.extra.CALL_ID";
     field public static final int STATE_DISCONNECTED = 3; // 0x3
     field public static final int STATE_HOLDING = 2; // 0x2
     field public static final int STATE_STREAMING = 1; // 0x1
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 37a1e62..b4f6d6f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -72,6 +72,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -107,6 +108,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 /**
  * <p>
@@ -3978,8 +3980,6 @@
      *
      * @return a list of {@link ApplicationStartInfo} records matching the criteria, sorted in
      *         the order from most recent to least recent.
-     *
-     * @hide
      */
     @NonNull
     public List<ApplicationStartInfo> getHistoricalProcessStartReasons(
@@ -4011,6 +4011,7 @@
      * @hide
      */
     @NonNull
+    @SystemApi
     @RequiresPermission(Manifest.permission.DUMP)
     public List<ApplicationStartInfo> getExternalHistoricalProcessStartReasons(
             @NonNull String packageName, @IntRange(from = 0) int maxNum) {
@@ -4024,18 +4025,6 @@
     }
 
     /**
-     * Callback to receive {@link ApplicationStartInfo} object once recording of startup related
-     * metrics is complete.
-     * Use with {@link #setApplicationStartInfoCompleteListener}.
-     *
-     * @hide
-     */
-    public interface ApplicationStartInfoCompleteListener {
-        /** {@link ApplicationStartInfo} is complete, no more info will be added. */
-        void onApplicationStartInfoComplete(@NonNull ApplicationStartInfo applicationStartInfo);
-    }
-
-    /**
      * Sets a callback to be notified when the {@link ApplicationStartInfo} records of this startup
      * are complete.
      *
@@ -4054,19 +4043,16 @@
      *                    complete. Will replace existing listener if one is already attached.
      *
      * @throws IllegalArgumentException if executor or listener are null.
-     *
-     * @hide
      */
-    public void setApplicationStartInfoCompleteListener(@NonNull final Executor executor,
-            @NonNull final ApplicationStartInfoCompleteListener listener) {
+    public void setApplicationStartInfoCompletionListener(@NonNull final Executor executor,
+            @NonNull final Consumer<ApplicationStartInfo> listener) {
         Preconditions.checkNotNull(executor, "executor cannot be null");
         Preconditions.checkNotNull(listener, "listener cannot be null");
         IApplicationStartInfoCompleteListener callback =
                 new IApplicationStartInfoCompleteListener.Stub() {
             @Override
             public void onApplicationStartInfoComplete(ApplicationStartInfo applicationStartInfo) {
-                executor.execute(() ->
-                        listener.onApplicationStartInfoComplete(applicationStartInfo));
+                executor.execute(() -> listener.accept(applicationStartInfo));
             }
         };
         try {
@@ -4077,13 +4063,42 @@
     }
 
     /**
-     * Removes the callback set by {@link #setApplicationStartInfoCompleteListener} if there is one.
-     *
-     * @hide
+     * Removes the callback set by {@link #setApplicationStartInfoCompletionListener} if there is one.
      */
-    public void removeApplicationStartInfoCompleteListener() {
+    public void clearApplicationStartInfoCompletionListener() {
         try {
-            getService().removeApplicationStartInfoCompleteListener(mContext.getUserId());
+            getService().clearApplicationStartInfoCompleteListener(mContext.getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Adds an optional developer supplied timestamp to the calling apps most recent
+     * {@link ApplicationStartInfo}. This is in addition to system recorded timestamps.
+     *
+     * <p class="note"> Note: timestamps added after {@link Activity#reportFullyDrawn} is called
+     * will be discarded.</p>
+     *
+     * <p class="note"> Note: will overwrite existing timestamp if called with same key.</p>
+     *
+     * @param key         Unique key for timestamp. Must be greater than
+     *                    {@link ApplicationStartInfo#START_TIMESTAMP_RESERVED_RANGE_SYSTEM} and
+     *                    less than or equal to
+     *                    {@link ApplicationStartInfo#START_TIMESTAMP_RESERVED_RANGE_DEVELOPER}.
+     *                    Will thow {@link java.lang.IllegalArgumentException} if not in range.
+     * @param timestampNs Clock monotonic time in nanoseconds of event to be recorded.
+     */
+    public void addStartInfoTimestamp(@IntRange(
+            from = ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START,
+            to = ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) int key,
+            long timestampNs) {
+        if (key <= ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_SYSTEM
+                || key > ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) {
+            throw new IllegalArgumentException("Key not in allowed range.");
+        }
+        try {
+            getService().addStartInfoTimestamp(key, timestampNs, mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java
index 5e2a4ca..f5fb6ed 100644
--- a/core/java/android/app/ApplicationStartInfo.java
+++ b/core/java/android/app/ApplicationStartInfo.java
@@ -21,20 +21,21 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.content.Intent;
+import android.icu.text.SimpleDateFormat;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
+import android.util.ArrayMap;
 
-import java.lang.annotation.ElementType;
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Provide information related to a processes startup.
- *
- * @hide
  */
 public final class ApplicationStartInfo implements Parcelable {
 
@@ -78,14 +79,14 @@
     /** Process started due to click app icon or widget from launcher. */
     public static final int START_REASON_LAUNCHER = 6;
 
+    /** Process started from launcher recents. */
+    public static final int START_REASON_LAUNCHER_RECENTS = 7;
+
     /** Process started not for any of the listed reasons. */
-    public static final int START_REASON_OTHER = 7;
+    public static final int START_REASON_OTHER = 8;
 
     /** Process started due to push message. */
-    public static final int START_REASON_PUSH = 8;
-
-    /** Process started to resume activity. */
-    public static final int START_REASON_RESUMED_ACTIVITY = 9;
+    public static final int START_REASON_PUSH = 9;
 
     /** Process service started. */
     public static final int START_REASON_SERVICE = 10;
@@ -136,11 +137,21 @@
      */
     public static final int LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK = 4;
 
+    /** The end of the range, beginning with 0, reserved for system timestamps.*/
+    public static final int START_TIMESTAMP_RESERVED_RANGE_SYSTEM = 20;
+
+    /** The beginning of the range reserved for developer supplied timestamps.*/
+    public static final int START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START =
+            START_TIMESTAMP_RESERVED_RANGE_SYSTEM + 1;
+
+    /** The end of the range reserved for developer supplied timestamps.*/
+    public static final int START_TIMESTAMP_RESERVED_RANGE_DEVELOPER = 30;
+
     /** Clock monotonic timestamp of launch started. */
     public static final int START_TIMESTAMP_LAUNCH = 0;
 
-    /** Clock monotonic timestamp of finish java classloading. */
-    public static final int START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE = 1;
+    /** Clock monotonic timestamp of process fork. */
+    public static final int START_TIMESTAMP_FORK = 1;
 
     /** Clock monotonic timestamp of Application onCreate called. */
     public static final int START_TIMESTAMP_APPLICATION_ONCREATE = 2;
@@ -154,6 +165,12 @@
     /** Clock monotonic timestamp of reportFullyDrawn called by application. */
     public static final int START_TIMESTAMP_FULLY_DRAWN = 5;
 
+    /** Clock monotonic timestamp of initial renderthread frame. */
+    public static final int START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME = 6;
+
+    /** Clock monotonic timestamp of surfaceflinger composition complete. */
+    public static final int START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE = 7;
+
     /**
      * @see #getStartupState
      */
@@ -192,7 +209,7 @@
     /**
      * @see #getStartupTimestamps
      */
-    private Map<@StartupTimestamp Integer, Long> mStartupTimestampsNs;
+    private ArrayMap<Integer, Long> mStartupTimestampsNs;
 
     /**
      * @see #getStartType
@@ -235,9 +252,9 @@
                 START_REASON_CONTENT_PROVIDER,
                 START_REASON_JOB,
                 START_REASON_LAUNCHER,
+                START_REASON_LAUNCHER_RECENTS,
                 START_REASON_OTHER,
                 START_REASON_PUSH,
-                START_REASON_RESUMED_ACTIVITY,
                 START_REASON_SERVICE,
                 START_REASON_START_ACTIVITY,
             })
@@ -273,22 +290,6 @@
     public @interface LaunchMode {}
 
     /**
-     * @hide *
-     */
-    @IntDef(
-            prefix = {"START_TIMESTAMP_"},
-            value = {
-                START_TIMESTAMP_LAUNCH,
-                START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE,
-                START_TIMESTAMP_APPLICATION_ONCREATE,
-                START_TIMESTAMP_BIND_APPLICATION,
-                START_TIMESTAMP_FULLY_DRAWN,
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
-    public @interface StartupTimestamp {}
-
-    /**
      * @see #getStartupState
      * @hide
      */
@@ -348,9 +349,12 @@
      * @see #getStartupTimestamps
      * @hide
      */
-    public void addStartupTimestamp(@StartupTimestamp int key, long timestampNs) {
+    public void addStartupTimestamp(int key, long timestampNs) {
+        if (key < 0 || key > START_TIMESTAMP_RESERVED_RANGE_DEVELOPER) {
+            return;
+        }
         if (mStartupTimestampsNs == null) {
-            mStartupTimestampsNs = new HashMap<@StartupTimestamp Integer, Long>();
+            mStartupTimestampsNs = new ArrayMap<Integer, Long>();
         }
         mStartupTimestampsNs.put(key, timestampNs);
     }
@@ -475,9 +479,9 @@
      * dependant on devloper calling {@link Activity#reportFullyDrawn}.
      * </p>
      */
-    public @NonNull Map<@StartupTimestamp Integer, Long> getStartupTimestamps() {
+    public @NonNull Map<Integer, Long> getStartupTimestamps() {
         if (mStartupTimestampsNs == null) {
-            mStartupTimestampsNs = new HashMap<@StartupTimestamp Integer, Long>();
+            mStartupTimestampsNs = new ArrayMap<Integer, Long>();
         }
         return mStartupTimestampsNs;
     }
@@ -536,9 +540,12 @@
         dest.writeString(mProcessName);
         dest.writeInt(mReason);
         dest.writeInt(mStartupTimestampsNs.size());
-        for (@StartupTimestamp int key : mStartupTimestampsNs.keySet()) {
-            dest.writeInt(key);
-            dest.writeLong(mStartupTimestampsNs.get(key));
+        Set<Map.Entry<Integer, Long>> timestampEntrySet = mStartupTimestampsNs.entrySet();
+        Iterator<Map.Entry<Integer, Long>> iter = timestampEntrySet.iterator();
+        while (iter.hasNext()) {
+            Map.Entry<Integer, Long> entry = iter.next();
+            dest.writeInt(entry.getKey());
+            dest.writeLong(entry.getValue());
         }
         dest.writeInt(mStartType);
         dest.writeParcelable(mStartIntent, flags);
@@ -599,4 +606,67 @@
                     return new ApplicationStartInfo[size];
                 }
             };
+
+    /** @hide */
+    public void dump(@NonNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix,
+            @NonNull SimpleDateFormat sdf) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(prefix)
+                .append("ApplicationStartInfo ").append(seqSuffix).append(':')
+                .append('\n')
+                .append(" pid=").append(mPid)
+                .append(" realUid=").append(mRealUid)
+                .append(" packageUid=").append(mPackageUid)
+                .append(" definingUid=").append(mDefiningUid)
+                .append(" user=").append(UserHandle.getUserId(mPackageUid))
+                .append('\n')
+                .append(" process=").append(mProcessName)
+                .append(" startupState=").append(mStartupState)
+                .append(" reason=").append(reasonToString(mReason))
+                .append(" startType=").append(startTypeToString(mStartType))
+                .append(" launchMode=").append(mLaunchMode)
+                .append('\n');
+        if (mStartIntent != null) {
+            sb.append(" intent=").append(mStartIntent.toString())
+                .append('\n');
+        }
+        if (mStartupTimestampsNs.size() > 0) {
+            sb.append(" timestamps: ");
+            Set<Map.Entry<Integer, Long>> timestampEntrySet = mStartupTimestampsNs.entrySet();
+            Iterator<Map.Entry<Integer, Long>> iter = timestampEntrySet.iterator();
+            while (iter.hasNext()) {
+                Map.Entry<Integer, Long> entry = iter.next();
+                sb.append(entry.getKey()).append("=").append(entry.getValue()).append(" ");
+            }
+            sb.append('\n');
+        }
+        pw.print(sb.toString());
+    }
+
+    private static String reasonToString(@StartReason int reason) {
+        return switch (reason) {
+            case START_REASON_ALARM -> "ALARM";
+            case START_REASON_BACKUP -> "BACKUP";
+            case START_REASON_BOOT_COMPLETE -> "BOOT COMPLETE";
+            case START_REASON_BROADCAST -> "BROADCAST";
+            case START_REASON_CONTENT_PROVIDER -> "CONTENT PROVIDER";
+            case START_REASON_JOB -> "JOB";
+            case START_REASON_LAUNCHER -> "LAUNCHER";
+            case START_REASON_LAUNCHER_RECENTS -> "LAUNCHER RECENTS";
+            case START_REASON_OTHER -> "OTHER";
+            case START_REASON_PUSH -> "PUSH";
+            case START_REASON_SERVICE -> "SERVICE";
+            case START_REASON_START_ACTIVITY -> "START ACTIVITY";
+            default -> "";
+        };
+    }
+
+    private static String startTypeToString(@StartType int startType) {
+        return switch (startType) {
+            case START_TYPE_COLD -> "COLD";
+            case START_TYPE_WARM -> "WARM";
+            case START_TYPE_HOT -> "HOT";
+            default -> "";
+        };
+    }
 }
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index a8b1688..03baf26 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -724,7 +724,20 @@
      *
      * @param userId      The userId in the multi-user environment.
      */
-    void removeApplicationStartInfoCompleteListener(int userId);
+    void clearApplicationStartInfoCompleteListener(int userId);
+
+
+    /**
+     * Adds a timestamp of the moment called to the calling apps most recent
+     * {@link ApplicationStartInfo}.
+     *
+     *
+     * @param key         Unique key for timestamp.
+     * @param timestampNs Clock monotonic time in nanoseconds of event to be
+     *                    recorded.
+     * @param userId      The userId in the multi-user environment.
+     */
+    void addStartInfoTimestamp(int key, long timestampNs, int userId);
 
     /**
      * Return a list of {@link ApplicationExitInfo} records.
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 8da8442..394f9e7 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -59,7 +59,7 @@
             "file_patterns": ["INotificationManager\\.aidl"]
         },
         {
-            "name": "CtsWindowManagerDeviceTestCases",
+            "name": "CtsWindowManagerDeviceWindow",
             "options": [
                 {
                     "include-filter": "android.server.wm.window.ToastWindowTest"
@@ -244,8 +244,143 @@
                 "(/|^)DeviceFeature[^/]*", "(/|^)Hdmi[^/]*"
             ]
         },
+{
+            "name": "CtsWindowManagerDeviceActivity",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.content.wm.cts"
+                }
+            ],
+            "file_patterns": ["(/|^)ContextImpl.java"]
+        },
         {
-            "name": "CtsWindowManagerTestCases",
+            "name": "CtsWindowManagerDeviceAm",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.content.wm.cts"
+                }
+            ],
+            "file_patterns": ["(/|^)ContextImpl.java"]
+        },
+        {
+            "name": "CtsWindowManagerDeviceBackNavigation",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.content.wm.cts"
+                }
+            ],
+            "file_patterns": ["(/|^)ContextImpl.java"]
+        },
+        {
+            "name": "CtsWindowManagerDeviceDisplay",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.content.wm.cts"
+                }
+            ],
+            "file_patterns": ["(/|^)ContextImpl.java"]
+        },
+        {
+            "name": "CtsWindowManagerDeviceKeyguard",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.content.wm.cts"
+                }
+            ],
+            "file_patterns": ["(/|^)ContextImpl.java"]
+        },
+        {
+            "name": "CtsWindowManagerDeviceInsets",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.content.wm.cts"
+                }
+            ],
+            "file_patterns": ["(/|^)ContextImpl.java"]
+        },
+        {
+            "name": "CtsWindowManagerDeviceTaskFragment",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.content.wm.cts"
+                }
+            ],
+            "file_patterns": ["(/|^)ContextImpl.java"]
+        },
+        {
+            "name": "CtsWindowManagerDeviceScvh",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.content.wm.cts"
+                }
+            ],
+            "file_patterns": ["(/|^)ContextImpl.java"]
+        },
+        {
+            "name": "CtsWindowManagerDeviceWindow",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                },
+                {
+                    "include-filter": "android.content.wm.cts"
+                }
+            ],
+            "file_patterns": ["(/|^)ContextImpl.java"]
+        },
+        {
+            "name": "CtsWindowManagerDeviceOther",
             "options": [
                 {
                     "exclude-annotation": "androidx.test.filters.FlakyTest"
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 289519d..d9a61ae 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3692,6 +3692,14 @@
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device is capable of communicating with
+     * other devices via Thread network.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_THREADNETWORK = "android.hardware.threadnetwork";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device is capable of communicating with
      * other devices via ultra wideband.
      */
     @SdkConstant(SdkConstantType.FEATURE)
diff --git a/core/java/android/widget/TEST_MAPPING b/core/java/android/widget/TEST_MAPPING
index 49c4093..107cac2 100644
--- a/core/java/android/widget/TEST_MAPPING
+++ b/core/java/android/widget/TEST_MAPPING
@@ -10,10 +10,10 @@
       "file_patterns": ["Toast\\.java"]
     },
     {
-      "name": "CtsWindowManagerDeviceTestCases",
+      "name": "CtsWindowManagerDeviceWindow",
       "options": [
         {
-          "include-filter": "android.server.wm.ToastWindowTest"
+          "include-filter": "android.server.wm.window.ToastWindowTest"
         }
       ],
       "file_patterns": ["Toast\\.java"]
diff --git a/packages/SystemUI/src/com/android/systemui/CoreStartable.java b/packages/SystemUI/src/com/android/systemui/CoreStartable.java
index becf5b3..c07a4d2 100644
--- a/packages/SystemUI/src/com/android/systemui/CoreStartable.java
+++ b/packages/SystemUI/src/com/android/systemui/CoreStartable.java
@@ -53,6 +53,11 @@
     default void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
     }
 
+    /** Called to determine if the dumpable should be registered as critical or normal priority */
+    default boolean isDumpCritical() {
+        return true;
+    }
+
     /** Called immediately after the system broadcasts
      * {@link android.content.Intent#ACTION_LOCKED_BOOT_COMPLETED} or during SysUI startup if the
      * property {@code sys.boot_completed} is already set to 1. The latter typically occurs when
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 522b397..38298cf 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -254,11 +254,16 @@
         }
 
         for (i = 0; i < mServices.length; i++) {
+            final CoreStartable service = mServices[i];
             if (mBootCompleteCache.isBootComplete()) {
-                notifyBootCompleted(mServices[i]);
+                notifyBootCompleted(service);
             }
 
-            dumpManager.registerDumpable(mServices[i].getClass().getSimpleName(), mServices[i]);
+            if (service.isDumpCritical()) {
+                dumpManager.registerCriticalDumpable(service);
+            } else {
+                dumpManager.registerNormalDumpable(service);
+            }
         }
         mSysUIComponent.getInitController().executePostInitTasks();
         log.traceEnd();
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
index 94b2ab1..046ccf16 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
@@ -18,7 +18,6 @@
 
 import com.android.systemui.globalactions.ShutdownUiModule;
 import com.android.systemui.keyguard.CustomizationProvider;
-import com.android.systemui.scene.startable.SceneContainerStartableModule;
 import com.android.systemui.shade.ShadeModule;
 import com.android.systemui.statusbar.NotificationInsetsModule;
 import com.android.systemui.statusbar.QsFrameTranslateModule;
@@ -36,7 +35,6 @@
         QsFrameTranslateModule.class,
         ShadeModule.class,
         ShutdownUiModule.class,
-        SceneContainerStartableModule.class,
         SystemUIBinder.class,
         SystemUIModule.class,
         SystemUICoreStartableModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index c11e485..66813f9 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -112,6 +112,12 @@
             default = true
         )
 
+    /** Only notify group expansion listeners when a change happens. */
+    // TODO(b/292213543): Tracking Bug
+    @JvmField
+    val NOTIFICATION_GROUP_EXPANSION_CHANGE =
+            unreleasedFlag(292213543, "notification_group_expansion_change", teamfood = false)
+
     // 200 - keyguard/lockscreen
     // ** Flag retired **
     // public static final BooleanFlag KEYGUARD_LAYOUT =
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 48790c2..2adc211 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -41,6 +41,8 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
 import com.android.systemui.log.DebugLogger.debugLog
+import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
+import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
 import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
 import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser
 import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
@@ -121,23 +123,26 @@
 
     /**
      * Returns the [UserHandle] of an android user that should handle the notes taking [entryPoint].
-     *
-     * On company owned personally enabled (COPE) devices, if the given [entryPoint] is in the
-     * [FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES] list, the default notes app in the work
-     * profile user will always be launched.
-     *
-     * On non managed devices or devices with other management modes, the current [UserHandle] is
-     * returned.
+     * 1. tail button entry point: In COPE or work profile devices, the user can select whether the
+     *    work or main profile notes app should be launched in the Settings app. In non-management
+     *    or device owner devices, the user can only select main profile notes app.
+     * 2. lock screen quick affordance: since there is no user setting, the main profile notes app
+     *    is used as default for work profile devices while the work profile notes app is used for
+     *    COPE devices.
+     * 3. Other entry point: the current user from [UserTracker.userHandle].
      */
     fun getUserForHandlingNotesTaking(entryPoint: NoteTaskEntryPoint): UserHandle =
-        if (
-            entryPoint in FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES &&
-                devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile
-        ) {
-            userTracker.userProfiles.firstOrNull { userManager.isManagedProfile(it.id) }?.userHandle
-                ?: userTracker.userHandle
-        } else {
-            secureSettings.preferredUser
+        when {
+            entryPoint == TAIL_BUTTON -> secureSettings.preferredUser
+            devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile &&
+                entryPoint == QUICK_AFFORDANCE -> {
+                userTracker.userProfiles
+                    .firstOrNull { userManager.isManagedProfile(it.id) }
+                    ?.userHandle
+                    ?: userTracker.userHandle
+            }
+            // On work profile devices, SysUI always run in the main user.
+            else -> userTracker.userHandle
         }
 
     /**
@@ -267,15 +272,7 @@
                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED
             }
 
-        // If the required user matches the tracking user, the injected context is already a context
-        // of the required user. Avoid calling #createContextAsUser because creating a context for
-        // a user takes time.
-        val userContext =
-            if (user == userTracker.userHandle) {
-                context
-            } else {
-                context.createContextAsUser(user, /* flags= */ 0)
-            }
+        val userContext = context.createContextAsUser(user, /* flags= */ 0)
 
         userContext.packageManager.setComponentEnabledSetting(
             componentName,
@@ -283,7 +280,7 @@
             PackageManager.DONT_KILL_APP,
         )
 
-        debugLog { "setNoteTaskShortcutEnabled - completed: $isEnabled" }
+        debugLog { "setNoteTaskShortcutEnabled for user $user- completed: $enabledState" }
     }
 
     /**
@@ -359,10 +356,12 @@
 
     private val SecureSettings.preferredUser: UserHandle
         get() {
+            val trackingUserId = userTracker.userHandle.identifier
             val userId =
-                secureSettings.getInt(
-                    Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
-                    userTracker.userHandle.identifier,
+                secureSettings.getIntForUser(
+                    /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
+                    /* def= */ trackingUserId,
+                    /* userHandle= */ trackingUserId,
                 )
             return UserHandle.of(userId)
         }
@@ -381,16 +380,6 @@
          * @see com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
          */
         const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package"
-
-        /**
-         * A list of entry points which should be redirected to the work profile default notes app
-         * on company owned personally enabled (COPE) devices.
-         *
-         * Entry points in this list don't let users / admin to select the work or personal default
-         * notes app to be launched.
-         */
-        val FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES =
-            listOf(NoteTaskEntryPoint.TAIL_BUTTON, NoteTaskEntryPoint.QUICK_AFFORDANCE)
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index 26c5219..0a9839e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.scene
 
-import com.android.systemui.scene.domain.startable.SceneContainerStartableModule
 import com.android.systemui.scene.shared.model.SceneContainerConfigModule
 import com.android.systemui.scene.ui.composable.SceneModule
 import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModelModule
@@ -26,7 +25,6 @@
     includes =
         [
             SceneContainerConfigModule::class,
-            SceneContainerStartableModule::class,
             SceneContainerViewModelModule::class,
             SceneModule::class,
         ],
diff --git a/packages/SystemUI/src/com/android/systemui/scene/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/startable/SceneContainerStartable.kt
deleted file mode 100644
index a29e92a..0000000
--- a/packages/SystemUI/src/com/android/systemui/scene/startable/SceneContainerStartable.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2023 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.scene.startable
-
-import com.android.systemui.CoreStartable
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.scene.shared.model.Scene
-import com.android.systemui.scene.shared.model.SceneContainerConfig
-import com.android.systemui.scene.shared.model.SceneContainerNames
-import com.android.systemui.scene.ui.view.SceneWindowRootView
-import com.android.systemui.scene.ui.view.WindowRootView
-import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
-import dagger.Binds
-import dagger.Module
-import dagger.multibindings.ClassKey
-import dagger.multibindings.IntoMap
-import javax.inject.Inject
-import javax.inject.Named
-
-@SysUISingleton
-class SceneContainerStartable
-@Inject
-constructor(
-    private val view: WindowRootView,
-    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) private val viewModel: SceneContainerViewModel,
-    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) private val containerConfig: SceneContainerConfig,
-    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
-    private val scenes: Set<@JvmSuppressWildcards Scene>,
-) : CoreStartable {
-
-    override fun start() {
-        (view as? SceneWindowRootView)?.init(
-            viewModel = viewModel,
-            containerConfig = containerConfig,
-            scenes = scenes,
-        )
-    }
-}
-
-@Module
-interface SceneContainerStartableModule {
-    @Binds
-    @IntoMap
-    @ClassKey(SceneContainerStartable::class)
-    fun bind(impl: SceneContainerStartable): CoreStartable
-}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index e428976..ed7cbff 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -28,6 +28,7 @@
 import static com.android.systemui.classifier.Classifier.GENERIC;
 import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
 import static com.android.systemui.classifier.Classifier.UNLOCK;
+import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
 import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadScroll;
 import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadThreeFingerSwipe;
 import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED;
@@ -70,6 +71,7 @@
 import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.util.MathUtils;
+import android.view.HapticFeedbackConstants;
 import android.view.InputDevice;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -2632,12 +2634,16 @@
         }
 
         if (!mStatusBarStateController.isDozing()) {
-            mVibratorHelper.vibrate(
-                    Process.myUid(),
-                    mView.getContext().getPackageName(),
-                    ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT,
-                    "falsing-additional-tap-required",
-                    TOUCH_VIBRATION_ATTRIBUTES);
+            if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
+                mVibratorHelper.performHapticFeedback(mView, HapticFeedbackConstants.REJECT);
+            } else {
+                mVibratorHelper.vibrate(
+                        Process.myUid(),
+                        mView.getContext().getPackageName(),
+                        ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT,
+                        "falsing-additional-tap-required",
+                        TOUCH_VIBRATION_ATTRIBUTES);
+            }
         }
     }
 
@@ -3504,7 +3510,14 @@
     private void maybeVibrateOnOpening(boolean openingWithTouch) {
         if (mVibrateOnOpening && mBarState != KEYGUARD && mBarState != SHADE_LOCKED) {
             if (!openingWithTouch || !mHasVibratedOnOpen) {
-                mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
+                if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
+                    mVibratorHelper.performHapticFeedback(
+                            mView,
+                            HapticFeedbackConstants.GESTURE_START
+                    );
+                } else {
+                    mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
+                }
                 mHasVibratedOnOpen = true;
                 mShadeLog.v("Vibrating on opening, mHasVibratedOnOpen=true");
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
index 93b9ac6..f381b37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
@@ -83,8 +83,6 @@
 import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.util.CarrierConfigTracker;
 
-import kotlin.Unit;
-
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -99,6 +97,8 @@
 
 import javax.inject.Inject;
 
+import kotlin.Unit;
+
 /** Platform implementation of the network controller. **/
 @SysUISingleton
 public class NetworkControllerImpl extends BroadcastReceiver
@@ -465,7 +465,7 @@
 
         mDemoModeController.addCallback(this);
 
-        mDumpManager.registerDumpable(TAG, this);
+        mDumpManager.registerNormalDumpable(TAG, this);
     }
 
     private final Runnable mClearForceValidated = () -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
index 4568c0c..46af03a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
@@ -21,6 +21,8 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.statusbar.notification.collection.GroupEntry;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -44,14 +46,21 @@
     private final GroupMembershipManager mGroupMembershipManager;
     private final Set<OnGroupExpansionChangeListener> mOnGroupChangeListeners = new HashSet<>();
 
-    // Set of summary keys whose groups are expanded
+    /**
+     * Set of summary keys whose groups are expanded.
+     * NOTE: This should not be modified without notifying listeners, so prefer using
+     * {@code setGroupExpanded} when making changes.
+      */
     private final Set<NotificationEntry> mExpandedGroups = new HashSet<>();
 
+    private final FeatureFlags mFeatureFlags;
+
     @Inject
     public GroupExpansionManagerImpl(DumpManager dumpManager,
-            GroupMembershipManager groupMembershipManager) {
+            GroupMembershipManager groupMembershipManager, FeatureFlags featureFlags) {
         mDumpManager = dumpManager;
         mGroupMembershipManager = groupMembershipManager;
+        mFeatureFlags = featureFlags;
     }
 
     /**
@@ -85,13 +94,17 @@
     @Override
     public void setGroupExpanded(NotificationEntry entry, boolean expanded) {
         final NotificationEntry groupSummary = mGroupMembershipManager.getGroupSummary(entry);
+        boolean changed;
         if (expanded) {
-            mExpandedGroups.add(groupSummary);
+            changed = mExpandedGroups.add(groupSummary);
         } else {
-            mExpandedGroups.remove(groupSummary);
+            changed = mExpandedGroups.remove(groupSummary);
         }
 
-        sendOnGroupExpandedChange(entry, expanded);
+        // Only notify listeners if something changed.
+        if (!mFeatureFlags.isEnabled(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE) || changed) {
+            sendOnGroupExpandedChange(entry, expanded);
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 943e906..6fafcd5 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -352,6 +352,13 @@
     }
 
     @Override
+    public boolean isDumpCritical() {
+        // Dump can't be critical because the shell has to dump on the main thread for
+        // synchronization reasons, which isn't reliably fast.
+        return false;
+    }
+
+    @Override
     public void dump(PrintWriter pw, String[] args) {
         // Handle commands if provided
         if (mShell.handleCommand(args, pw)) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index a76af8e..c65a2d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -118,6 +118,7 @@
         whenever(context.getString(eq(R.string.note_task_shortcut_long_label), any()))
             .thenReturn(NOTE_TASK_LONG_LABEL)
         whenever(context.packageManager).thenReturn(packageManager)
+        whenever(context.createContextAsUser(any(), any())).thenReturn(context)
         whenever(packageManager.getApplicationInfo(any(), any<Int>())).thenReturn(mock())
         whenever(packageManager.getApplicationLabel(any())).thenReturn(NOTE_TASK_LONG_LABEL)
         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(NOTE_TASK_INFO)
@@ -353,7 +354,13 @@
 
     @Test
     fun showNoteTask_defaultUserSet_shouldStartActivityWithExpectedUserAndLogUiEvent() {
-        whenever(secureSettings.getInt(eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE), any()))
+        whenever(
+                secureSettings.getIntForUser(
+                    /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
+                    /* def= */ any(),
+                    /* userHandle= */ any()
+                )
+            )
             .thenReturn(10)
         val user10 = UserHandle.of(/* userId= */ 10)
 
@@ -615,13 +622,21 @@
     }
 
     @Test
-    fun showNoteTask_copeDevices_tailButtonEntryPoint_shouldStartBubbleInWorkProfile() {
+    fun showNoteTask_copeDevices_tailButtonEntryPoint_shouldStartBubbleInTheUserSelectedUser() {
+        whenever(
+                secureSettings.getIntForUser(
+                    /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
+                    /* def= */ any(),
+                    /* userHandle= */ any()
+                )
+            )
+            .thenReturn(mainUserInfo.id)
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
         createNoteTaskController().showNoteTask(entryPoint = TAIL_BUTTON)
 
-        verifyNoteTaskOpenInBubbleInUser(workUserInfo.userHandle)
+        verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
     }
 
     @Test
@@ -813,7 +828,15 @@
     }
 
     @Test
-    fun getUserForHandlingNotesTaking_cope_tailButton_shouldReturnWorkProfileUser() {
+    fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { // ktlint-disable max-line-length
+        whenever(
+                secureSettings.getIntForUser(
+                    /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
+                    /* def= */ any(),
+                    /* userHandle= */ any()
+                )
+            )
+            .thenReturn(workUserInfo.id)
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
@@ -823,6 +846,24 @@
     }
 
     @Test
+    fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { // ktlint-disable max-line-length
+        whenever(
+                secureSettings.getIntForUser(
+                    /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
+                    /* def= */ any(),
+                    /* userHandle= */ any()
+                )
+            )
+            .thenReturn(mainUserInfo.id)
+        whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
+        userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
+
+        val user = createNoteTaskController().getUserForHandlingNotesTaking(TAIL_BUTTON)
+
+        assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
+    }
+
+    @Test
     fun getUserForHandlingNotesTaking_cope_appClip_shouldReturnCurrentUser() {
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
index 0c046e9..c68095c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
@@ -16,17 +16,23 @@
 
 package com.android.systemui.shade
 
+import android.os.VibrationEffect
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import android.view.HapticFeedbackConstants
 import android.view.View
 import android.view.ViewStub
 import androidx.test.filters.SmallTest
 import com.android.internal.util.CollectionUtils
 import com.android.keyguard.KeyguardClockSwitch.LARGE
 import com.android.systemui.R
+import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
 import com.android.systemui.statusbar.StatusBarState.KEYGUARD
 import com.android.systemui.statusbar.StatusBarState.SHADE
 import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED
+import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
@@ -55,6 +61,9 @@
 
     override fun getMainDispatcher() = Dispatchers.Main.immediate
 
+    private val ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT =
+        VibrationEffect.get(VibrationEffect.EFFECT_STRENGTH_MEDIUM, false)
+
     @Test
     fun testDisableUserSwitcherAfterEnabling_returnsViewStubToTheViewHierarchy() = runTest {
         launch(Dispatchers.Main.immediate) { givenViewAttached() }
@@ -148,6 +157,43 @@
     }
 
     @Test
+    fun doubleTapRequired_onKeyguard_oneWayHapticsDisabled_usesOldVibrate() = runTest {
+        launch(Dispatchers.Main.immediate) {
+            whenever(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(false)
+            val listener = getFalsingTapListener()
+            mStatusBarStateController.setState(KEYGUARD)
+
+            listener.onAdditionalTapRequired()
+            val packageName = mView.context.packageName
+            verify(mKeyguardIndicationController).showTransientIndication(anyInt())
+            verify(mVibratorHelper)
+                .vibrate(
+                    any(),
+                    eq(packageName),
+                    eq(ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT),
+                    eq("falsing-additional-tap-required"),
+                    eq(VibratorHelper.TOUCH_VIBRATION_ATTRIBUTES)
+                )
+        }
+        advanceUntilIdle()
+    }
+
+    @Test
+    fun doubleTapRequired_onKeyguard_oneWayHapticsEnabled_usesPerformHapticFeedback() = runTest {
+        launch(Dispatchers.Main.immediate) {
+            whenever(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(true)
+            val listener = getFalsingTapListener()
+            mStatusBarStateController.setState(KEYGUARD)
+
+            listener.onAdditionalTapRequired()
+            verify(mKeyguardIndicationController).showTransientIndication(anyInt())
+            verify(mVibratorHelper)
+                .performHapticFeedback(eq(mView), eq(HapticFeedbackConstants.REJECT))
+        }
+        advanceUntilIdle()
+    }
+
+    @Test
     fun testDoubleTapRequired_ShadeLocked() = runTest {
         launch(Dispatchers.Main.immediate) {
             val listener = getFalsingTapListener()
@@ -161,6 +207,45 @@
     }
 
     @Test
+    fun doubleTapRequired_shadeLocked_oneWayHapticsDisabled_usesOldVibrate() = runTest {
+        launch(Dispatchers.Main.immediate) {
+            whenever(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(false)
+            val listener = getFalsingTapListener()
+            val packageName = mView.context.packageName
+            mStatusBarStateController.setState(SHADE_LOCKED)
+
+            listener.onAdditionalTapRequired()
+            verify(mVibratorHelper)
+                .vibrate(
+                    any(),
+                    eq(packageName),
+                    eq(ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT),
+                    eq("falsing-additional-tap-required"),
+                    eq(VibratorHelper.TOUCH_VIBRATION_ATTRIBUTES)
+                )
+
+            verify(mTapAgainViewController).show()
+        }
+        advanceUntilIdle()
+    }
+
+    @Test
+    fun doubleTapRequired_shadeLocked_oneWayHapticsEnabled_usesPerformHapticFeedback() = runTest {
+        launch(Dispatchers.Main.immediate) {
+            whenever(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(true)
+            val listener = getFalsingTapListener()
+            mStatusBarStateController.setState(SHADE_LOCKED)
+
+            listener.onAdditionalTapRequired()
+            verify(mVibratorHelper)
+                .performHapticFeedback(eq(mView), eq(HapticFeedbackConstants.REJECT))
+
+            verify(mTapAgainViewController).show()
+        }
+        advanceUntilIdle()
+    }
+
+    @Test
     fun testOnAttachRefreshStatusBarState() = runTest {
         launch(Dispatchers.Main.immediate) {
             mStatusBarStateController.setState(KEYGUARD)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
new file mode 100644
index 0000000..4a94dc8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2023 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.render
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.util.mockito.mock
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+class GroupExpansionManagerTest : SysuiTestCase() {
+    private lateinit var gem: GroupExpansionManagerImpl
+
+    private val dumpManager: DumpManager = mock()
+    private val groupMembershipManager: GroupMembershipManager = mock()
+    private val featureFlags = FakeFeatureFlags()
+
+    private val entry1 = NotificationEntryBuilder().build()
+    private val entry2 = NotificationEntryBuilder().build()
+
+    @Before
+    fun setUp() {
+        whenever(groupMembershipManager.getGroupSummary(entry1)).thenReturn(entry1)
+        whenever(groupMembershipManager.getGroupSummary(entry2)).thenReturn(entry2)
+
+        gem = GroupExpansionManagerImpl(dumpManager, groupMembershipManager, featureFlags)
+    }
+
+    @Test
+    fun testNotifyOnlyOnChange_enabled() {
+        featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true)
+
+        var listenerCalledCount = 0
+        gem.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ }
+
+        gem.setGroupExpanded(entry1, false)
+        Assert.assertEquals(0, listenerCalledCount)
+        gem.setGroupExpanded(entry1, true)
+        Assert.assertEquals(1, listenerCalledCount)
+        gem.setGroupExpanded(entry2, true)
+        Assert.assertEquals(2, listenerCalledCount)
+        gem.setGroupExpanded(entry1, true)
+        Assert.assertEquals(2, listenerCalledCount)
+        gem.setGroupExpanded(entry2, false)
+        Assert.assertEquals(3, listenerCalledCount)
+    }
+
+    @Test
+    fun testNotifyOnlyOnChange_disabled() {
+        featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false)
+
+        var listenerCalledCount = 0
+        gem.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ }
+
+        gem.setGroupExpanded(entry1, false)
+        Assert.assertEquals(1, listenerCalledCount)
+        gem.setGroupExpanded(entry1, true)
+        Assert.assertEquals(2, listenerCalledCount)
+        gem.setGroupExpanded(entry2, true)
+        Assert.assertEquals(3, listenerCalledCount)
+        gem.setGroupExpanded(entry1, true)
+        Assert.assertEquals(4, listenerCalledCount)
+        gem.setGroupExpanded(entry2, false)
+        Assert.assertEquals(5, listenerCalledCount)
+    }
+}
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 7a95d77..41cca49 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -14,7 +14,7 @@
             "file_patterns": ["NotificationManagerService\\.java"]
         },
         {
-            "name": "CtsWindowManagerDeviceTestCases",
+            "name": "CtsWindowManagerDeviceWindow",
             "options": [
                 {
                     "include-filter": "android.server.wm.window.ToastWindowTest"
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 03e8691..bef53c7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -287,10 +287,6 @@
       */
     private static final String KEY_LOW_SWAP_THRESHOLD_PERCENT = "low_swap_threshold_percent";
 
-    /** Default value for mFlagApplicationStartInfoEnabled. Defaults to false. */
-    private static final String KEY_DEFAULT_APPLICATION_START_INFO_ENABLED =
-            "enable_app_start_info";
-
     /**
      * Default value for mFlagBackgroundActivityStartsEnabled if not explicitly set in
      * Settings.Global. This allows it to be set experimentally unless it has been
@@ -596,9 +592,6 @@
     // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
     volatile boolean mFlagActivityStartsLoggingEnabled;
 
-    // Indicates whether ApplicationStartInfo is enabled.
-    volatile boolean mFlagApplicationStartInfoEnabled;
-
     // Indicates whether the background activity starts is enabled.
     // Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED.
     // If not set explicitly the default is controlled by DeviceConfig.
@@ -1070,9 +1063,6 @@
                             case KEY_MAX_CACHED_PROCESSES:
                                 updateMaxCachedProcesses();
                                 break;
-                            case KEY_DEFAULT_APPLICATION_START_INFO_ENABLED:
-                                updateApplicationStartInfoEnabled();
-                                break;
                             case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED:
                                 updateBackgroundActivityStarts();
                                 break;
@@ -1493,14 +1483,6 @@
                 Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 1) == 1;
     }
 
-    private void updateApplicationStartInfoEnabled() {
-        mFlagApplicationStartInfoEnabled =
-                DeviceConfig.getBoolean(
-                        DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
-                        KEY_DEFAULT_APPLICATION_START_INFO_ENABLED,
-                        /*defaultValue*/ false);
-    }
-
     private void updateBackgroundActivityStarts() {
         mFlagBackgroundActivityStartsEnabled = DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -2125,10 +2107,6 @@
         pw.println(mFgToBgFgsGraceDuration);
         pw.print("  "); pw.print(KEY_FGS_START_FOREGROUND_TIMEOUT); pw.print("=");
         pw.println(mFgsStartForegroundTimeoutMs);
-        pw.print("  ");
-        pw.print(KEY_DEFAULT_APPLICATION_START_INFO_ENABLED);
-        pw.print("=");
-        pw.println(mFlagApplicationStartInfoEnabled);
         pw.print("  "); pw.print(KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED); pw.print("=");
         pw.println(mFlagBackgroundActivityStartsEnabled);
         pw.print("  "); pw.print(KEY_DEFAULT_BACKGROUND_FGS_STARTS_RESTRICTION_ENABLED);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 132d6a9..a0fae26 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9563,14 +9563,9 @@
         return retList;
     }
 
-    /* @hide */
     @Override
     public ParceledListSlice<ApplicationStartInfo> getHistoricalProcessStartReasons(
             String packageName, int maxNum, int userId) {
-        if (!mConstants.mFlagApplicationStartInfoEnabled) {
-            return new ParceledListSlice<ApplicationStartInfo>(
-                new ArrayList<ApplicationStartInfo>());
-        }
         enforceNotIsolatedCaller("getHistoricalProcessStartReasons");
 
         final ArrayList<ApplicationStartInfo> results = new ArrayList<ApplicationStartInfo>();
@@ -9579,24 +9574,28 @@
     }
 
 
-    /* @hide */
     @Override
     public void setApplicationStartInfoCompleteListener(
             IApplicationStartInfoCompleteListener listener, int userId) {
-        if (!mConstants.mFlagApplicationStartInfoEnabled) {
-            return;
-        }
         enforceNotIsolatedCaller("setApplicationStartInfoCompleteListener");
     }
 
 
-    /* @hide */
     @Override
-    public void removeApplicationStartInfoCompleteListener(int userId) {
-        if (!mConstants.mFlagApplicationStartInfoEnabled) {
-            return;
+    public void clearApplicationStartInfoCompleteListener(int userId) {
+        enforceNotIsolatedCaller("clearApplicationStartInfoCompleteListener");
+
+        // For the simplification, we don't support USER_ALL nor USER_CURRENT here.
+        if (userId == UserHandle.USER_ALL || userId == UserHandle.USER_CURRENT) {
+            throw new IllegalArgumentException("Unsupported userId");
         }
-        enforceNotIsolatedCaller("removeApplicationStartInfoCompleteListener");
+
+        final int callingUid = Binder.getCallingUid();
+    }
+
+    @Override
+    public void addStartInfoTimestamp(int key, long timestampNs, int userId) {
+        enforceNotIsolatedCaller("addStartInfoTimestamp");
     }
 
     @Override
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 5a050ac..75fcca5 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -5583,7 +5583,7 @@
         private void recordReferenceLocked(String id) {
             LongArray times = mOpenReferenceTimes.get(id);
             if (times == null) {
-                times = new LongArray();
+                times = new LongArray(2);
                 mOpenReferenceTimes.put(id, times);
             }
             times.add(System.currentTimeMillis());
@@ -5593,6 +5593,9 @@
             LongArray times = mOpenReferenceTimes.get(id);
             if (times != null && times.size() > 0) {
                 times.remove(times.size() - 1);
+                if (times.size() == 0) {
+                    mOpenReferenceTimes.remove(id);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/uri/TEST_MAPPING b/services/core/java/com/android/server/uri/TEST_MAPPING
index 6c36af5..b42d154 100644
--- a/services/core/java/com/android/server/uri/TEST_MAPPING
+++ b/services/core/java/com/android/server/uri/TEST_MAPPING
@@ -39,10 +39,10 @@
             ]
         },
         {
-            "name": "CtsWindowManagerDeviceTestCases",
+            "name": "CtsWindowManagerDeviceWindow",
             "options": [
                 {
-                    "include-filter": "android.server.wm.CrossAppDragAndDropTests"
+                    "include-filter": "android.server.wm.window.CrossAppDragAndDropTests"
                 }
             ]
         }
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 554b0f4..85d0473c 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -90,7 +90,7 @@
 
         <activity android:name="com.android.server.wm.SurfaceControlViewHostTests$TestActivity" />
 
-        <activity android:name="android.server.wm.scvh.SurfaceSyncGroupActivity"
+        <activity android:name="com.android.server.wm.SurfaceSyncGroupTests$TestActivity"
             android:screenOrientation="locked"
             android:turnScreenOn="true"
             android:theme="@style/WhiteBackgroundTheme"
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java
index 89d7252..abaa776 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTests.java
@@ -23,22 +23,27 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import android.app.Activity;
 import android.app.Instrumentation;
+import android.app.KeyguardManager;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.platform.test.annotations.Presubmit;
-import android.server.wm.scvh.SurfaceSyncGroupActivity;
 import android.view.SurfaceControl;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 import android.view.cts.surfacevalidator.BitmapPixelChecker;
+import android.widget.FrameLayout;
 import android.window.SurfaceSyncGroup;
 
+import androidx.annotation.Nullable;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
 
@@ -56,10 +61,10 @@
     private static final long TIMEOUT_S = HW_TIMEOUT_MULTIPLIER * 5L;
 
     @Rule
-    public ActivityTestRule<SurfaceSyncGroupActivity> mActivityRule = new ActivityTestRule<>(
-            SurfaceSyncGroupActivity.class);
+    public ActivityTestRule<TestActivity> mActivityRule = new ActivityTestRule<>(
+            TestActivity.class);
 
-    private SurfaceSyncGroupActivity mActivity;
+    private TestActivity mActivity;
 
     Instrumentation mInstrumentation;
 
@@ -187,4 +192,24 @@
 
         swBitmap.recycle();
     }
+
+    public static class TestActivity extends Activity {
+        private ViewGroup mParentView;
+
+        @Override
+        public void onCreate(@Nullable Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+
+            mParentView = new FrameLayout(this);
+            setContentView(mParentView);
+
+            KeyguardManager km = getSystemService(KeyguardManager.class);
+            km.requestDismissKeyguard(this, null);
+        }
+
+        public View getBackgroundView() {
+            return mParentView;
+        }
+    }
 }
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 1da4ea9..78b86d3 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -936,6 +936,12 @@
             return mState;
         }
 
+        /**
+         * @return the Telecom identifier associated with this {@link Call} . This is not a stable
+         * identifier and is not guaranteed to be unique across device reboots.
+         */
+        public @NonNull String getId() { return mTelecomCallId; }
+
         /** {@hide} */
         @TestApi
         public String getTelecomCallId() {
diff --git a/telecomm/java/android/telecom/StreamingCall.java b/telecomm/java/android/telecom/StreamingCall.java
index 3319fc1..29f436d 100644
--- a/telecomm/java/android/telecom/StreamingCall.java
+++ b/telecomm/java/android/telecom/StreamingCall.java
@@ -56,7 +56,6 @@
 
     /**
      * The ID associated with this call.  This is the same value as {@link CallControl#getCallId()}.
-     * @hide
      */
     public static final String EXTRA_CALL_ID = "android.telecom.extra.CALL_ID";