Merge "Remove unused windowAttributes"
diff --git a/core/api/current.txt b/core/api/current.txt
index 7c92793..9e3e955 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7335,6 +7335,7 @@
   public final class UiAutomation {
     method public void adoptShellPermissionIdentity();
     method public void adoptShellPermissionIdentity(@Nullable java.lang.String...);
+    method public boolean clearCache();
     method @Deprecated public void clearWindowAnimationFrameStats();
     method public boolean clearWindowContentFrameStats(int);
     method public void dropShellPermissionIdentity();
@@ -28818,24 +28819,15 @@
 
   public final class NfcAdapter {
     method public void disableForegroundDispatch(android.app.Activity);
-    method @Deprecated public void disableForegroundNdefPush(android.app.Activity);
     method public void disableReaderMode(android.app.Activity);
     method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]);
-    method @Deprecated public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
     method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
     method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
     method @Nullable public android.nfc.NfcAntennaInfo getNfcAntennaInfo();
     method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler);
-    method @Deprecated public boolean invokeBeam(android.app.Activity);
     method public boolean isEnabled();
-    method @Deprecated public boolean isNdefPushEnabled();
     method public boolean isSecureNfcEnabled();
     method public boolean isSecureNfcSupported();
-    method @Deprecated public void setBeamPushUris(android.net.Uri[], android.app.Activity);
-    method @Deprecated public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity);
-    method @Deprecated public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
-    method @Deprecated public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...);
-    method @Deprecated public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
     field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
     field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
     field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
@@ -33312,6 +33304,7 @@
     field public static final int LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF = 1; // 0x1
     field public static final int LOCATION_MODE_NO_CHANGE = 0; // 0x0
     field public static final int LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF = 4; // 0x4
+    field public static final int LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST = 2; // 0x2
     field public static final int LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION = 1; // 0x1
     field public static final String LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN = "com.android.lowpowerstandby.WAKE_ON_LAN";
     field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
@@ -53956,6 +53949,7 @@
     method public java.util.List<java.lang.String> getAvailableExtraData();
     method @Deprecated public void getBoundsInParent(android.graphics.Rect);
     method public void getBoundsInScreen(android.graphics.Rect);
+    method public void getBoundsInWindow(@NonNull android.graphics.Rect);
     method public android.view.accessibility.AccessibilityNodeInfo getChild(int);
     method @Nullable public android.view.accessibility.AccessibilityNodeInfo getChild(int, int);
     method public int getChildCount();
@@ -54034,6 +54028,7 @@
     method public void setAvailableExtraData(java.util.List<java.lang.String>);
     method @Deprecated public void setBoundsInParent(android.graphics.Rect);
     method public void setBoundsInScreen(android.graphics.Rect);
+    method public void setBoundsInWindow(@NonNull android.graphics.Rect);
     method public void setCanOpenPopup(boolean);
     method public void setCheckable(boolean);
     method public void setChecked(boolean);
diff --git a/core/api/removed.txt b/core/api/removed.txt
index 1fa1e89..8b3696a 100644
--- a/core/api/removed.txt
+++ b/core/api/removed.txt
@@ -252,6 +252,22 @@
 
 }
 
+package android.nfc {
+
+  public final class NfcAdapter {
+    method @Deprecated public void disableForegroundNdefPush(android.app.Activity);
+    method @Deprecated public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
+    method @Deprecated public boolean invokeBeam(android.app.Activity);
+    method @Deprecated public boolean isNdefPushEnabled();
+    method @Deprecated public void setBeamPushUris(android.net.Uri[], android.app.Activity);
+    method @Deprecated public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity);
+    method @Deprecated public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
+    method @Deprecated public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...);
+    method @Deprecated public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
+  }
+
+}
+
 package android.os {
 
   public class BatteryManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index fde95bd..dc7e28c 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -626,6 +626,7 @@
     field public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
     field public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
     field public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
+    field public static final String OPSTR_SYSTEM_EXEMPT_FROM_HIBERNATION = "android:system_exempt_from_hibernation";
     field public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
     field public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
     field public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
@@ -10114,9 +10115,7 @@
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean addNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler, String[]);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable();
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(boolean);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush();
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
     method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
@@ -10125,10 +10124,8 @@
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean);
-    method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
-    field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
     field public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff
     field public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0; // 0x0
     field public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2; // 0xfffffffe
diff --git a/core/api/system-removed.txt b/core/api/system-removed.txt
index 2c5acf1..1c10356 100644
--- a/core/api/system-removed.txt
+++ b/core/api/system-removed.txt
@@ -140,6 +140,17 @@
 
 }
 
+package android.nfc {
+
+  public final class NfcAdapter {
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush();
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
+    method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
+    field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
+  }
+
+}
+
 package android.os {
 
   public class Build {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 1abdbb9..c25f875 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -448,6 +448,7 @@
     method @Deprecated public boolean grantRuntimePermission(String, String, android.os.UserHandle);
     method public boolean injectInputEvent(@NonNull android.view.InputEvent, boolean, boolean);
     method public void injectInputEventToInputFilter(@NonNull android.view.InputEvent);
+    method public boolean isNodeInCache(@NonNull android.view.accessibility.AccessibilityNodeInfo);
     method @Deprecated public boolean revokeRuntimePermission(String, String, android.os.UserHandle);
     method public void syncInputTransactions();
     method public void syncInputTransactions(boolean);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 8263a4e3..8a671be 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1462,9 +1462,17 @@
      */
     public static final int OP_USE_FULL_SCREEN_INTENT = AppProtoEnums.APP_OP_USE_FULL_SCREEN_INTENT;
 
+    /**
+     * Prevent an app from being placed into hibernation.
+     *
+     * @hide
+     */
+    public static final int OP_SYSTEM_EXEMPT_FROM_HIBERNATION =
+            AppProtoEnums.APP_OP_SYSTEM_EXEMPT_FROM_HIBERNATION;
+
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int _NUM_OP = 134;
+    public static final int _NUM_OP = 135;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -2058,6 +2066,15 @@
      */
     public static final String OPSTR_USE_FULL_SCREEN_INTENT = "android:use_full_screen_intent";
 
+    /**
+     *  Prevent an app from being placed into hibernation.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String OPSTR_SYSTEM_EXEMPT_FROM_HIBERNATION =
+            "android:system_exempt_from_hibernation";
+
     /** {@link #sAppOpsToNote} not initialized yet for this op */
     private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
     /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -2580,7 +2597,10 @@
                 .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
         new AppOpInfo.Builder(OP_USE_FULL_SCREEN_INTENT, OPSTR_USE_FULL_SCREEN_INTENT,
                 "USE_FULL_SCREEN_INTENT").setPermission(Manifest.permission.USE_FULL_SCREEN_INTENT)
-                .build()
+                .build(),
+        new AppOpInfo.Builder(OP_SYSTEM_EXEMPT_FROM_HIBERNATION,
+                OPSTR_SYSTEM_EXEMPT_FROM_HIBERNATION,
+                "SYSTEM_EXEMPT_FROM_HIBERNATION").build()
     };
 
     // The number of longs needed to form a full bitmask of app ops
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index e93ce6b..c628ec4 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -734,7 +734,22 @@
      * guarantees that the format is stable across devices or Android releases.</p>
      */
     public @Nullable String getDescription() {
-        return mDescription;
+        final StringBuilder sb = new StringBuilder();
+
+        if (mSubReason != SUBREASON_UNKNOWN) {
+            sb.append("[");
+            sb.append(subreasonToString(mSubReason));
+            sb.append("]");
+        }
+
+        if (!TextUtils.isEmpty(mDescription)) {
+            if (sb.length() > 0) {
+                sb.append(" ");
+            }
+            sb.append(mDescription);
+        }
+
+        return sb.toString();
     }
 
     /**
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 249937a..b3b1cf8 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.accessibilityservice.AccessibilityGestureEvent;
+import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.AccessibilityService.Callbacks;
 import android.accessibilityservice.AccessibilityService.IAccessibilityServiceClientWrapper;
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -58,6 +59,7 @@
 import android.view.Window;
 import android.view.WindowAnimationFrameStats;
 import android.view.WindowContentFrameStats;
+import android.view.accessibility.AccessibilityCache;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -465,6 +467,48 @@
     }
 
     /**
+     * Clears the accessibility cache.
+     *
+     * @return {@code true} if the cache was cleared
+     * @see AccessibilityService#clearCache()
+     */
+    public boolean clearCache() {
+        final int connectionId;
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+            connectionId = mConnectionId;
+        }
+        final AccessibilityCache cache = AccessibilityInteractionClient.getCache(connectionId);
+        if (cache == null) {
+            return false;
+        }
+        cache.clear();
+        return true;
+    }
+
+    /**
+     * Checks if {@code node} is in the accessibility cache.
+     *
+     * @param node the node to check.
+     * @return {@code true} if {@code node} is in the cache.
+     * @hide
+     * @see AccessibilityService#isNodeInCache(AccessibilityNodeInfo)
+     */
+    @TestApi
+    public boolean isNodeInCache(@NonNull AccessibilityNodeInfo node) {
+        final int connectionId;
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+            connectionId = mConnectionId;
+        }
+        final AccessibilityCache cache = AccessibilityInteractionClient.getCache(connectionId);
+        if (cache == null) {
+            return false;
+        }
+        return cache.isNodeInCache(node);
+    }
+
+    /**
      * Adopt the permission identity of the shell UID for all permissions. This allows
      * you to call APIs protected permissions which normal apps cannot hold but are
      * granted to the shell UID. If you already adopted all shell permissions by calling
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e7f6990..90e0318 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -4020,26 +4020,26 @@
         return MTE_NOT_CONTROLLED_BY_POLICY;
     }
 
-    // TODO: Expose this as SystemAPI once we add the query API
+    // TODO: Expose this as a public API
     /**
      * @hide
      */
     public static final String AUTO_TIMEZONE_POLICY = "autoTimezone";
 
-    // TODO: Expose this as SystemAPI once we add the query API
+    // TODO: Expose this as a public API
     /**
      * @hide
      */
     public static final String PERMISSION_GRANT_POLICY = "permissionGrant";
 
 
-    // TODO: Expose this as SystemAPI once we add the query API
+    // TODO: Expose this as a public API
     /**
      * @hide
      */
     public static final String LOCK_TASK_POLICY = "lockTask";
 
-    // TODO: Expose this as SystemAPI once we add the query API
+    // TODO: Expose this as a public API
     /**
      * @hide
      */
@@ -4047,25 +4047,31 @@
             "userControlDisabledPackages";
 
 
-    // TODO: Expose this as SystemAPI once we add the query API
+    // TODO: Expose this as a public API
     /**
      * @hide
      */
     public static final String PERSISTENT_PREFERRED_ACTIVITY_POLICY =
             "persistentPreferredActivity";
 
-    // TODO: Expose this as SystemAPI once we add the query API
+    // TODO: Expose this as a public API
     /**
      * @hide
      */
     public static final String PACKAGE_UNINSTALL_BLOCKED_POLICY = "packageUninstallBlocked";
 
-    // TODO: Expose this as SystemAPI once we add the query API
+    // TODO: Expose this as a public API
     /**
      * @hide
      */
     public static final String APPLICATION_RESTRICTIONS_POLICY = "applicationRestrictions";
 
+    // TODO: Expose this as a public API
+    /**
+     * @hide
+     */
+    public static final String RESET_PASSWORD_TOKEN_POLICY = "resetPasswordToken";
+
     /**
      * This object is a single place to tack on invalidation and disable calls.  All
      * binder caches in this class derive from this Config, so all can be invalidated or
diff --git a/core/java/android/app/admin/LongPolicyValue.java b/core/java/android/app/admin/LongPolicyValue.java
new file mode 100644
index 0000000..b149b8a
--- /dev/null
+++ b/core/java/android/app/admin/LongPolicyValue.java
@@ -0,0 +1,79 @@
+/*
+ * 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 android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+public final class LongPolicyValue extends PolicyValue<Long> {
+
+    public LongPolicyValue(long value) {
+        super(value);
+    }
+
+    private LongPolicyValue(Parcel source) {
+        this(source.readLong());
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        LongPolicyValue other = (LongPolicyValue) o;
+        return Objects.equals(getValue(), other.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getValue());
+    }
+
+    @Override
+    public String toString() {
+        return "LongPolicyValue { mValue= " + getValue() + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeLong(getValue());
+    }
+
+    @NonNull
+    public static final Creator<LongPolicyValue> CREATOR =
+            new Creator<LongPolicyValue>() {
+                @Override
+                public LongPolicyValue createFromParcel(Parcel source) {
+                    return new LongPolicyValue(source);
+                }
+
+                @Override
+                public LongPolicyValue[] newArray(int size) {
+                    return new LongPolicyValue[size];
+                }
+            };
+}
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 3e6b380..29e2231 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -630,9 +630,6 @@
                 @NonNull VirtualDisplayConfig config,
                 @Nullable @CallbackExecutor Executor executor,
                 @Nullable VirtualDisplay.Callback callback) {
-            // TODO(b/205343547): Handle display groups properly instead of creating a new display
-            //  group for every new virtual display created using this API.
-            // belongs to the same display group.
             IVirtualDisplayCallback callbackWrapper =
                     new DisplayManagerGlobal.VirtualDisplayCallback(callback, executor);
             final int displayId;
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 49d21da..90ed4ce 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -246,8 +246,17 @@
 
     /**
      * Constant corresponding to {@code mediaProjection} in
-     * the {@link android.R.attr#foregroundServiceType} attribute.
-     * Managing a media projection session, e.g for screen recording or taking screenshots.
+     * the {@link android.R.attr#foregroundServiceType foregroundServiceType} attribute.
+     *
+     * <p>
+     * To capture through {@link android.media.projection.MediaProjection}, an app must start a
+     * foreground service with the type corresponding to this constant. This type should only be
+     * used for {@link android.media.projection.MediaProjection}. Capturing screen contents via
+     * {@link android.media.projection.MediaProjection#createVirtualDisplay(String, int, int, int,
+     * int, android.view.Surface, android.hardware.display.VirtualDisplay.Callback,
+     * android.os.Handler) createVirtualDisplay} conveniently allows recording, presenting screen
+     * contents into a meeting, taking screenshots, or several other scenarios.
+     * </p>
      *
      * <p>Starting foreground service with this type from apps targeting API level
      * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and later, will require permission
diff --git a/core/java/android/nfc/BeamShareData.aidl b/core/java/android/nfc/BeamShareData.aidl
deleted file mode 100644
index a47e240..0000000
--- a/core/java/android/nfc/BeamShareData.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2013 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.nfc;
-
-parcelable BeamShareData;
diff --git a/core/java/android/nfc/BeamShareData.java b/core/java/android/nfc/BeamShareData.java
deleted file mode 100644
index 6a40f98..0000000
--- a/core/java/android/nfc/BeamShareData.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package android.nfc;
-
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.UserHandle;
-
-/**
- * Class to IPC data to be shared over Android Beam.
- * Allows bundling NdefMessage, Uris and flags in a single
- * IPC call. This is important as we want to reduce the
- * amount of IPC calls at "touch time".
- * @hide
- */
-public final class BeamShareData implements Parcelable {
-    public final NdefMessage ndefMessage;
-    public final Uri[] uris;
-    public final UserHandle userHandle;
-    public final int flags;
-
-    public BeamShareData(NdefMessage msg, Uri[] uris, UserHandle userHandle, int flags) {
-        this.ndefMessage = msg;
-        this.uris = uris;
-        this.userHandle = userHandle;
-        this.flags = flags;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        int urisLength = (uris != null) ? uris.length : 0;
-        dest.writeParcelable(ndefMessage, 0);
-        dest.writeInt(urisLength);
-        if (urisLength > 0) {
-            dest.writeTypedArray(uris, 0);
-        }
-        dest.writeParcelable(userHandle, 0);
-        dest.writeInt(this.flags);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<BeamShareData> CREATOR =
-            new Parcelable.Creator<BeamShareData>() {
-        @Override
-        public BeamShareData createFromParcel(Parcel source) {
-            Uri[] uris = null;
-            NdefMessage msg = source.readParcelable(NdefMessage.class.getClassLoader(), android.nfc.NdefMessage.class);
-            int numUris = source.readInt();
-            if (numUris > 0) {
-                uris = new Uri[numUris];
-                source.readTypedArray(uris, Uri.CREATOR);
-            }
-            UserHandle userHandle = source.readParcelable(UserHandle.class.getClassLoader(), android.os.UserHandle.class);
-            int flags = source.readInt();
-
-            return new BeamShareData(msg, uris, userHandle, flags);
-        }
-
-        @Override
-        public BeamShareData[] newArray(int size) {
-            return new BeamShareData[size];
-        }
-    };
-}
diff --git a/core/java/android/nfc/IAppCallback.aidl b/core/java/android/nfc/IAppCallback.aidl
index 133146d..b06bf06 100644
--- a/core/java/android/nfc/IAppCallback.aidl
+++ b/core/java/android/nfc/IAppCallback.aidl
@@ -16,7 +16,6 @@
 
 package android.nfc;
 
-import android.nfc.BeamShareData;
 import android.nfc.Tag;
 
 /**
@@ -24,7 +23,5 @@
  */
 interface IAppCallback
 {
-    BeamShareData createBeamShareData(byte peerLlcpVersion);
-    oneway void onNdefPushComplete(byte peerLlcpVersion);
     oneway void onTagDiscovered(in Tag tag);
 }
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 8a30ef4..a6d8caf 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -18,7 +18,6 @@
 
 import android.app.PendingIntent;
 import android.content.IntentFilter;
-import android.nfc.BeamShareData;
 import android.nfc.NdefMessage;
 import android.nfc.Tag;
 import android.nfc.TechListParcel;
@@ -47,24 +46,18 @@
     int getState();
     boolean disable(boolean saveState);
     boolean enable();
-    boolean enableNdefPush();
-    boolean disableNdefPush();
-    boolean isNdefPushEnabled();
     void pausePolling(int timeoutInMs);
     void resumePolling();
 
     void setForegroundDispatch(in PendingIntent intent,
             in IntentFilter[] filters, in TechListParcel techLists);
     void setAppCallback(in IAppCallback callback);
-    oneway void invokeBeam();
-    oneway void invokeBeamInternal(in BeamShareData shareData);
 
     boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback);
 
     void dispatch(in Tag tag);
 
     void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras);
-    void setP2pModes(int initatorModes, int targetModes);
 
     void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList);
     void removeNfcUnlockHandler(INfcUnlockHandler unlockHandler);
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 911aaf3..8d75cac 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -19,9 +19,6 @@
 import android.app.Activity;
 import android.app.Application;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ContentProvider;
-import android.content.Intent;
-import android.net.Uri;
 import android.nfc.NfcAdapter.ReaderCallback;
 import android.os.Binder;
 import android.os.Bundle;
@@ -110,14 +107,8 @@
     class NfcActivityState {
         boolean resumed = false;
         Activity activity;
-        NdefMessage ndefMessage = null;  // static NDEF message
-        NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
-        NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
-        NfcAdapter.CreateBeamUrisCallback uriCallback = null;
-        Uri[] uris = null;
-        int flags = 0;
-        int readerModeFlags = 0;
         NfcAdapter.ReaderCallback readerCallback = null;
+        int readerModeFlags = 0;
         Bundle readerModeExtras = null;
         Binder token;
 
@@ -137,24 +128,16 @@
             unregisterApplication(activity.getApplication());
             resumed = false;
             activity = null;
-            ndefMessage = null;
-            ndefMessageCallback = null;
-            onNdefPushCompleteCallback = null;
-            uriCallback = null;
-            uris = null;
+            readerCallback = null;
             readerModeFlags = 0;
+            readerModeExtras = null;
             token = null;
         }
         @Override
         public String toString() {
-            StringBuilder s = new StringBuilder("[").append(" ");
-            s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
-            s.append(uriCallback).append(" ");
-            if (uris != null) {
-                for (Uri uri : uris) {
-                    s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
-                }
-            }
+            StringBuilder s = new StringBuilder("[");
+            s.append(readerCallback);
+            s.append("]");
             return s.toString();
         }
     }
@@ -245,92 +228,6 @@
         }
     }
 
-    public void setNdefPushContentUri(Activity activity, Uri[] uris) {
-        boolean isResumed;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.uris = uris;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            // requestNfcServiceCallback() verifies permission also
-            requestNfcServiceCallback();
-        } else {
-            // Crash API calls early in case NFC permission is missing
-            verifyNfcPermission();
-        }
-    }
-
-
-    public void setNdefPushContentUriCallback(Activity activity,
-            NfcAdapter.CreateBeamUrisCallback callback) {
-        boolean isResumed;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.uriCallback = callback;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            // requestNfcServiceCallback() verifies permission also
-            requestNfcServiceCallback();
-        } else {
-            // Crash API calls early in case NFC permission is missing
-            verifyNfcPermission();
-        }
-    }
-
-    public void setNdefPushMessage(Activity activity, NdefMessage message, int flags) {
-        boolean isResumed;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.ndefMessage = message;
-            state.flags = flags;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            // requestNfcServiceCallback() verifies permission also
-            requestNfcServiceCallback();
-        } else {
-            // Crash API calls early in case NFC permission is missing
-            verifyNfcPermission();
-        }
-    }
-
-    public void setNdefPushMessageCallback(Activity activity,
-            NfcAdapter.CreateNdefMessageCallback callback, int flags) {
-        boolean isResumed;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.ndefMessageCallback = callback;
-            state.flags = flags;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            // requestNfcServiceCallback() verifies permission also
-            requestNfcServiceCallback();
-        } else {
-            // Crash API calls early in case NFC permission is missing
-            verifyNfcPermission();
-        }
-    }
-
-    public void setOnNdefPushCompleteCallback(Activity activity,
-            NfcAdapter.OnNdefPushCompleteCallback callback) {
-        boolean isResumed;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.onNdefPushCompleteCallback = callback;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            // requestNfcServiceCallback() verifies permission also
-            requestNfcServiceCallback();
-        } else {
-            // Crash API calls early in case NFC permission is missing
-            verifyNfcPermission();
-        }
-    }
-
     /**
      * Request or unrequest NFC service callbacks.
      * Makes IPC call - do not hold lock.
@@ -351,86 +248,6 @@
         }
     }
 
-    /** Callback from NFC service, usually on binder thread */
-    @Override
-    public BeamShareData createBeamShareData(byte peerLlcpVersion) {
-        NfcAdapter.CreateNdefMessageCallback ndefCallback;
-        NfcAdapter.CreateBeamUrisCallback urisCallback;
-        NdefMessage message;
-        Activity activity;
-        Uri[] uris;
-        int flags;
-        NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = findResumedActivityState();
-            if (state == null) return null;
-
-            ndefCallback = state.ndefMessageCallback;
-            urisCallback = state.uriCallback;
-            message = state.ndefMessage;
-            uris = state.uris;
-            flags = state.flags;
-            activity = state.activity;
-        }
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            // Make callbacks without lock
-            if (ndefCallback != null) {
-                message = ndefCallback.createNdefMessage(event);
-            }
-            if (urisCallback != null) {
-                uris = urisCallback.createBeamUris(event);
-                if (uris != null) {
-                    ArrayList<Uri> validUris = new ArrayList<Uri>();
-                    for (Uri uri : uris) {
-                        if (uri == null) {
-                            Log.e(TAG, "Uri not allowed to be null.");
-                            continue;
-                        }
-                        String scheme = uri.getScheme();
-                        if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
-                                !scheme.equalsIgnoreCase("content"))) {
-                            Log.e(TAG, "Uri needs to have " +
-                                    "either scheme file or scheme content");
-                            continue;
-                        }
-                        uri = ContentProvider.maybeAddUserId(uri, activity.getUserId());
-                        validUris.add(uri);
-                    }
-
-                    uris = validUris.toArray(new Uri[validUris.size()]);
-                }
-            }
-            if (uris != null && uris.length > 0) {
-                for (Uri uri : uris) {
-                    // Grant the NFC process permission to read these URIs
-                    activity.grantUriPermission("com.android.nfc", uri,
-                            Intent.FLAG_GRANT_READ_URI_PERMISSION);
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-        return new BeamShareData(message, uris, activity.getUser(), flags);
-    }
-
-    /** Callback from NFC service, usually on binder thread */
-    @Override
-    public void onNdefPushComplete(byte peerLlcpVersion) {
-        NfcAdapter.OnNdefPushCompleteCallback callback;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = findResumedActivityState();
-            if (state == null) return;
-
-            callback = state.onNdefPushCompleteCallback;
-        }
-        NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
-        // Make callback without lock
-        if (callback != null) {
-            callback.onNdefPushComplete(event);
-        }
-    }
-
     @Override
     public void onTagDiscovered(Tag tag) throws RemoteException {
         NfcAdapter.ReaderCallback callback;
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 1bb44af..4a244c0 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -343,8 +343,12 @@
      */
     public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
 
-    /** @hide */
+    /**
+     * @hide
+     * @removed
+     */
     @SystemApi
+    @UnsupportedAppUsage
     public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1;
 
     /** @hide */
@@ -418,7 +422,6 @@
     // Guarded by NfcAdapter.class
     static boolean sIsInitialized = false;
     static boolean sHasNfcFeature;
-    static boolean sHasBeamFeature;
 
     // Final after first constructor, except for
     // attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
@@ -483,7 +486,7 @@
      * A callback to be invoked when the system successfully delivers your {@link NdefMessage}
      * to another device.
      * @see #setOnNdefPushCompleteCallback
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @deprecated this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
@@ -509,7 +512,7 @@
      * content currently visible to the user. Alternatively, you can call {@link
      * #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the
      * same data.
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @deprecated this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
@@ -539,7 +542,7 @@
 
 
      /**
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @deprecated this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
@@ -615,7 +618,6 @@
             PackageManager pm;
             pm = context.getPackageManager();
             sHasNfcFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC);
-            sHasBeamFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM);
             boolean hasHceFeature =
                     pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
                     || pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
@@ -1111,35 +1113,17 @@
      * @param uris an array of Uri(s) to push over Android Beam
      * @param activity activity for which the Uri(s) will be pushed
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @removed this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
+    @UnsupportedAppUsage
     public void setBeamPushUris(Uri[] uris, Activity activity) {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
-            if (!sHasBeamFeature) {
-                return;
-            }
         }
-        if (activity == null) {
-            throw new NullPointerException("activity cannot be null");
-        }
-        if (uris != null) {
-            for (Uri uri : uris) {
-                if (uri == null) throw new NullPointerException("Uri not " +
-                        "allowed to be null");
-                String scheme = uri.getScheme();
-                if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
-                        !scheme.equalsIgnoreCase("content"))) {
-                    throw new IllegalArgumentException("URI needs to have " +
-                            "either scheme file or scheme content");
-                }
-            }
-        }
-        mNfcActivityManager.setNdefPushContentUri(activity, uris);
     }
 
     /**
@@ -1199,23 +1183,17 @@
      * @param callback callback, or null to disable
      * @param activity activity for which the Uri(s) will be pushed
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @removed this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
+    @UnsupportedAppUsage
     public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
-            if (!sHasBeamFeature) {
-                return;
-            }
         }
-        if (activity == null) {
-            throw new NullPointerException("activity cannot be null");
-        }
-        mNfcActivityManager.setNdefPushContentUriCallback(activity, callback);
     }
 
     /**
@@ -1289,58 +1267,32 @@
      *        to only register one at a time, and to do so in that activity's
      *        {@link Activity#onCreate}
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @removed this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
+    @UnsupportedAppUsage
     public void setNdefPushMessage(NdefMessage message, Activity activity,
             Activity ... activities) {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
-            if (!sHasBeamFeature) {
-                return;
-            }
-        }
-        int targetSdkVersion = getSdkVersion();
-        try {
-            if (activity == null) {
-                throw new NullPointerException("activity cannot be null");
-            }
-            mNfcActivityManager.setNdefPushMessage(activity, message, 0);
-            for (Activity a : activities) {
-                if (a == null) {
-                    throw new NullPointerException("activities cannot contain null");
-                }
-                mNfcActivityManager.setNdefPushMessage(a, message, 0);
-            }
-        } catch (IllegalStateException e) {
-            if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) {
-                // Less strict on old applications - just log the error
-                Log.e(TAG, "Cannot call API with Activity that has already " +
-                        "been destroyed", e);
-            } else {
-                // Prevent new applications from making this mistake, re-throw
-                throw(e);
-            }
         }
     }
 
     /**
      * @hide
+     * @removed
      */
     @SystemApi
+    @UnsupportedAppUsage
     public void setNdefPushMessage(NdefMessage message, Activity activity, int flags) {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
         }
-        if (activity == null) {
-            throw new NullPointerException("activity cannot be null");
-        }
-        mNfcActivityManager.setNdefPushMessage(activity, message, flags);
     }
 
     /**
@@ -1408,54 +1360,18 @@
      *        to only register one at a time, and to do so in that activity's
      *        {@link Activity#onCreate}
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @removed this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
+    @UnsupportedAppUsage
     public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
             Activity ... activities) {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
-            if (!sHasBeamFeature) {
-                return;
-            }
         }
-        int targetSdkVersion = getSdkVersion();
-        try {
-            if (activity == null) {
-                throw new NullPointerException("activity cannot be null");
-            }
-            mNfcActivityManager.setNdefPushMessageCallback(activity, callback, 0);
-            for (Activity a : activities) {
-                if (a == null) {
-                    throw new NullPointerException("activities cannot contain null");
-                }
-                mNfcActivityManager.setNdefPushMessageCallback(a, callback, 0);
-            }
-        } catch (IllegalStateException e) {
-            if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) {
-                // Less strict on old applications - just log the error
-                Log.e(TAG, "Cannot call API with Activity that has already " +
-                        "been destroyed", e);
-            } else {
-                // Prevent new applications from making this mistake, re-throw
-                throw(e);
-            }
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
-            int flags) {
-        if (activity == null) {
-            throw new NullPointerException("activity cannot be null");
-        }
-        mNfcActivityManager.setNdefPushMessageCallback(activity, callback, flags);
     }
 
     /**
@@ -1495,41 +1411,17 @@
      *        to only register one at a time, and to do so in that activity's
      *        {@link Activity#onCreate}
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @removed this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
+    @UnsupportedAppUsage
     public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
             Activity activity, Activity ... activities) {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
-            if (!sHasBeamFeature) {
-                return;
-            }
-        }
-        int targetSdkVersion = getSdkVersion();
-        try {
-            if (activity == null) {
-                throw new NullPointerException("activity cannot be null");
-            }
-            mNfcActivityManager.setOnNdefPushCompleteCallback(activity, callback);
-            for (Activity a : activities) {
-                if (a == null) {
-                    throw new NullPointerException("activities cannot contain null");
-                }
-                mNfcActivityManager.setOnNdefPushCompleteCallback(a, callback);
-            }
-        } catch (IllegalStateException e) {
-            if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) {
-                // Less strict on old applications - just log the error
-                Log.e(TAG, "Cannot call API with Activity that has already " +
-                        "been destroyed", e);
-            } else {
-                // Prevent new applications from making this mistake, re-throw
-                throw(e);
-            }
         }
     }
 
@@ -1712,46 +1604,18 @@
      * @param activity the current foreground Activity that has registered data to share
      * @return whether the Beam animation was successfully invoked
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @removed this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
+    @UnsupportedAppUsage
     public boolean invokeBeam(Activity activity) {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
-            if (!sHasBeamFeature) {
-                return false;
-            }
         }
-        if (activity == null) {
-            throw new NullPointerException("activity may not be null.");
-        }
-        enforceResumed(activity);
-        try {
-            sService.invokeBeam();
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG, "invokeBeam: NFC process has died.");
-            attemptDeadServiceRecovery(e);
-            return false;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public boolean invokeBeam(BeamShareData shareData) {
-        try {
-            Log.e(TAG, "invokeBeamInternal()");
-            sService.invokeBeamInternal(shareData);
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG, "invokeBeam: NFC process has died.");
-            attemptDeadServiceRecovery(e);
-            return false;
-        }
+        return false;
     }
 
     /**
@@ -1777,25 +1641,18 @@
      *
      * @param activity foreground activity
      * @param message a NDEF Message to push over NFC
-     * @throws IllegalStateException if the activity is not currently in the foreground
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated use {@link #setNdefPushMessage} instead
+     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
+     * @removed this feature is removed. File sharing can work using other technology like
+     * Bluetooth.
      */
     @Deprecated
+    @UnsupportedAppUsage
     public void enableForegroundNdefPush(Activity activity, NdefMessage message) {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
-            if (!sHasBeamFeature) {
-                return;
-            }
         }
-        if (activity == null || message == null) {
-            throw new NullPointerException();
-        }
-        enforceResumed(activity);
-        mNfcActivityManager.setNdefPushMessage(activity, message, 0);
     }
 
     /**
@@ -1814,27 +1671,18 @@
      * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
      *
      * @param activity the Foreground activity
-     * @throws IllegalStateException if the Activity has already been paused
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated use {@link #setNdefPushMessage} instead
+     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
+     * @removed this feature is removed. File sharing can work using other technology like
+     * Bluetooth.
      */
     @Deprecated
+    @UnsupportedAppUsage
     public void disableForegroundNdefPush(Activity activity) {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
-            if (!sHasBeamFeature) {
-                return;
-            }
         }
-        if (activity == null) {
-            throw new NullPointerException();
-        }
-        enforceResumed(activity);
-        mNfcActivityManager.setNdefPushMessage(activity, null, 0);
-        mNfcActivityManager.setNdefPushMessageCallback(activity, null, 0);
-        mNfcActivityManager.setOnNdefPushCompleteCallback(activity, null);
     }
 
     /**
@@ -1959,40 +1807,26 @@
      * Enable NDEF Push feature.
      * <p>This API is for the Settings application.
      * @hide
+     * @removed
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @UnsupportedAppUsage
     public boolean enableNdefPush() {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        try {
-            return sService.enableNdefPush();
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            return false;
-        }
+        return false;
     }
 
     /**
      * Disable NDEF Push feature.
      * <p>This API is for the Settings application.
      * @hide
+     * @removed
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @UnsupportedAppUsage
     public boolean disableNdefPush() {
-        synchronized (NfcAdapter.class) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        try {
-            return sService.disableNdefPush();
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            return false;
-        }
+        return false;
     }
 
     /**
@@ -2018,26 +1852,18 @@
      * @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS
      * @return true if NDEF Push feature is enabled
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * @removed this feature is removed. File sharing can work using other technology like
      * Bluetooth.
      */
     @java.lang.Deprecated
-
+    @UnsupportedAppUsage
     public boolean isNdefPushEnabled() {
         synchronized (NfcAdapter.class) {
             if (!sHasNfcFeature) {
                 throw new UnsupportedOperationException();
             }
-            if (!sHasBeamFeature) {
-                return false;
-            }
         }
-        try {
-            return sService.isNdefPushEnabled();
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            return false;
-        }
+        return false;
     }
 
     /**
@@ -2128,17 +1954,6 @@
     }
 
     /**
-     * @hide
-     */
-    public void setP2pModes(int initiatorModes, int targetModes) {
-        try {
-            sService.setP2pModes(initiatorModes, targetModes);
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-        }
-    }
-
-    /**
      * Registers a new NFC unlock handler with the NFC service.
      *
      * <p />NFC unlock handlers are intended to unlock the keyguard in the presence of a trusted
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 832f23c..9689be2 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -787,12 +787,9 @@
          * PackageManager.setComponentEnabledSetting} will now throw an
          * IllegalArgumentException if the given component class name does not
          * exist in the application's manifest.
-         * <li> {@link android.nfc.NfcAdapter#setNdefPushMessage
-         * NfcAdapter.setNdefPushMessage},
-         * {@link android.nfc.NfcAdapter#setNdefPushMessageCallback
-         * NfcAdapter.setNdefPushMessageCallback} and
-         * {@link android.nfc.NfcAdapter#setOnNdefPushCompleteCallback
-         * NfcAdapter.setOnNdefPushCompleteCallback} will throw
+         * <li> {@code NfcAdapter.setNdefPushMessage},
+         * {@code NfcAdapter.setNdefPushMessageCallback} and
+         * {@code NfcAdapter.setOnNdefPushCompleteCallback} will throw
          * IllegalStateException if called after the Activity has been destroyed.
          * <li> Accessibility services must require the new
          * {@link android.Manifest.permission#BIND_ACCESSIBILITY_SERVICE} permission or
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 2142c4c..13d54ef 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -2994,6 +2994,7 @@
      */
     @IntDef(prefix = { "LOW_POWER_STANDBY_ALLOWED_REASON_" }, flag = true, value = {
             LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION,
+            LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface LowPowerStandbyAllowedReason {
@@ -3006,6 +3007,13 @@
      */
     public static final int LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION = 1 << 0;
 
+    /**
+     * Exempts apps on the temporary powersave allowlist.
+     *
+     * @see #isAllowedInLowPowerStandby(int)
+     */
+    public static final int LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST = 1 << 1;
+
     /** @hide */
     public static String lowPowerStandbyAllowedReasonsToString(
             @LowPowerStandbyAllowedReason int allowedReasons) {
@@ -3014,6 +3022,10 @@
             allowedStrings.add("ALLOWED_REASON_VOICE_INTERACTION");
             allowedReasons &= ~LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION;
         }
+        if ((allowedReasons & LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST) != 0) {
+            allowedStrings.add("ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST");
+            allowedReasons &= ~LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST;
+        }
         if (allowedReasons != 0) {
             allowedStrings.add(String.valueOf(allowedReasons));
         }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e0c022f..563adf8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1716,7 +1716,6 @@
      * Input: Nothing.
      * <p>
      * Output: Nothing
-     * @see android.nfc.NfcAdapter#isNdefPushEnabled()
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_NFCSHARING_SETTINGS =
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index af43222..98c0d7f 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -129,7 +129,8 @@
      *
      * @hide
      */
-    public static final class TimeResult {
+    // Non-final for mocking frameworks
+    public static class TimeResult {
         private final long mUnixEpochTimeMillis;
         private final long mElapsedRealtimeMillis;
         private final int mUncertaintyMillis;
diff --git a/core/java/android/util/PackageUtils.java b/core/java/android/util/PackageUtils.java
index 6f8c5db..ea7efc7 100644
--- a/core/java/android/util/PackageUtils.java
+++ b/core/java/android/util/PackageUtils.java
@@ -184,24 +184,15 @@
     }
 
     /**
-     * @see #computeSha256DigestForLargeFile(String, byte[], String)
-     */
-    public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
-            @NonNull byte[] fileBuffer) {
-        return computeSha256DigestForLargeFile(filePath, fileBuffer, null);
-    }
-
-    /**
-     * Computes the SHA256 digest of large files. This is typically useful for large APEXs.
+     * Computes the SHA256 digest of a large file.
      * @param filePath The path to which the file's content is to be hashed.
      * @param fileBuffer A buffer to read file's content into memory. It is strongly recommended to
      *                   make use of the {@link #createLargeFileBuffer()} method to create this
      *                   buffer.
-     * @param separator Separator between each pair of characters, such as colon, or null to omit.
-     * @return The SHA256 digest or null if an error occurs.
+     * @return The byte array of SHA256 digest or null if an error occurs.
      */
-    public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
-            @NonNull byte[] fileBuffer, @Nullable String separator) {
+    public static @Nullable byte[] computeSha256DigestForLargeFileAsBytes(@NonNull String filePath,
+            @NonNull byte[] fileBuffer) {
         MessageDigest messageDigest;
         try {
             messageDigest = MessageDigest.getInstance("SHA256");
@@ -221,8 +212,30 @@
             return null;
         }
 
-        byte[] resultBytes = messageDigest.digest();
+        return messageDigest.digest();
+    }
 
+    /**
+     * @see #computeSha256DigestForLargeFile(String, byte[], String)
+     */
+    public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
+            @NonNull byte[] fileBuffer) {
+        return computeSha256DigestForLargeFile(filePath, fileBuffer, null);
+    }
+
+    /**
+     * Computes the SHA256 digest of a large file.
+     * @param filePath The path to which the file's content is to be hashed.
+     * @param fileBuffer A buffer to read file's content into memory. It is strongly recommended to
+     *                   make use of the {@link #createLargeFileBuffer()} method to create this
+     *                   buffer.
+     * @param separator Separator between each pair of characters, such as colon, or null to omit.
+     * @see #computeSha256DigestForLargeFile(String, byte[])
+     * @return The encoded string of SHA256 digest or null if an error occurs.
+     */
+    public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
+            @NonNull byte[] fileBuffer, @Nullable String separator) {
+        byte[] resultBytes = computeSha256DigestForLargeFileAsBytes(filePath, fileBuffer);
         if (separator == null) {
             return HexEncoding.encodeToString(resultBytes, false);
         }
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index bda707b..1898407 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -619,10 +619,11 @@
             }
             if (in.readInt() != 0) {
                 event.mDragSurface = SurfaceControl.CREATOR.createFromParcel(in);
+                event.mDragSurface.setUnreleasedWarningCallSite("DragEvent");
             }
             if (in.readInt() != 0) {
                 event.mDragAndDropPermissions =
-                        IDragAndDropPermissions.Stub.asInterface(in.readStrongBinder());;
+                        IDragAndDropPermissions.Stub.asInterface(in.readStrongBinder());
             }
             return event;
         }
diff --git a/core/java/android/view/RemoteAnimationTarget.java b/core/java/android/view/RemoteAnimationTarget.java
index 8d8ddb9..5ea640c 100644
--- a/core/java/android/view/RemoteAnimationTarget.java
+++ b/core/java/android/view/RemoteAnimationTarget.java
@@ -296,6 +296,9 @@
         taskId = in.readInt();
         mode = in.readInt();
         leash = in.readTypedObject(SurfaceControl.CREATOR);
+        if (leash != null) {
+            leash.setUnreleasedWarningCallSite("RemoteAnimationTarget[leash]");
+        }
         isTranslucent = in.readBoolean();
         clipRect = in.readTypedObject(Rect.CREATOR);
         contentInsets = in.readTypedObject(Rect.CREATOR);
@@ -307,6 +310,9 @@
         windowConfiguration = in.readTypedObject(WindowConfiguration.CREATOR);
         isNotInRecents = in.readBoolean();
         startLeash = in.readTypedObject(SurfaceControl.CREATOR);
+        if (startLeash != null) {
+            startLeash.setUnreleasedWarningCallSite("RemoteAnimationTarget[startLeash]");
+        }
         startBounds = in.readTypedObject(Rect.CREATOR);
         taskInfo = in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
         allowEnterPip = in.readBoolean();
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 8e09411..c3302cb 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1291,6 +1291,20 @@
     }
 
     /**
+     * Provides more information to show about the source of this SurfaceControl if it is finalized
+     * without being released. This is primarily intended for callers to update the call site after
+     * receiving a SurfaceControl from another process, which would otherwise get a generic default
+     * call site.
+     * @hide
+     */
+    public void setUnreleasedWarningCallSite(@NonNull String callsite) {
+        if (!isValid()) {
+            return;
+        }
+        mCloseGuard.openWithCallSite("release", callsite);
+    }
+
+    /**
      * Checks whether two {@link SurfaceControl} objects represent the same surface.
      *
      * @param other The other object to check
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index f7bdd09..52b96de 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -170,6 +170,7 @@
         private SurfacePackage(Parcel in) {
             mSurfaceControl = new SurfaceControl();
             mSurfaceControl.readFromParcel(in);
+            mSurfaceControl.setUnreleasedWarningCallSite("SurfacePackage(Parcel)");
             mAccessibilityEmbeddedConnection = IAccessibilityEmbeddedConnection.Stub.asInterface(
                     in.readStrongBinder());
             mInputToken = in.readStrongBinder();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index cecfc8a..241ee5a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8945,11 +8945,33 @@
         outRect.set(position.left, position.top, position.right, position.bottom);
     }
 
+    /**
+     * Gets the location of this view in window coordinates.
+     *
+     * @param outRect The output location
+     * @param clipToParent Whether to clip child bounds to the parent ones.
+     * @hide
+     */
+    public void getBoundsInWindow(Rect outRect, boolean clipToParent) {
+        if (mAttachInfo == null) {
+            return;
+        }
+        RectF position = mAttachInfo.mTmpTransformRect;
+        getBoundsToWindowInternal(position, clipToParent);
+        outRect.set(Math.round(position.left), Math.round(position.top),
+                Math.round(position.right), Math.round(position.bottom));
+    }
+
     private void getBoundsToScreenInternal(RectF position, boolean clipToParent) {
         position.set(0, 0, mRight - mLeft, mBottom - mTop);
         mapRectFromViewToScreenCoords(position, clipToParent);
     }
 
+    private void getBoundsToWindowInternal(RectF position, boolean clipToParent) {
+        position.set(0, 0, mRight - mLeft, mBottom - mTop);
+        mapRectFromViewToWindowCoords(position, clipToParent);
+    }
+
     /**
      * Map a rectangle from view-relative coordinates to screen-relative coordinates
      *
@@ -8958,6 +8980,18 @@
      * @hide
      */
     public void mapRectFromViewToScreenCoords(RectF rect, boolean clipToParent) {
+        mapRectFromViewToWindowCoords(rect, clipToParent);
+        rect.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
+    }
+
+    /**
+     * Map a rectangle from view-relative coordinates to window-relative coordinates
+     *
+     * @param rect The rectangle to be mapped
+     * @param clipToParent Whether to clip child bounds to the parent ones.
+     * @hide
+     */
+    public void mapRectFromViewToWindowCoords(RectF rect, boolean clipToParent) {
         if (!hasIdentityMatrix()) {
             getMatrix().mapRect(rect);
         }
@@ -8990,8 +9024,6 @@
             ViewRootImpl viewRootImpl = (ViewRootImpl) parent;
             rect.offset(0, -viewRootImpl.mCurScrollY);
         }
-
-        rect.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
     }
 
     /**
@@ -10578,6 +10610,8 @@
 
         getBoundsOnScreen(bounds, true);
         info.setBoundsInScreen(bounds);
+        getBoundsInWindow(bounds, true);
+        info.setBoundsInWindow(bounds);
 
         ViewParent parent = getParentForAccessibility();
         if (parent instanceof View) {
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index d88cdf1..4576d62 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -906,6 +906,7 @@
     private int mBooleanProperties;
     private final Rect mBoundsInParent = new Rect();
     private final Rect mBoundsInScreen = new Rect();
+    private final Rect mBoundsInWindow = new Rect();
     private int mDrawingOrderInParent;
 
     private CharSequence mPackageName;
@@ -2156,6 +2157,49 @@
     }
 
     /**
+     * Gets the node bounds in window coordinates.
+     * <p>
+     * When magnification is enabled, the bounds in window are scaled up by magnification scale
+     * and the positions are also adjusted according to the offset of magnification viewport.
+     * For example, it returns Rect(-180, -180, 0, 0) for original bounds Rect(10, 10, 100, 100),
+     * when the magnification scale is 2 and offsets for X and Y are both 200.
+     * <p/>
+     *
+     * @param outBounds The output node bounds.
+     */
+    public void getBoundsInWindow(@NonNull Rect outBounds) {
+        outBounds.set(mBoundsInWindow.left, mBoundsInWindow.top,
+                mBoundsInWindow.right, mBoundsInWindow.bottom);
+    }
+
+    /**
+     * Returns the actual rect containing the node bounds in window coordinates.
+     *
+     * @hide Not safe to expose outside the framework.
+     */
+    @NonNull
+    public Rect getBoundsInWindow() {
+        return mBoundsInWindow;
+    }
+
+    /**
+     * Sets the node bounds in window coordinates.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param bounds The node bounds.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void setBoundsInWindow(@NonNull Rect bounds) {
+        enforceNotSealed();
+        mBoundsInWindow.set(bounds);
+    }
+
+    /**
      * Gets whether this node is checkable.
      *
      * @return True if the node is checkable.
@@ -4054,6 +4098,11 @@
             nonDefaultFields |= bitAt(fieldIndex);
         }
         fieldIndex++;
+        if (!Objects.equals(mBoundsInWindow, DEFAULT.mBoundsInWindow)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
+        fieldIndex++;
+
         if (!Objects.equals(mActions, DEFAULT.mActions)) nonDefaultFields |= bitAt(fieldIndex);
         fieldIndex++;
         if (mMaxTextLength != DEFAULT.mMaxTextLength) nonDefaultFields |= bitAt(fieldIndex);
@@ -4203,6 +4252,13 @@
         }
 
         if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            parcel.writeInt(mBoundsInWindow.top);
+            parcel.writeInt(mBoundsInWindow.bottom);
+            parcel.writeInt(mBoundsInWindow.left);
+            parcel.writeInt(mBoundsInWindow.right);
+        }
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             if (mActions != null && !mActions.isEmpty()) {
                 final int actionCount = mActions.size();
 
@@ -4333,6 +4389,7 @@
         mUniqueId = other.mUniqueId;
         mBoundsInParent.set(other.mBoundsInParent);
         mBoundsInScreen.set(other.mBoundsInScreen);
+        mBoundsInWindow.set(other.mBoundsInWindow);
         mPackageName = other.mPackageName;
         mClassName = other.mClassName;
         mText = other.mText;
@@ -4465,6 +4522,13 @@
         }
 
         if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mBoundsInWindow.top = parcel.readInt();
+            mBoundsInWindow.bottom = parcel.readInt();
+            mBoundsInWindow.left = parcel.readInt();
+            mBoundsInWindow.right = parcel.readInt();
+        }
+
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
             final long standardActions = parcel.readLong();
             addStandardActions(standardActions);
             final int nonStandardActionCount = parcel.readInt();
@@ -4815,6 +4879,7 @@
 
         builder.append("; boundsInParent: ").append(mBoundsInParent);
         builder.append("; boundsInScreen: ").append(mBoundsInScreen);
+        builder.append("; boundsInWindow: ").append(mBoundsInScreen);
 
         builder.append("; packageName: ").append(mPackageName);
         builder.append("; className: ").append(mClassName);
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index c8a69e2..e277b49 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -198,6 +198,7 @@
         in.readTypedList(mChanges, Change.CREATOR);
         mRootLeash = new SurfaceControl();
         mRootLeash.readFromParcel(in);
+        mRootLeash.setUnreleasedWarningCallSite("TransitionInfo");
         mRootOffset.readFromParcel(in);
         mOptions = in.readTypedObject(AnimationOptions.CREATOR);
     }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index b79c540..b4599c8 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -332,7 +332,6 @@
                 "libdl",
                 "libdl_android",
                 "libtimeinstate",
-                "libtflite",
                 "server_configurable_flags",
                 "libimage_io",
                 "libjpegdecoder",
diff --git a/core/proto/android/nfc/nfc_service.proto b/core/proto/android/nfc/nfc_service.proto
index 2df1d5d..1dcd5cc 100644
--- a/core/proto/android/nfc/nfc_service.proto
+++ b/core/proto/android/nfc/nfc_service.proto
@@ -60,7 +60,7 @@
     optional bool secure_nfc_capable = 13;
     optional bool vr_mode_enabled = 14;
     optional DiscoveryParamsProto discovery_params = 15;
-    optional P2pLinkManagerProto p2p_link_manager = 16;
+    reserved 16;
     optional com.android.nfc.cardemulation.CardEmulationManagerProto card_emulation_manager = 17;
     optional NfcDispatcherProto nfc_dispatcher = 18;
     optional string native_crash_logs = 19 [(.android.privacy).dest = DEST_EXPLICIT];
@@ -77,38 +77,6 @@
     optional bool enable_p2p = 5;
 }
 
-// Debugging information for com.android.nfc.P2pLinkManager
-message P2pLinkManagerProto {
-    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-    enum LinkState {
-        LINK_STATE_UNKNOWN = 0;
-        LINK_STATE_DOWN = 1;
-        LINK_STATE_DEBOUNCE = 2;
-        LINK_STATE_UP = 3;
-    }
-
-    enum SendState {
-        SEND_STATE_UNKNOWN = 0;
-        SEND_STATE_NOTHING_TO_SEND = 1;
-        SEND_STATE_NEED_CONFIRMATION = 2;
-        SEND_STATE_SENDING = 3;
-        SEND_STATE_COMPLETE = 4;
-        SEND_STATE_CANCELED = 5;
-    }
-
-    optional int32 default_miu = 1;
-    optional int32 default_rw_size = 2;
-    optional LinkState link_state = 3;
-    optional SendState send_state = 4;
-    optional int32 send_flags = 5;
-    optional bool send_enabled = 6;
-    optional bool receive_enabled = 7;
-    optional string callback_ndef = 8 [(.android.privacy).dest = DEST_EXPLICIT];
-    optional .android.nfc.NdefMessageProto message_to_send = 9;
-    repeated string uris_to_send = 10 [(.android.privacy).dest = DEST_EXPLICIT];
-}
-
 // Debugging information for com.android.nfc.NfcDispatcher
 message NfcDispatcherProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f937390..bb3fc01 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -176,6 +176,7 @@
     <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" />
     <protected-broadcast android:name="android.bluetooth.device.action.SDP_RECORD" />
     <protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.device.action.REMOTE_ISSUE_OCCURRED" />
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" />
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" />
     <protected-broadcast
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 11a4ed7..d2ee5de 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1648,14 +1648,25 @@
             or has been granted the access to one of the attached USB devices/accessories.
         -->
         <flag name="connectedDevice" value="0x10" />
-        <!-- Managing a media projection session, e.g, for screen recording or taking
-            screenshots.
+        <!-- Managing a {@link android.media.projection.MediaProjection MediaProjection} session,
+             e.g., for screen recording or takingscreenshots.
 
-            <p>For apps with <code>targetSdkVersion</code>
-            {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above, starting a foreground
-            service with this type will require permission
-            {@link android.Manifest.permission#FOREGROUND_SERVICE_MEDIA_PROJECTION}, and the user
-            must have allowed the screen capture request from this app.
+             <p>
+             To capture through {@link android.media.projection.MediaProjection}, an app must start
+             a foreground service with the type corresponding to this constant. This type should
+             only be used for {@link android.media.projection.MediaProjection}. Capturing screen
+             contents via
+             {@link android.media.projection.MediaProjection#createVirtualDisplay(String, int, int,
+             int, int, android.view.Surface, android.hardware.display.VirtualDisplay.Callback,
+             android.os.Handler) createVirtualDisplay} conveniently allows recording, presenting
+             screen contents into a meeting, taking screenshots, or several other scenarios.
+             </p>
+
+             <p>For apps with <code>targetSdkVersion</code>
+             {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above, starting a
+             foreground service with this type will require permission
+             {@link android.Manifest.permission#FOREGROUND_SERVICE_MEDIA_PROJECTION}, and the user
+             must have allowed the screen capture request from this app.
         -->
         <flag name="mediaProjection" value="0x20" />
         <!-- Use the camera device or record video.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c75ee93..8e5ae9c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2997,6 +2997,12 @@
     <string name="config_customAdbWifiNetworkConfirmationSecondaryUserComponent"
             >com.android.systemui/com.android.systemui.wifi.WifiDebuggingSecondaryUserActivity</string>
 
+    <!-- Package name of the system service that implements the shared connectivity service -->
+    <string translatable="false" name="shared_connectivity_service_package"></string>
+
+    <!-- Intent action used when binding to the shared connectivity service -->
+    <string translatable="false" name="shared_connectivity_service_intent_action"></string>
+
     <!-- Component name of the activity that shows the usb containment status. -->
     <string name="config_usbContaminantActivity" translatable="false"
             >com.android.systemui/com.android.systemui.usb.UsbContaminantActivity</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d7cdf73..91d5692 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4938,6 +4938,9 @@
   <java-symbol type="bool" name="config_stopSystemPackagesByDefault"/>
   <java-symbol type="string" name="config_wearServiceComponent" />
 
+  <java-symbol type="string" name="shared_connectivity_service_package" />
+  <java-symbol type="string" name="shared_connectivity_service_intent_action" />
+
   <!-- Whether to show weather on the lockscreen by default. -->
   <java-symbol type="bool" name="config_lockscreenWeatherEnabledByDefault" />
 </resources>
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
index 248420f..0d7c8b8 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
@@ -46,7 +46,7 @@
     // The number of fields tested in the corresponding CTS AccessibilityNodeInfoTest:
     // See fullyPopulateAccessibilityNodeInfo, assertEqualsAccessibilityNodeInfo,
     // and assertAccessibilityNodeInfoCleared in that class.
-    private static final int NUM_MARSHALLED_PROPERTIES = 42;
+    private static final int NUM_MARSHALLED_PROPERTIES = 43;
 
     /**
      * The number of properties that are purposely not marshalled
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
index b085b73..34bf9e0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
@@ -76,6 +76,7 @@
                             + " mDisplayAreasInfo.get():" + mDisplayAreasInfo.get(displayId));
         }
 
+        leash.setUnreleasedWarningCallSite("RootDisplayAreaOrganizer.onDisplayAreaAppeared");
         mDisplayAreasInfo.put(displayId, displayAreaInfo);
         mLeashes.put(displayId, leash);
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
index ca977ed..544d757 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
@@ -122,6 +122,8 @@
                             + " mDisplayAreasInfo.get():" + mDisplayAreasInfo.get(displayId));
         }
 
+        leash.setUnreleasedWarningCallSite(
+                "RootTaskDisplayAreaOrganizer.onDisplayAreaAppeared");
         mDisplayAreasInfo.put(displayId, displayAreaInfo);
         mLeashes.put(displayId, leash);
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index b5ef72a..585f81c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -464,6 +464,9 @@
 
     @Override
     public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
+        if (leash != null) {
+            leash.setUnreleasedWarningCallSite("ShellTaskOrganizer.onTaskAppeared");
+        }
         synchronized (mLock) {
             onTaskAppeared(new TaskAppearedInfo(taskInfo, leash));
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
index f376e1f..32894cd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java
@@ -117,6 +117,7 @@
     @Override
     public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo,
             @NonNull SurfaceControl leash) {
+        leash.setUnreleasedWarningCallSite("HideDisplayCutoutOrganizer.onDisplayAreaAppeared");
         if (!addDisplayAreaInfoAndLeashToMap(displayAreaInfo, leash)) {
             return;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
index 451afa0..38ce164 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -154,6 +154,8 @@
     @Override
     public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo,
             @NonNull SurfaceControl leash) {
+        leash.setUnreleasedWarningCallSite(
+                "OneHandedSiaplyAreaOrganizer.onDisplayAreaAppeared");
         mDisplayAreaTokenMap.put(displayAreaInfo.token, leash);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index ec34f73..00ed094 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -1215,6 +1215,9 @@
         @Override
         public void stopSwipePipToHome(int taskId, ComponentName componentName,
                 Rect destinationBounds, SurfaceControl overlay) {
+            if (overlay != null) {
+                overlay.setUnreleasedWarningCallSite("PipController.stopSwipePipToHome");
+            }
             executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome",
                     (controller) -> {
                         controller.stopSwipePipToHome(taskId, componentName, destinationBounds,
diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp
index a55de95..c1bcb55 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.cpp
+++ b/libs/hwui/pipeline/skia/ShaderCache.cpp
@@ -33,7 +33,8 @@
 // Cache size limits.
 static const size_t maxKeySize = 1024;
 static const size_t maxValueSize = 2 * 1024 * 1024;
-static const size_t maxTotalSize = 1024 * 1024;
+static const size_t maxTotalSize = 4 * 1024 * 1024;
+static_assert(maxKeySize + maxValueSize < maxTotalSize);
 
 ShaderCache::ShaderCache() {
     // There is an "incomplete FileBlobCache type" compilation error, if ctor is moved to header.
diff --git a/media/java/android/media/projection/MediaProjectionManager.java b/media/java/android/media/projection/MediaProjectionManager.java
index 6d65c26..f327e4e 100644
--- a/media/java/android/media/projection/MediaProjectionManager.java
+++ b/media/java/android/media/projection/MediaProjectionManager.java
@@ -29,6 +29,7 @@
 import android.os.ServiceManager;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.Surface;
 
 import java.util.Map;
 
@@ -74,8 +75,9 @@
      * Returns an {@link Intent} that <b>must</b> be passed to
      * {@link Activity#startActivityForResult(Intent, int)} (or similar) in order to start screen
      * capture. The activity will prompt the user whether to allow screen capture.  The result of
-     * this activity (received by overriding {@link Activity#onActivityResult(int, int, Intent)}
-     * should be passed to {@link #getMediaProjection(int, Intent)}.
+     * this activity (received by overriding {@link Activity#onActivityResult(int, int, Intent)
+     * onActivityResult(int, int, Intent)}) should be passed to
+     * {@link #getMediaProjection(int, Intent)}.
      * <p>
      * Identical to calling {@link #createScreenCaptureIntent(MediaProjectionConfig)} with
      * a {@link MediaProjectionConfig#createConfigForUserChoice()}.
@@ -102,8 +104,8 @@
      * capture. Customizes the activity and resulting {@link MediaProjection} session based up
      * the provided {@code config}. The activity will prompt the user whether to allow screen
      * capture. The result of this activity (received by overriding
-     * {@link Activity#onActivityResult(int, int, Intent)}) should be passed to
-     * {@link #getMediaProjection(int, Intent)}.
+     * {@link Activity#onActivityResult(int, int, Intent) onActivityResult(int, int, Intent)})
+     * should be passed to {@link #getMediaProjection(int, Intent)}.
      *
      * <p>
      * If {@link MediaProjectionConfig} was created from:
@@ -146,47 +148,48 @@
 
     /**
      * Retrieves the {@link MediaProjection} obtained from a successful screen
-     * capture request. The result code and data from the request are provided
-     * by overriding {@link Activity#onActivityResult(int, int, Intent)
-     * onActivityResult(int, int, Intent)}, which is called after starting an
-     * activity using {@link #createScreenCaptureIntent()}.
-     *
-     * <p>Starting from Android {@link android.os.Build.VERSION_CODES#R}, if
-     * your application requests the
-     * {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW
-     * SYSTEM_ALERT_WINDOW} permission, and the user has not explicitly denied
-     * it, the permission will be automatically granted until the projection is
-     * stopped. The permission allows your app to display user controls on top
-     * of the screen being captured.
-     *
-     * <p>Apps targeting SDK version {@link android.os.Build.VERSION_CODES#Q} or
-     * later must set the
-     * {@link android.R.attr#foregroundServiceType foregroundServiceType}
-     * attribute to {@code mediaProjection} in the
-     * <a href="/guide/topics/manifest/service-element">
-     * <code>&lt;service&gt;</code></a> element of the app's manifest file;
-     * {@code mediaProjection} is equivalent to
+     * capture request. The result code and data from the request are provided by overriding
+     * {@link Activity#onActivityResult(int, int, Intent) onActivityResult(int, int, Intent)},
+     * which is called after starting an activity using {@link #createScreenCaptureIntent()}.
+     * <p>
+     * Starting from Android {@link android.os.Build.VERSION_CODES#R R}, if your application
+     * requests the {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW SYSTEM_ALERT_WINDOW}
+     * permission, and the user has not explicitly denied it, the permission will be automatically
+     * granted until the projection is stopped. The permission allows your app to display user
+     * controls on top of the screen being captured.
+     * </p>
+     * <p>
+     * An app targeting SDK version {@link android.os.Build.VERSION_CODES#Q Q} or later must
+     * invoke {@code getMediaProjection} and maintain the capture session
+     * ({@link MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface,
+     * android.hardware.display.VirtualDisplay.Callback, Handler)
+     * MediaProjection#createVirtualDisplay}) while running a foreground service. The app must set
+     * the {@link android.R.attr#foregroundServiceType foregroundServiceType} attribute to
      * {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
-     * FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION}.
+     * FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION} in the
+     * <a href="/guide/topics/manifest/service-element"><code>&lt;service&gt;</code></a> element of
+     * the app's manifest file.
+     * </p>
      *
-     * @see <a href="/guide/components/foreground-services">
-     *      Foreground services developer guide</a>
-     * @see <a href="/guide/topics/large-screens/media-projection">
-     *      Media projection developer guide</a>
-     *
-     * @param resultCode The result code from
-     *      {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)
-     *      onActivityResult(int, int, Intent)}.
-     * @param resultData The result data from
-     *      {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)
-     *      onActivityResult(int, int, Intent)}.
-     * @return The media projection obtained from a successful screen capture
-     *      request, or null if the result of the screen capture request is not
-     *      {@link Activity#RESULT_OK RESULT_OK}.
+     * @param resultCode The result code from {@link Activity#onActivityResult(int, int, Intent)
+     *                   onActivityResult(int, int, Intent)}.
+     * @param resultData The result data from {@link Activity#onActivityResult(int, int, Intent)
+     *                   onActivityResult(int, int, Intent)}.
+     * @return The media projection obtained from a successful screen capture request, or null if
+     * the result of the screen capture request is not {@link Activity#RESULT_OK RESULT_OK}.
      * @throws IllegalStateException On
-     *      pre-{@link android.os.Build.VERSION_CODES#Q Q} devices if a
-     *      previously obtained {@code MediaProjection} from the same
-     *      {@code resultData} has not yet been stopped.
+     *                               pre-{@link android.os.Build.VERSION_CODES#Q Q} devices if a
+     *                               previously obtained {@code MediaProjection} from the same
+     *                               {@code resultData} has not yet been stopped.
+     * @throws SecurityException     On {@link android.os.Build.VERSION_CODES#Q Q}+ devices if not
+     *                               invoked from a foreground service with type
+     *                {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
+     *                               FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION}, unless caller is a
+     *                               privileged app.
+     * @see <a href="/guide/components/foreground-services">
+     * Foreground services developer guide</a>
+     * @see <a href="/guide/topics/large-screens/media-projection">
+     * Media projection developer guide</a>
      */
     public MediaProjection getMediaProjection(int resultCode, @NonNull Intent resultData) {
         if (resultCode != Activity.RESULT_OK || resultData == null) {
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 00a58f2..7306a1f 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -116,6 +116,36 @@
         <item>full</item>
     </string-array>
 
+    <!-- Titles for Bluetooth HCI Snoop Filtered Logging -->
+    <string-array name="bt_hci_snoop_log_filters_entries">
+        <item>Headers Filtered</item>
+        <item>A2DP Media Packets Filtered</item>
+        <item>RFCOMM Channel Filtered</item>
+    </string-array>
+
+        <!-- Values for Bluetooth HCI Snoop Filtered Logging -->
+    <string-array name="bt_hci_snoop_log_filters_values" translatable="false">
+        <item>headers</item>
+        <item>profiles.a2dp</item>
+        <item>profiles.rfcomm</item>
+    </string-array>
+
+        <!-- Titles for Bluetooth HCI Snoop Filtered Logging -->
+    <string-array name="bt_hci_snoop_log_profile_filter_entries">
+        <item>Disabled</item>
+        <item>Magic</item>
+        <item>Header</item>
+        <item>Full Filter</item>
+    </string-array>
+
+        <!-- Values for Bluetooth HCI Snoop Filtered Logging -->
+    <string-array name="bt_hci_snoop_log_profile_filter_values" translatable="false">
+        <item>disabled</item>
+        <item>magic</item>
+        <item>header</item>
+        <item>fullfilter</item>
+    </string-array>
+
     <!-- Titles for Bluetooth AVRCP Versions -->
     <string-array name="bluetooth_avrcp_versions">
         <item>AVRCP 1.5 (Default)</item>
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableImageView.kt
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt
rename to packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableImageView.kt
index 7bbfec7..a1d9d90 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableImageView.kt
@@ -15,7 +15,7 @@
  *
  */
 
-package com.android.systemui.common.ui.view
+package com.android.systemui.animation.view
 
 import android.content.Context
 import android.util.AttributeSet
@@ -23,6 +23,7 @@
 import com.android.systemui.animation.LaunchableView
 import com.android.systemui.animation.LaunchableViewDelegate
 
+/** An [ImageView] that also implements [LaunchableView]. */
 class LaunchableImageView : ImageView, LaunchableView {
     private val delegate =
         LaunchableViewDelegate(
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableLinearLayout.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt
rename to packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableLinearLayout.kt
index 2edac52..bce2622 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableLinearLayout.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableLinearLayout.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.common.ui.view
+package com.android.systemui.animation.view
 
 import android.content.Context
 import android.util.AttributeSet
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableTextView.kt
similarity index 78%
copy from packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt
copy to packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableTextView.kt
index 7bbfec7..286996d 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/LaunchableImageView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableTextView.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -15,15 +15,16 @@
  *
  */
 
-package com.android.systemui.common.ui.view
+package com.android.systemui.animation.view
 
 import android.content.Context
 import android.util.AttributeSet
-import android.widget.ImageView
+import android.widget.TextView
 import com.android.systemui.animation.LaunchableView
 import com.android.systemui.animation.LaunchableViewDelegate
 
-class LaunchableImageView : ImageView, LaunchableView {
+/** A [TextView] that also implements [LaunchableView]. */
+class LaunchableTextView : TextView, LaunchableView {
     private val delegate =
         LaunchableViewDelegate(
             this,
@@ -38,13 +39,6 @@
         defStyleAttr: Int,
     ) : super(context, attrs, defStyleAttr)
 
-    constructor(
-        context: Context?,
-        attrs: AttributeSet?,
-        defStyleAttr: Int,
-        defStyleRes: Int,
-    ) : super(context, attrs, defStyleAttr, defStyleRes)
-
     override fun setShouldBlockVisibilityChanges(block: Boolean) {
         delegate.setShouldBlockVisibilityChanges(block)
     }
diff --git a/packages/SystemUI/res-keyguard/layout/footer_actions_text_button.xml b/packages/SystemUI/res-keyguard/layout/footer_actions_text_button.xml
index fc18132..6fe7d39 100644
--- a/packages/SystemUI/res-keyguard/layout/footer_actions_text_button.xml
+++ b/packages/SystemUI/res-keyguard/layout/footer_actions_text_button.xml
@@ -14,7 +14,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.systemui.common.ui.view.LaunchableLinearLayout
+<com.android.systemui.animation.view.LaunchableLinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="0dp"
     android:layout_height="@dimen/qs_security_footer_single_line_height"
@@ -63,4 +63,4 @@
         android:src="@*android:drawable/ic_chevron_end"
         android:autoMirrored="true"
         android:tint="?android:attr/textColorSecondary" />
-</com.android.systemui.common.ui.view.LaunchableLinearLayout>
\ No newline at end of file
+</com.android.systemui.animation.view.LaunchableLinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml b/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml
index 446bb01..fb78b49 100644
--- a/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml
@@ -20,7 +20,7 @@
     android:layout_width="wrap_content"
     android:paddingVertical="@dimen/dream_overlay_complication_home_controls_padding">
 
-    <com.android.systemui.common.ui.view.LaunchableImageView
+    <com.android.systemui.animation.view.LaunchableImageView
         android:id="@+id/home_controls_chip"
         android:layout_height="@dimen/keyguard_affordance_fixed_height"
         android:layout_width="@dimen/keyguard_affordance_fixed_width"
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 3f95515..2871cdf 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -59,7 +59,7 @@
 
     </LinearLayout>
 
-    <com.android.systemui.common.ui.view.LaunchableImageView
+    <com.android.systemui.animation.view.LaunchableImageView
         android:id="@+id/start_button"
         android:layout_height="@dimen/keyguard_affordance_fixed_height"
         android:layout_width="@dimen/keyguard_affordance_fixed_width"
@@ -72,7 +72,7 @@
         android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
         android:visibility="gone" />
 
-    <com.android.systemui.common.ui.view.LaunchableImageView
+    <com.android.systemui.animation.view.LaunchableImageView
         android:id="@+id/end_button"
         android:layout_height="@dimen/keyguard_affordance_fixed_height"
         android:layout_width="@dimen/keyguard_affordance_fixed_width"
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index f2e114b..9d91419 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -106,7 +106,7 @@
         app:layout_constrainedWidth="true"
         app:layout_constraintWidth_min="@dimen/min_clickable_item_size"
         app:layout_constraintHeight_min="@dimen/min_clickable_item_size">
-        <com.android.systemui.common.ui.view.LaunchableLinearLayout
+        <com.android.systemui.animation.view.LaunchableLinearLayout
             android:id="@+id/media_seamless_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -135,7 +135,7 @@
                 android:textDirection="locale"
                 android:textSize="12sp"
                 android:lineHeight="16sp" />
-        </com.android.systemui.common.ui.view.LaunchableLinearLayout>
+        </com.android.systemui.animation.view.LaunchableLinearLayout>
     </LinearLayout>
 
     <!-- Song name -->
diff --git a/packages/SystemUI/res/layout/ongoing_call_chip.xml b/packages/SystemUI/res/layout/ongoing_call_chip.xml
index 18d231c..238fc84 100644
--- a/packages/SystemUI/res/layout/ongoing_call_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_call_chip.xml
@@ -23,7 +23,7 @@
     android:layout_gravity="center_vertical|start"
     android:layout_marginStart="5dp"
 >
-    <com.android.systemui.common.ui.view.LaunchableLinearLayout
+    <com.android.systemui.animation.view.LaunchableLinearLayout
         android:id="@+id/ongoing_call_chip_background"
         android:layout_width="wrap_content"
         android:layout_height="@dimen/ongoing_appops_chip_height"
@@ -55,5 +55,5 @@
             android:textColor="?android:attr/colorPrimary"
         />
 
-    </com.android.systemui.common.ui.view.LaunchableLinearLayout>
+    </com.android.systemui.animation.view.LaunchableLinearLayout>
 </FrameLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
index 13b3aca..27fe747 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
@@ -70,7 +70,15 @@
         buffer.log(TAG, DEBUG, {
             str1 = entry.logKey
         }, {
-            "No alerting: snoozed package: $str1"
+            "No heads up: snoozed package: $str1"
+        })
+    }
+
+    fun logHeadsUpPackageSnoozeBypassedHasFsi(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
+        }, {
+            "Heads up: package snooze bypassed because notification has full-screen intent: $str1"
         })
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index 9bcf92d..afeb72f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -19,6 +19,7 @@
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
 import static com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD;
 import static com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR;
+import static com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.HUN_SNOOZE_BYPASSED_POTENTIALLY_SUPPRESSED_FSI;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -87,7 +88,10 @@
         FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD(1236),
 
         @UiEvent(doc = "HUN suppressed for old when")
-        HUN_SUPPRESSED_OLD_WHEN(1237);
+        HUN_SUPPRESSED_OLD_WHEN(1237),
+
+        @UiEvent(doc = "HUN snooze bypassed for potentially suppressed FSI")
+        HUN_SNOOZE_BYPASSED_POTENTIALLY_SUPPRESSED_FSI(1269);
 
         private final int mId;
 
@@ -409,7 +413,15 @@
             return false;
         }
 
-        if (isSnoozedPackage(sbn)) {
+        final boolean isSnoozedPackage = isSnoozedPackage(sbn);
+        final boolean fsiRequiresKeyguard = mFlags.fullScreenIntentRequiresKeyguard();
+        final boolean hasFsi = sbn.getNotification().fullScreenIntent != null;
+
+        // Assume any notification with an FSI is time-sensitive (like an alarm or incoming call)
+        // and ignore whether HUNs have been snoozed for the package.
+        final boolean shouldBypassSnooze = fsiRequiresKeyguard && hasFsi;
+
+        if (isSnoozedPackage && !shouldBypassSnooze) {
             if (log) mLogger.logNoHeadsUpPackageSnoozed(entry);
             return false;
         }
@@ -447,6 +459,19 @@
                 return false;
             }
         }
+
+        if (isSnoozedPackage) {
+            if (log) {
+                mLogger.logHeadsUpPackageSnoozeBypassedHasFsi(entry);
+                final int uid = entry.getSbn().getUid();
+                final String packageName = entry.getSbn().getPackageName();
+                mUiEventLogger.log(HUN_SNOOZE_BYPASSED_POTENTIALLY_SUPPRESSED_FSI, uid,
+                        packageName);
+            }
+
+            return true;
+        }
+
         if (log) mLogger.logHeadsUp(entry);
         return true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
index 2d80edb..270c592 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
@@ -21,7 +21,7 @@
 import android.widget.ImageView
 import android.widget.TextView
 import com.android.systemui.R
-import com.android.systemui.common.ui.view.LaunchableLinearLayout
+import com.android.systemui.animation.view.LaunchableLinearLayout
 
 class StatusBarUserSwitcherContainer(
     context: Context?,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java
index fc1d38b..8534d4f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java
@@ -37,7 +37,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.common.ui.view.LaunchableImageView;
+import com.android.systemui.animation.view.LaunchableImageView;
 import com.android.systemui.controls.ControlsServiceInfo;
 import com.android.systemui.controls.controller.ControlsController;
 import com.android.systemui.controls.controller.StructureInfo;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index 831d07f..07d0dbd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -741,7 +741,7 @@
     }
 
     @Test
-    public void testShouldFullScreen_snoozed_occluding_withStrictRules() throws Exception {
+    public void testShouldNotFullScreen_snoozed_occluding_withStrictRules() throws Exception {
         when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
         NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
         when(mPowerManager.isInteractive()).thenReturn(true);
@@ -753,16 +753,41 @@
         when(mKeyguardStateController.isOccluded()).thenReturn(true);
 
         assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
-                .isEqualTo(FullScreenIntentDecision.FSI_KEYGUARD_OCCLUDED);
+                .isEqualTo(FullScreenIntentDecision.NO_FSI_EXPECTED_TO_HUN);
         assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
-                .isTrue();
-        verify(mLogger, never()).logNoFullscreen(any(), any());
+                .isFalse();
+        verify(mLogger).logNoFullscreen(entry, "Expected to HUN");
         verify(mLogger, never()).logNoFullscreenWarning(any(), any());
-        verify(mLogger).logFullscreen(entry, "Expected not to HUN while keyguard occluded");
+        verify(mLogger, never()).logFullscreen(any(), any());
     }
 
     @Test
-    public void testShouldFullScreen_snoozed_lockedShade_withStrictRules() throws Exception {
+    public void testShouldHeadsUp_snoozed_occluding_withStrictRules() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mStatusBarStateController.getState()).thenReturn(SHADE);
+        when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        when(mKeyguardStateController.isOccluded()).thenReturn(true);
+
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
+
+        verify(mLogger).logHeadsUpPackageSnoozeBypassedHasFsi(entry);
+        verify(mLogger, never()).logHeadsUp(any());
+
+        assertThat(mUiEventLoggerFake.numLogs()).isEqualTo(1);
+        UiEventLoggerFake.FakeUiEvent fakeUiEvent = mUiEventLoggerFake.get(0);
+        assertThat(fakeUiEvent.eventId).isEqualTo(
+                NotificationInterruptEvent.HUN_SNOOZE_BYPASSED_POTENTIALLY_SUPPRESSED_FSI.getId());
+        assertThat(fakeUiEvent.uid).isEqualTo(entry.getSbn().getUid());
+        assertThat(fakeUiEvent.packageName).isEqualTo(entry.getSbn().getPackageName());
+    }
+
+    @Test
+    public void testShouldNotFullScreen_snoozed_lockedShade_withStrictRules() throws Exception {
         when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
         NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
         when(mPowerManager.isInteractive()).thenReturn(true);
@@ -774,12 +799,37 @@
         when(mKeyguardStateController.isOccluded()).thenReturn(false);
 
         assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
-                .isEqualTo(FullScreenIntentDecision.FSI_LOCKED_SHADE);
+                .isEqualTo(FullScreenIntentDecision.NO_FSI_EXPECTED_TO_HUN);
         assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
-                .isTrue();
-        verify(mLogger, never()).logNoFullscreen(any(), any());
+                .isFalse();
+        verify(mLogger).logNoFullscreen(entry, "Expected to HUN");
         verify(mLogger, never()).logNoFullscreenWarning(any(), any());
-        verify(mLogger).logFullscreen(entry, "Keyguard is showing and not occluded");
+        verify(mLogger, never()).logFullscreen(any(), any());
+    }
+
+    @Test
+    public void testShouldHeadsUp_snoozed_lockedShade_withStrictRules() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mStatusBarStateController.getState()).thenReturn(SHADE_LOCKED);
+        when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        when(mKeyguardStateController.isOccluded()).thenReturn(false);
+
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
+
+        verify(mLogger).logHeadsUpPackageSnoozeBypassedHasFsi(entry);
+        verify(mLogger, never()).logHeadsUp(any());
+
+        assertThat(mUiEventLoggerFake.numLogs()).isEqualTo(1);
+        UiEventLoggerFake.FakeUiEvent fakeUiEvent = mUiEventLoggerFake.get(0);
+        assertThat(fakeUiEvent.eventId).isEqualTo(
+                NotificationInterruptEvent.HUN_SNOOZE_BYPASSED_POTENTIALLY_SUPPRESSED_FSI.getId());
+        assertThat(fakeUiEvent.uid).isEqualTo(entry.getSbn().getUid());
+        assertThat(fakeUiEvent.packageName).isEqualTo(entry.getSbn().getPackageName());
     }
 
     @Test
@@ -795,21 +845,41 @@
         when(mKeyguardStateController.isOccluded()).thenReturn(false);
 
         assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
-                .isEqualTo(FullScreenIntentDecision.NO_FSI_NO_HUN_OR_KEYGUARD);
+                .isEqualTo(FullScreenIntentDecision.NO_FSI_EXPECTED_TO_HUN);
         assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
                 .isFalse();
-        verify(mLogger, never()).logNoFullscreen(any(), any());
-        verify(mLogger).logNoFullscreenWarning(entry, "Expected not to HUN while not on keyguard");
+        verify(mLogger).logNoFullscreen(entry, "Expected to HUN");
+        verify(mLogger, never()).logNoFullscreenWarning(any(), any());
         verify(mLogger, never()).logFullscreen(any(), any());
+    }
+
+    @Test
+    public void testShouldHeadsUp_snoozed_unlocked_withStrictRules() throws Exception {
+        when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true);
+        NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
+        when(mPowerManager.isInteractive()).thenReturn(true);
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mDreamManager.isDreaming()).thenReturn(false);
+        when(mStatusBarStateController.getState()).thenReturn(SHADE);
+        when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
+        when(mKeyguardStateController.isShowing()).thenReturn(false);
+        when(mKeyguardStateController.isOccluded()).thenReturn(false);
+
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
+
+        verify(mLogger).logHeadsUpPackageSnoozeBypassedHasFsi(entry);
+        verify(mLogger, never()).logHeadsUp(any());
 
         assertThat(mUiEventLoggerFake.numLogs()).isEqualTo(1);
         UiEventLoggerFake.FakeUiEvent fakeUiEvent = mUiEventLoggerFake.get(0);
         assertThat(fakeUiEvent.eventId).isEqualTo(
-                NotificationInterruptEvent.FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD.getId());
+                NotificationInterruptEvent.HUN_SNOOZE_BYPASSED_POTENTIALLY_SUPPRESSED_FSI.getId());
         assertThat(fakeUiEvent.uid).isEqualTo(entry.getSbn().getUid());
         assertThat(fakeUiEvent.packageName).isEqualTo(entry.getSbn().getPackageName());
     }
 
+    /* TODO: Verify the FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD UiEvent some other way. */
+
     /**
      * Bubbles can happen.
      */
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index eafd3e0..9d07365 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -263,26 +263,26 @@
             Map<Integer, byte[]> contentDigests = computeApkContentDigest(apkPath);
             if (contentDigests == null) {
                 Slog.d(TAG, "Failed to compute content digest for " + apkPath);
-                return new Checksum(0, new byte[] { -1 });
-            }
-
-            // in this iteration, we'll be supporting only 2 types of digests:
-            // CHUNKED_SHA256 and CHUNKED_SHA512.
-            // And only one of them will be available per package.
-            if (contentDigests.containsKey(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256)) {
-                return new Checksum(
-                        Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256,
-                        contentDigests.get(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256));
-            } else if (contentDigests.containsKey(
-                    ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA512)) {
-                return new Checksum(
-                        Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512,
-                        contentDigests.get(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA512));
             } else {
-                // TODO(b/259423111): considering putting the raw values for the algorithm & digest
-                //  into the bundle to track potential other digest algorithms that may be in use
-                return new Checksum(0, new byte[] { -1 });
+                // in this iteration, we'll be supporting only 2 types of digests:
+                // CHUNKED_SHA256 and CHUNKED_SHA512.
+                // And only one of them will be available per package.
+                if (contentDigests.containsKey(
+                            ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256)) {
+                    return new Checksum(
+                            Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256,
+                            contentDigests.get(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256));
+                } else if (contentDigests.containsKey(
+                        ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA512)) {
+                    return new Checksum(
+                            Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512,
+                            contentDigests.get(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA512));
+                }
             }
+            // When something went wrong, fall back to simple sha256.
+            byte[] digest = PackageUtils.computeSha256DigestForLargeFileAsBytes(apkPath,
+                    PackageUtils.createLargeFileBuffer());
+            return new Checksum(Checksum.TYPE_WHOLE_SHA256, digest);
         }
 
 
@@ -1199,7 +1199,7 @@
     }
 
     /**
-     * JobService to measure all covered binaries and record result to Westworld.
+     * JobService to measure all covered binaries and record results to statsd.
      */
     public static class UpdateMeasurementsJobService extends JobService {
         private static long sTimeLastRanMs = 0;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1fe097e..b7985a5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13692,6 +13692,17 @@
             // not be used generally, so we will be marking them as exported by default
             boolean requireExplicitFlagForDynamicReceivers = CompatChanges.isChangeEnabled(
                     DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED, callingUid);
+
+            // A receiver that is visible to instant apps must also be exported.
+            final boolean unexportedReceiverVisibleToInstantApps =
+                    ((flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0) && (
+                            (flags & Context.RECEIVER_NOT_EXPORTED) != 0);
+            if (unexportedReceiverVisibleToInstantApps && requireExplicitFlagForDynamicReceivers) {
+                throw new IllegalArgumentException(
+                        "Receiver can't specify both RECEIVER_VISIBLE_TO_INSTANT_APPS and "
+                                + "RECEIVER_NOT_EXPORTED flag");
+            }
+
             // STOPSHIP(b/259139792): Allow apps that are currently targeting U and in process of
             // updating their receivers to be exempt from this requirement until their receivers
             // are flagged.
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 14ecf9f..8b34fe0 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -376,7 +376,7 @@
         return DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                 ENABLE_DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER,
-                false); // assume false if the property is unknown
+                true);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 3f2083f..6032fec 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -167,10 +167,10 @@
     );
 
     /**
-     * User restrictions that cannot be set by profile owners of secondary users. When set by DO
-     * they will be applied to all users.
+     * User restrictions that can only be set by profile owners on the main user, or by device
+     * owners. When set by DO they will be applied to all users.
      */
-    private static final Set<String> PRIMARY_USER_ONLY_RESTRICTIONS = Sets.newArraySet(
+    private static final Set<String> MAIN_USER_ONLY_RESTRICTIONS = Sets.newArraySet(
             UserManager.DISALLOW_BLUETOOTH,
             UserManager.DISALLOW_USB_FILE_TRANSFER,
             UserManager.DISALLOW_CONFIG_TETHERING,
@@ -454,14 +454,14 @@
     }
 
     /**
-     * @return true if a restriction is settable by profile owner.  Note it takes a user ID because
-     * some restrictions can be changed by PO only when it's running on the system user.
+     * @return true if a restriction is settable by profile owner.  Note it takes a boolean to say
+     * if the relevant user is the {@link UserManager#isMainUser() MainUser}, because some
+     * restrictions can be changed by PO only when it's running on the main user.
      */
-    public static boolean canProfileOwnerChange(String restriction, int userId) {
+    public static boolean canProfileOwnerChange(String restriction, boolean isMainUser) {
         return !IMMUTABLE_BY_OWNERS.contains(restriction)
                 && !DEVICE_OWNER_ONLY_RESTRICTIONS.contains(restriction)
-                && !(userId != UserHandle.USER_SYSTEM
-                    && PRIMARY_USER_ONLY_RESTRICTIONS.contains(restriction));
+                && !(!isMainUser && MAIN_USER_ONLY_RESTRICTIONS.contains(restriction));
     }
 
     /**
@@ -494,7 +494,7 @@
     public static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType,
             String key) {
         return ((restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) && (
-                PRIMARY_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key)))
+                MAIN_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key)))
                 || ((restrictionOwnerType
                 == UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)
                 && PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS.contains(key))
diff --git a/services/core/java/com/android/server/power/LowPowerStandbyController.java b/services/core/java/com/android/server/power/LowPowerStandbyController.java
index 223bd55..0dc5f76 100644
--- a/services/core/java/com/android/server/power/LowPowerStandbyController.java
+++ b/services/core/java/com/android/server/power/LowPowerStandbyController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.power;
 
+import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST;
 import static android.os.PowerManager.lowPowerStandbyAllowedReasonsToString;
 
 import android.Manifest;
@@ -59,6 +60,7 @@
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 import com.android.server.LocalServices;
+import com.android.server.PowerAllowlistInternal;
 import com.android.server.net.NetworkPolicyManagerInternal;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -134,7 +136,7 @@
     @GuardedBy("mLock")
     private boolean mEnableCustomPolicy;
 
-    private final BroadcastReceiver mIdleBroadcastReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             switch (intent.getAction()) {
@@ -150,6 +152,8 @@
             }
         }
     };
+    private final TempAllowlistChangeListener mTempAllowlistChangeListener =
+            new TempAllowlistChangeListener();
 
     private final BroadcastReceiver mPackageBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -318,7 +322,7 @@
             updateSettingsLocked();
 
             if (mIsEnabled) {
-                registerBroadcastReceiver();
+                registerListeners();
             }
         }
 
@@ -594,7 +598,7 @@
             onNonInteractive();
         }
 
-        registerBroadcastReceiver();
+        registerListeners();
     }
 
     @GuardedBy("mLock")
@@ -604,7 +608,7 @@
         }
 
         cancelStandbyTimeoutAlarmLocked();
-        unregisterBroadcastReceiver();
+        unregisterListeners();
         updateActiveLocked();
     }
 
@@ -629,13 +633,13 @@
         }
     }
 
-    private void registerBroadcastReceiver() {
+    private void registerListeners() {
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
 
-        mContext.registerReceiver(mIdleBroadcastReceiver, intentFilter);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
 
         IntentFilter packageFilter = new IntentFilter();
         packageFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
@@ -648,12 +652,18 @@
         userFilter.addAction(Intent.ACTION_USER_ADDED);
         userFilter.addAction(Intent.ACTION_USER_REMOVED);
         mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
+
+        PowerAllowlistInternal pai = LocalServices.getService(PowerAllowlistInternal.class);
+        pai.registerTempAllowlistChangeListener(mTempAllowlistChangeListener);
     }
 
-    private void unregisterBroadcastReceiver() {
-        mContext.unregisterReceiver(mIdleBroadcastReceiver);
+    private void unregisterListeners() {
+        mContext.unregisterReceiver(mBroadcastReceiver);
         mContext.unregisterReceiver(mPackageBroadcastReceiver);
         mContext.unregisterReceiver(mUserReceiver);
+
+        PowerAllowlistInternal pai = LocalServices.getService(PowerAllowlistInternal.class);
+        pai.unregisterTempAllowlistChangeListener(mTempAllowlistChangeListener);
     }
 
     @GuardedBy("mLock")
@@ -1197,4 +1207,18 @@
             onSettingsChanged();
         }
     }
+
+    final class TempAllowlistChangeListener implements
+            PowerAllowlistInternal.TempAllowlistChangeListener {
+        @Override
+        public void onAppAdded(int uid) {
+            addToAllowlistInternal(uid, LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST);
+        }
+
+        @Override
+        public void onAppRemoved(int uid) {
+            removeFromAllowlistInternal(uid,
+                    LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST);
+        }
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index 71764dc..8f16737 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -555,8 +555,9 @@
             if (!hasLocalPolicyLocked(policyDefinition, userId)) {
                 return null;
             }
-            return getLocalPolicyStateLocked(policyDefinition, userId)
-                    .getPoliciesSetByAdmins().get(enforcingAdmin).getValue();
+            PolicyValue<V> value = getLocalPolicyStateLocked(policyDefinition, userId)
+                    .getPoliciesSetByAdmins().get(enforcingAdmin);
+            return value == null ? null : value.getValue();
         }
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f5a1b80..d6dc5d2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -235,6 +235,7 @@
 import android.app.admin.IntegerPolicyValue;
 import android.app.admin.IntentFilterPolicyKey;
 import android.app.admin.LockTaskPolicy;
+import android.app.admin.LongPolicyValue;
 import android.app.admin.ManagedProfileProvisioningParams;
 import android.app.admin.ManagedSubscriptionsPolicy;
 import android.app.admin.NetworkEvent;
@@ -9038,12 +9039,12 @@
     }
 
     private @UserIdInt int getMainUserId() {
-        UserHandle mainUser = mUserManager.getMainUser();
-        if (mainUser == null) {
+        int mainUserId = mUserManagerInternal.getMainUserId();
+        if (mainUserId == UserHandle.USER_NULL) {
             Slogf.d(LOG_TAG, "getMainUserId(): no main user, returning USER_SYSTEM");
             return UserHandle.USER_SYSTEM;
         }
-        return mainUser.getIdentifier();
+        return mainUserId;
     }
 
     // TODO(b/240562946): Remove api as owner name is not used.
@@ -12019,10 +12020,10 @@
             Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
         }
 
-        int userHandle = caller.getUserId();
+        int userId = caller.getUserId();
         synchronized (getLockObject()) {
             final ActiveAdmin activeAdmin = getParentOfAdminIfRequired(
-                    getProfileOwnerOrDeviceOwnerLocked(userHandle), parent);
+                    getProfileOwnerOrDeviceOwnerLocked(userId), parent);
 
             if (isDefaultDeviceOwner(caller)) {
                 if (!UserRestrictionsUtils.canDeviceOwnerChange(key)) {
@@ -12039,7 +12040,8 @@
                         "Cannot use the parent instance in Financed Device Owner mode");
             } else {
                 boolean profileOwnerCanChangeOnItself = !parent
-                        && UserRestrictionsUtils.canProfileOwnerChange(key, userHandle);
+                        && UserRestrictionsUtils.canProfileOwnerChange(
+                                key, userId == getMainUserId());
                 boolean orgOwnedProfileOwnerCanChangesGlobally = parent
                         && isProfileOwnerOfOrganizationOwnedDevice(caller)
                         && UserRestrictionsUtils.canProfileOwnerOfOrganizationOwnedDeviceChange(
@@ -12058,7 +12060,7 @@
             } else {
                 restrictions.remove(key);
             }
-            saveUserRestrictionsLocked(userHandle);
+            saveUserRestrictionsLocked(userId);
         }
         final int eventId = enabledFromThisOwner
                 ? DevicePolicyEnums.ADD_USER_RESTRICTION
@@ -12072,7 +12074,7 @@
             final int eventTag = enabledFromThisOwner
                     ? SecurityLog.TAG_USER_RESTRICTION_ADDED
                     : SecurityLog.TAG_USER_RESTRICTION_REMOVED;
-            SecurityLog.writeEvent(eventTag, who.getPackageName(), userHandle, key);
+            SecurityLog.writeEvent(eventTag, who.getPackageName(), userId, key);
         }
     }
 
@@ -16996,23 +16998,52 @@
         final CallerIdentity caller = getCallerIdentity(admin);
         Preconditions.checkCallAuthorization(
                 isProfileOwner(caller) || isDefaultDeviceOwner(caller));
+        final int userId = caller.getUserId();
 
-        synchronized (getLockObject()) {
-            final int userHandle = caller.getUserId();
-
-            DevicePolicyData policy = getUserData(userHandle);
-            return mInjector.binderWithCleanCallingIdentity(() -> {
-                if (policy.mPasswordTokenHandle != 0) {
-                    mLockPatternUtils.removeEscrowToken(policy.mPasswordTokenHandle, userHandle);
-                }
-                policy.mPasswordTokenHandle = mLockPatternUtils.addEscrowToken(token,
-                        userHandle, /*EscrowTokenStateChangeCallback*/ null);
-                saveSettingsLocked(userHandle);
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
+            EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+                    admin, userId);
+            Long currentTokenHandle = mDevicePolicyEngine.getLocalPolicySetByAdmin(
+                    PolicyDefinition.RESET_PASSWORD_TOKEN,
+                    enforcingAdmin,
+                    userId);
+            long tokenHandle = addEscrowToken(
+                    token, currentTokenHandle == null ? 0 : currentTokenHandle, userId);
+            if (tokenHandle == 0) {
+                return false;
+            }
+            mDevicePolicyEngine.setLocalPolicy(
+                    PolicyDefinition.RESET_PASSWORD_TOKEN,
+                    enforcingAdmin,
+                    new LongPolicyValue(tokenHandle),
+                    userId);
+            return true;
+        } else {
+            synchronized (getLockObject()) {
+                DevicePolicyData policy = getUserData(userId);
+                policy.mPasswordTokenHandle = addEscrowToken(
+                        token, policy.mPasswordTokenHandle, userId);
+                saveSettingsLocked(userId);
                 return policy.mPasswordTokenHandle != 0;
-            });
+            }
         }
     }
 
+    private long addEscrowToken(byte[] token, long currentPasswordTokenHandle, int userId) {
+        resetEscrowToken(currentPasswordTokenHandle, userId);
+        return mInjector.binderWithCleanCallingIdentity(() -> mLockPatternUtils.addEscrowToken(
+                token, userId, /* EscrowTokenStateChangeCallback= */ null));
+    }
+
+    private boolean resetEscrowToken(long tokenHandle, int userId) {
+        return mInjector.binderWithCleanCallingIdentity(() -> {
+            if (tokenHandle != 0) {
+                return mLockPatternUtils.removeEscrowToken(tokenHandle, userId);
+            }
+            return false;
+        });
+    }
+
     @Override
     public boolean clearResetPasswordToken(ComponentName admin) {
         if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
@@ -17021,22 +17052,34 @@
         final CallerIdentity caller = getCallerIdentity(admin);
         Preconditions.checkCallAuthorization(
                 isProfileOwner(caller) || isDefaultDeviceOwner(caller));
+        final int userId = caller.getUserId();
+        boolean result = false;
 
-        synchronized (getLockObject()) {
-            final int userHandle = caller.getUserId();
-
-            DevicePolicyData policy = getUserData(userHandle);
-            if (policy.mPasswordTokenHandle != 0) {
-                return mInjector.binderWithCleanCallingIdentity(() -> {
-                    boolean result = mLockPatternUtils.removeEscrowToken(
-                            policy.mPasswordTokenHandle, userHandle);
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
+            EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+                    admin, userId);
+            Long currentTokenHandle = mDevicePolicyEngine.getLocalPolicySetByAdmin(
+                    PolicyDefinition.RESET_PASSWORD_TOKEN,
+                    enforcingAdmin,
+                    userId);
+            if (currentTokenHandle != null) {
+                result = resetEscrowToken(currentTokenHandle, userId);
+                mDevicePolicyEngine.removeLocalPolicy(
+                        PolicyDefinition.RESET_PASSWORD_TOKEN,
+                        enforcingAdmin,
+                        userId);
+            }
+        } else {
+            synchronized (getLockObject()) {
+                DevicePolicyData policy = getUserData(userId);
+                if (policy.mPasswordTokenHandle != 0) {
+                    result = resetEscrowToken(policy.mPasswordTokenHandle, userId);
                     policy.mPasswordTokenHandle = 0;
-                    saveSettingsLocked(userHandle);
-                    return result;
-                });
+                    saveSettingsLocked(userId);
+                }
             }
         }
-        return false;
+        return result;
     }
 
     @Override
@@ -17048,16 +17091,30 @@
         Preconditions.checkCallAuthorization(
                 isProfileOwner(caller) || isDefaultDeviceOwner(caller));
 
-        synchronized (getLockObject()) {
-            return isResetPasswordTokenActiveForUserLocked(caller.getUserId());
+        int userId = caller.getUserId();
+
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
+            EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+                    admin, userId);
+            Long currentTokenHandle = mDevicePolicyEngine.getLocalPolicySetByAdmin(
+                    PolicyDefinition.RESET_PASSWORD_TOKEN,
+                    enforcingAdmin,
+                    userId);
+            return isResetPasswordTokenActiveForUserLocked(
+                    currentTokenHandle == null ? 0 : currentTokenHandle, userId);
+        } else {
+            synchronized (getLockObject()) {
+                DevicePolicyData policy = getUserData(userId);
+                return isResetPasswordTokenActiveForUserLocked(policy.mPasswordTokenHandle, userId);
+            }
         }
     }
 
-    private boolean isResetPasswordTokenActiveForUserLocked(int userHandle) {
-        DevicePolicyData policy = getUserData(userHandle);
-        if (policy.mPasswordTokenHandle != 0) {
+    private boolean isResetPasswordTokenActiveForUserLocked(
+            long passwordTokenHandle, int userHandle) {
+        if (passwordTokenHandle != 0) {
             return mInjector.binderWithCleanCallingIdentity(() ->
-                    mLockPatternUtils.isEscrowTokenActive(policy.mPasswordTokenHandle, userHandle));
+                    mLockPatternUtils.isEscrowTokenActive(passwordTokenHandle, userHandle));
         }
         return false;
     }
@@ -17074,24 +17131,41 @@
         Preconditions.checkCallAuthorization(
                 isProfileOwner(caller) || isDefaultDeviceOwner(caller));
 
-        synchronized (getLockObject()) {
-            DevicePolicyData policy = getUserData(caller.getUserId());
-            if (policy.mPasswordTokenHandle != 0) {
-                final String password = passwordOrNull != null ? passwordOrNull : "";
-                final boolean result = resetPasswordInternal(password, policy.mPasswordTokenHandle,
-                        token, flags, caller);
-                if (result) {
-                    DevicePolicyEventLogger
-                            .createEvent(DevicePolicyEnums.RESET_PASSWORD_WITH_TOKEN)
-                            .setAdmin(caller.getComponentName())
-                            .write();
-                }
-                return result;
+        int userId = caller.getUserId();
+        boolean result = false;
+        final String password = passwordOrNull != null ? passwordOrNull : "";
+
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
+            EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+                    admin, userId);
+            Long currentTokenHandle = mDevicePolicyEngine.getLocalPolicySetByAdmin(
+                    PolicyDefinition.RESET_PASSWORD_TOKEN,
+                    enforcingAdmin,
+                    userId);
+            if (currentTokenHandle != null && currentTokenHandle != 0) {
+                result = resetPasswordInternal(password, currentTokenHandle, token, flags, caller);
             } else {
                 Slogf.w(LOG_TAG, "No saved token handle");
             }
+        } else {
+            synchronized (getLockObject()) {
+                DevicePolicyData policy = getUserData(userId);
+                if (policy.mPasswordTokenHandle != 0) {
+                    result = resetPasswordInternal(
+                            password, policy.mPasswordTokenHandle, token, flags, caller);
+                } else {
+                    Slogf.w(LOG_TAG, "No saved token handle");
+                }
+            }
         }
-        return false;
+
+        if (result) {
+            DevicePolicyEventLogger
+                    .createEvent(DevicePolicyEnums.RESET_PASSWORD_WITH_TOKEN)
+                    .setAdmin(caller.getComponentName())
+                    .write();
+        }
+        return result;
     }
 
     @Override
@@ -18784,9 +18858,11 @@
                         "call canProfileOwnerResetPasswordWhenLocked"));
         synchronized (getLockObject()) {
             final ActiveAdmin poAdmin = getProfileOwnerAdminLocked(userId);
+            DevicePolicyData policy = getUserData(userId);
             if (poAdmin == null
                     || getEncryptionStatus() != ENCRYPTION_STATUS_ACTIVE_PER_USER
-                    || !isResetPasswordTokenActiveForUserLocked(userId)) {
+                    || !isResetPasswordTokenActiveForUserLocked(
+                            policy.mPasswordTokenHandle, userId)) {
                 return false;
             }
             final ApplicationInfo poAppInfo;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/LongPolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/LongPolicySerializer.java
new file mode 100644
index 0000000..f77d051
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/LongPolicySerializer.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.LongPolicyValue;
+import android.app.admin.PolicyKey;
+import android.util.Log;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.Objects;
+
+final class LongPolicySerializer extends PolicySerializer<Long> {
+
+    @Override
+    void saveToXml(PolicyKey policyKey, TypedXmlSerializer serializer, String attributeName,
+            @NonNull Long value) throws IOException {
+        Objects.requireNonNull(value);
+        serializer.attributeLong(/* namespace= */ null, attributeName, value);
+    }
+
+    @Nullable
+    @Override
+    LongPolicyValue readFromXml(TypedXmlPullParser parser, String attributeName) {
+        try {
+            return new LongPolicyValue(
+                    parser.getAttributeLong(/* namespace= */ null, attributeName));
+        } catch (XmlPullParserException e) {
+            Log.e(DevicePolicyEngine.TAG, "Error parsing Long policy value", e);
+            return null;
+        }
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
index ab6f732..9e0da26 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -199,6 +199,8 @@
             new PolicyDefinition<>(
                     new PackagePolicyKey(
                             DevicePolicyManager.APPLICATION_RESTRICTIONS_POLICY),
+                    // Don't need to take in a resolution mechanism since its never used, but might
+                    // need some refactoring to not always assume a non-null mechanism.
                     new MostRecent<>(),
                     POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_NON_COEXISTABLE_POLICY,
                     // Application restrictions are now stored and retrieved from DPMS, so no
@@ -221,6 +223,16 @@
                         DevicePolicyManager.APPLICATION_RESTRICTIONS_POLICY, packageName));
     }
 
+    static PolicyDefinition<Long> RESET_PASSWORD_TOKEN = new PolicyDefinition<>(
+            new NoArgsPolicyKey(DevicePolicyManager.RESET_PASSWORD_TOKEN_POLICY),
+            // Don't need to take in a resolution mechanism since its never used, but might
+            // need some refactoring to not always assume a non-null mechanism.
+            new MostRecent<>(),
+            POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_NON_COEXISTABLE_POLICY,
+            // DevicePolicyManagerService handles the enforcement, this just takes care of storage
+            (Long value, Context context, Integer userId, PolicyKey policyKey) -> true,
+            new LongPolicySerializer());
+
     private static final Map<String, PolicyDefinition<?>> sPolicyDefinitions = Map.of(
             DevicePolicyManager.AUTO_TIMEZONE_POLICY, AUTO_TIMEZONE,
             DevicePolicyManager.PERMISSION_GRANT_POLICY, GENERIC_PERMISSION_GRANT,
@@ -230,7 +242,8 @@
             DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY,
             GENERIC_PERSISTENT_PREFERRED_ACTIVITY,
             DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY, GENERIC_PACKAGE_UNINSTALL_BLOCKED,
-            DevicePolicyManager.APPLICATION_RESTRICTIONS_POLICY, GENERIC_APPLICATION_RESTRICTIONS
+            DevicePolicyManager.APPLICATION_RESTRICTIONS_POLICY, GENERIC_APPLICATION_RESTRICTIONS,
+            DevicePolicyManager.RESET_PASSWORD_TOKEN_POLICY, RESET_PASSWORD_TOKEN
     );
 
 
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 419351d4..9263bff 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -711,8 +711,6 @@
                 null);                                // description
 
         // Case 8: App1 gets "remove task"
-        final String app1Description = "remove task";
-
         sleep(1);
         final int app1IsolatedUidUser2 = 1099002; // isolated uid
         final long app1Pss4 = 34343;
@@ -739,7 +737,7 @@
 
         mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app1IsolatedUidUser2, app1UidUser2);
         noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
-                ApplicationExitInfo.SUBREASON_UNKNOWN, app1Description, now8);
+                ApplicationExitInfo.SUBREASON_REMOVE_TASK, null, now8);
 
         updateExitInfo(app, now8);
         list.clear();
@@ -749,21 +747,21 @@
         info = list.get(0);
 
         verifyApplicationExitInfo(
-                info,                                     // info
-                now8,                                     // timestamp
-                app1PidUser2,                             // pid
-                app1IsolatedUidUser2,                     // uid
-                app1UidUser2,                             // packageUid
-                null,                                     // definingUid
-                app1ProcessName,                          // processName
-                0,                                        // connectionGroup
-                ApplicationExitInfo.REASON_OTHER,         // reason
-                ApplicationExitInfo.SUBREASON_UNKNOWN,    // subReason
-                0,                                        // status
-                app1Pss4,                                 // pss
-                app1Rss4,                                 // rss
-                IMPORTANCE_CACHED,                        // importance
-                app1Description);                         // description
+                info,                                       // info
+                now8,                                       // timestamp
+                app1PidUser2,                               // pid
+                app1IsolatedUidUser2,                       // uid
+                app1UidUser2,                               // packageUid
+                null,                                       // definingUid
+                app1ProcessName,                            // processName
+                0,                                          // connectionGroup
+                ApplicationExitInfo.REASON_OTHER,           // reason
+                ApplicationExitInfo.SUBREASON_REMOVE_TASK,  // subReason
+                0,                                          // status
+                app1Pss4,                                   // pss
+                app1Rss4,                                   // rss
+                IMPORTANCE_CACHED,                          // importance
+                null);                                      // description
 
         // App1 gets "too many empty"
         final String app1Description2 = "too many empty";
@@ -1058,7 +1056,18 @@
         if (importance != null) {
             assertEquals(importance.intValue(), info.getImportance());
         }
-        if (description != null) {
+
+        // info.getDescription returns a combination of subReason & description
+        if ((subReason != null) && (subReason != ApplicationExitInfo.SUBREASON_UNKNOWN)
+                && (description != null)) {
+            assertTrue(TextUtils.equals(
+                    "[" + info.subreasonToString(subReason) + "] " + description,
+                    info.getDescription()));
+        } else if ((subReason != null) && (subReason != ApplicationExitInfo.SUBREASON_UNKNOWN)) {
+            assertTrue(TextUtils.equals(
+                    "[" + info.subreasonToString(subReason) + "]",
+                    info.getDescription()));
+        } else if (description != null) {
             assertTrue(TextUtils.equals(description, info.getDescription()));
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
index 07a5303..a387d4a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
@@ -20,7 +20,6 @@
 import static com.android.server.devicepolicy.DpmTestUtils.newRestrictions;
 
 import android.os.Bundle;
-import android.os.UserHandle;
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
@@ -77,30 +76,30 @@
         assertTrue(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_USER_SWITCH));
     }
 
-    public void testCanProfileOwnerChange() {
-        int user = UserHandle.USER_SYSTEM;
+    public void testCanProfileOwnerChange_mainUser() {
         assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_RECORD_AUDIO, user));
+                UserManager.DISALLOW_RECORD_AUDIO, true));
         assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_WALLPAPER, user));
+                UserManager.DISALLOW_WALLPAPER, true));
         assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_USER_SWITCH, user));
+                UserManager.DISALLOW_USER_SWITCH, true));
         assertTrue(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_ADD_USER, user));
+                UserManager.DISALLOW_ADD_USER, true));
         assertTrue(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_ADJUST_VOLUME, user));
+                UserManager.DISALLOW_ADJUST_VOLUME, true));
+    }
 
-        user = 10;
+    public void testCanProfileOwnerChange_notMainUser() {
         assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_RECORD_AUDIO, user));
+                UserManager.DISALLOW_RECORD_AUDIO, false));
         assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_WALLPAPER, user));
+                UserManager.DISALLOW_WALLPAPER, false));
         assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_ADD_USER, user));
+                UserManager.DISALLOW_ADD_USER, false));
         assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_USER_SWITCH, user));
+                UserManager.DISALLOW_USER_SWITCH, false));
         assertTrue(UserRestrictionsUtils.canProfileOwnerChange(
-                UserManager.DISALLOW_ADJUST_VOLUME, user));
+                UserManager.DISALLOW_ADJUST_VOLUME, false));
     }
 
     public void testMoveRestriction() {
diff --git a/services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java b/services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java
index 6553ea9..454d3f3 100644
--- a/services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.power;
 
+import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST;
 import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION;
 import static android.os.PowerManager.LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN;
 
@@ -62,6 +63,8 @@
 import com.android.internal.util.test.BroadcastInterceptingContext;
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
+import com.android.server.PowerAllowlistInternal;
+import com.android.server.PowerAllowlistInternal.TempAllowlistChangeListener;
 import com.android.server.net.NetworkPolicyManagerInternal;
 import com.android.server.power.LowPowerStandbyController.DeviceConfigWrapper;
 import com.android.server.testutils.OffsettableClock;
@@ -117,6 +120,8 @@
     private PowerManagerInternal mPowerManagerInternalMock;
     @Mock
     private NetworkPolicyManagerInternal mNetworkPolicyManagerInternalMock;
+    @Mock
+    private PowerAllowlistInternal mPowerAllowlistInternalMock;
 
     @Before
     public void setUp() throws Exception {
@@ -130,6 +135,7 @@
         when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
         addLocalServiceMock(PowerManagerInternal.class, mPowerManagerInternalMock);
         addLocalServiceMock(NetworkPolicyManagerInternal.class, mNetworkPolicyManagerInternalMock);
+        addLocalServiceMock(PowerAllowlistInternal.class, mPowerAllowlistInternalMock);
 
         when(mIPowerManagerMock.isInteractive()).thenReturn(true);
 
@@ -169,6 +175,7 @@
         LocalServices.removeServiceForTest(PowerManagerInternal.class);
         LocalServices.removeServiceForTest(LowPowerStandbyControllerInternal.class);
         LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
+        LocalServices.removeServiceForTest(PowerAllowlistInternal.class);
         mTestPolicyFile.delete();
     }
 
@@ -614,7 +621,7 @@
 
         InOrder inOrder = inOrder(mPowerManagerInternalMock);
 
-        inOrder.verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[] {
+        inOrder.verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{
                 UserHandle.getUid(USER_ID_1, TEST_PKG1_APP_ID),
                 UserHandle.getUid(USER_ID_2, TEST_PKG1_APP_ID),
         });
@@ -626,7 +633,7 @@
         mContextSpy.sendBroadcast(intent);
         mTestLooper.dispatchAll();
 
-        inOrder.verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[] {
+        inOrder.verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{
                 UserHandle.getUid(USER_ID_1, TEST_PKG1_APP_ID)
         });
         inOrder.verifyNoMoreInteractions();
@@ -663,6 +670,39 @@
         assertFalse(mController.isPackageExempt(TEST_PKG1_APP_ID));
     }
 
+    @Test
+    public void testAllowReason_tempPowerSaveAllowlist() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mController.setPolicy(policyWithAllowedReasons(
+                LOW_POWER_STANDBY_ALLOWED_REASON_TEMP_POWER_SAVE_ALLOWLIST));
+        mTestLooper.dispatchAll();
+
+        ArgumentCaptor<TempAllowlistChangeListener> tempAllowlistChangeListenerArgumentCaptor =
+                ArgumentCaptor.forClass(TempAllowlistChangeListener.class);
+        verify(mPowerAllowlistInternalMock).registerTempAllowlistChangeListener(
+                tempAllowlistChangeListenerArgumentCaptor.capture());
+        TempAllowlistChangeListener tempAllowlistChangeListener =
+                tempAllowlistChangeListenerArgumentCaptor.getValue();
+
+        tempAllowlistChangeListener.onAppAdded(TEST_PKG1_APP_ID);
+        mTestLooper.dispatchAll();
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{TEST_PKG1_APP_ID});
+
+        tempAllowlistChangeListener.onAppAdded(TEST_PKG2_APP_ID);
+        mTestLooper.dispatchAll();
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(
+                new int[]{TEST_PKG1_APP_ID, TEST_PKG2_APP_ID});
+
+        tempAllowlistChangeListener.onAppRemoved(TEST_PKG1_APP_ID);
+        mTestLooper.dispatchAll();
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{TEST_PKG2_APP_ID});
+
+        mController.setPolicy(EMPTY_POLICY);
+        mTestLooper.dispatchAll();
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[0]);
+    }
+
     private void setInteractive() throws Exception {
         when(mIPowerManagerMock.isInteractive()).thenReturn(true);
         mContextSpy.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON));
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityInterceptorCallbackTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityInterceptorCallbackTest.java
new file mode 100644
index 0000000..ff0591b
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityInterceptorCallbackTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.server.wm;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ResolveInfo;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.MediumTest;
+
+import org.junit.Test;
+
+@Presubmit
+@MediumTest
+public class ActivityInterceptorCallbackTest {
+
+    @Test
+    public void testBuildActivityInterceptorCallback() {
+        int callingUid = 10;
+        int callingPid = 100;
+        int realCallingUid = 20;
+        int realCallingPid = 200;
+        int userId = 1;
+        Intent intent = new Intent();
+        ResolveInfo resolveInfo = new ResolveInfo();
+        ActivityInfo activityInfo = new ActivityInfo();
+        String resolveType = "resolveType";
+        String callingPackage = "callingPackage";
+        String callingFeatureId = "callingFeatureId";
+        ActivityOptions activityOptions = ActivityOptions.makeBasic();
+        Runnable clearOptionsAnimation = () -> {};
+
+        ActivityInterceptorCallback.ActivityInterceptorInfo activityInterceptorInfo =
+                new ActivityInterceptorCallback.ActivityInterceptorInfo.Builder(callingUid,
+                        callingPid, realCallingUid, realCallingPid, userId, intent, resolveInfo,
+                        activityInfo)
+                .setResolvedType(resolveType)
+                .setCallingPackage(callingPackage)
+                .setCallingFeatureId(callingFeatureId)
+                .setCheckedOptions(activityOptions)
+                .setClearOptionsAnimationRunnable(clearOptionsAnimation)
+                .build();
+
+        assertThat(activityInterceptorInfo.getCallingUid()).isEqualTo(callingUid);
+        assertThat(activityInterceptorInfo.getCallingPid()).isEqualTo(callingPid);
+        assertThat(activityInterceptorInfo.getRealCallingUid()).isEqualTo(realCallingUid);
+        assertThat(activityInterceptorInfo.getRealCallingPid()).isEqualTo(realCallingPid);
+        assertThat(activityInterceptorInfo.getUserId()).isEqualTo(userId);
+        assertThat(activityInterceptorInfo.getIntent()).isEqualTo(intent);
+        assertThat(activityInterceptorInfo.getResolveInfo()).isEqualTo(resolveInfo);
+        assertThat(activityInterceptorInfo.getActivityInfo()).isEqualTo(activityInfo);
+        assertThat(activityInterceptorInfo.getResolvedType()).isEqualTo(resolveType);
+        assertThat(activityInterceptorInfo.getCallingPackage()).isEqualTo(callingPackage);
+        assertThat(activityInterceptorInfo.getCallingFeatureId()).isEqualTo(callingFeatureId);
+        assertThat(activityInterceptorInfo.getCheckedOptions()).isEqualTo(activityOptions);
+        assertThat(activityInterceptorInfo.getClearOptionsAnimationRunnable())
+                .isEqualTo(clearOptionsAnimation);
+    }
+
+    @Test
+    public void testActivityInterceptResult() {
+        Intent intent = new Intent();
+        ActivityOptions activityOptions = ActivityOptions.makeBasic();
+        boolean isActivityResolved = true;
+
+        ActivityInterceptorCallback.ActivityInterceptResult result =
+                new ActivityInterceptorCallback.ActivityInterceptResult(intent, activityOptions);
+        assertThat(result.getIntent()).isEqualTo(intent);
+        assertThat(result.getActivityOptions()).isEqualTo(activityOptions);
+        assertThat(result.isActivityResolved()).isFalse();
+
+        result = new ActivityInterceptorCallback.ActivityInterceptResult(
+                intent, activityOptions, isActivityResolved);
+        assertThat(result.getIntent()).isEqualTo(intent);
+        assertThat(result.getActivityOptions()).isEqualTo(activityOptions);
+        assertThat(result.isActivityResolved()).isTrue();
+    }
+}
diff --git a/telephony/java/android/telephony/satellite/ISatelliteCapabilitiesConsumer.aidl b/telephony/java/android/telephony/satellite/ISatelliteCapabilitiesConsumer.aidl
deleted file mode 100644
index f3ae245..0000000
--- a/telephony/java/android/telephony/satellite/ISatelliteCapabilitiesConsumer.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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 android.telephony.satellite;
-
-import android.telephony.satellite.SatelliteCapabilities;
-
-/**
- * Consumer for a SatelliteCapabilities result from the satellite service.
- * @hide
- */
-oneway interface ISatelliteCapabilitiesConsumer {
-    void accept(in SatelliteCapabilities result);
-}
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index a818b63..129d4ca 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -26,15 +26,15 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.ICancellationSignal;
+import android.os.OutcomeReceiver;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
-import android.telephony.satellite.stub.SatelliteImplBase;
 
-import com.android.internal.telephony.IBooleanConsumer;
-import com.android.internal.telephony.IIntArrayConsumer;
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.ITelephony;
 import com.android.telephony.Rlog;
@@ -72,16 +72,6 @@
     }
 
     /**
-     * Create a new SatelliteManager associated with the given subscription ID.
-     *
-     * @param subId The subscription ID to create the SatelliteManager with.
-     * @return A SatelliteManager that uses the given subscription ID for all calls.
-     */
-    @NonNull public SatelliteManager createForSubscriptionId(int subId) {
-        return new SatelliteManager(mContext, subId);
-    }
-
-    /**
      * Create an instance of the SatelliteManager associated with a particular subscription.
      *
      * @param context The context the SatelliteManager belongs to.
@@ -93,6 +83,67 @@
     }
 
     /**
+     * Exception from the satellite service containing the {@link SatelliteError} error code.
+     */
+    public static class SatelliteException extends Exception {
+        @SatelliteError private final int mErrorCode;
+
+        /**
+         * Create a SatelliteException with a given error code.
+         *
+         * @param errorCode The {@link SatelliteError}.
+         */
+        public SatelliteException(@SatelliteError int errorCode) {
+            mErrorCode = errorCode;
+        }
+
+        /**
+         * Get the error code returned from the satellite service.
+         *
+         * @return The {@link SatelliteError}.
+         */
+        @SatelliteError public int getErrorCode() {
+            return mErrorCode;
+        }
+    }
+
+    /**
+     * Bundle key to get the response from
+     * {@link #requestIsSatelliteEnabled(Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_SATELLITE_ENABLED = "satellite_enabled";
+
+    /**
+     * Bundle key to get the response from
+     * {@link #requestIsSatelliteSupported(Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_SATELLITE_SUPPORTED = "satellite_supported";
+
+    /**
+     * Bundle key to get the response from
+     * {@link #requestSatelliteCapabilities(Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_SATELLITE_CAPABILITIES = "satellite_capabilities";
+
+    /**
+     * Bundle key to get the response from
+     * {@link #requestMaxCharactersPerSatelliteTextMessage(Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_MAX_CHARACTERS_PER_SATELLITE_TEXT =
+            "max_characters_per_satellite_text";
+
+    /**
+     * Bundle key to get the response from
+     * {@link #requestIsSatelliteProvisioned(Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_SATELLITE_PROVISIONED = "satellite_provisioned";
+
+    /**
      * The request was successfully processed.
      */
     public static final int SATELLITE_ERROR_NONE = 0;
@@ -133,8 +184,8 @@
      */
     public static final int SATELLITE_INVALID_ARGUMENTS = 8;
     /**
-     * Telephony framework failed to send a request to the vendor service or the satellite
-     * modem due to internal error.
+     * Telephony framework failed to send a request or receive a response from the vendor service
+     * or satellite modem due to internal error.
      */
     public static final int SATELLITE_REQUEST_FAILED = 9;
     /**
@@ -211,158 +262,201 @@
     public @interface SatelliteError {}
 
     /**
-     * Power on or off the satellite modem.
+     * Enable or disable the satellite modem. If the satellite modem is enabled, this will also
+     * disable the cellular modem, and if the satellite modem is disabled, this will also re-enable
+     * the cellular modem.
      *
-     * @param powerOn {@code true} to power on the satellite modem and {@code false} to power off.
+     * @param enable {@code true} to enable the satellite modem and {@code false} to disable.
+     * @param executor The executor on which the error code listener will be called.
+     * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
-     *
-     * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError public int setSatellitePower(boolean powerOn) {
+    public void setSatelliteEnabled(boolean enable, @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<Integer> errorCodeListener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(errorCodeListener);
+
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.setSatellitePower(mSubId, powerOn);
+                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        executor.execute(() -> Binder.withCleanCallingIdentity(
+                                () -> errorCodeListener.accept(result)));
+                    }
+                };
+                telephony.setSatelliteEnabled(mSubId, enable, errorCallback);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            Rlog.e(TAG, "setSatellitePower RemoteException", ex);
+            Rlog.e(TAG, "setSatelliteEnabled RemoteException: ", ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
-     * Check whether the satellite modem is powered on.
+     * Request to get whether the satellite modem is enabled.
      *
-     * @param executor The executor on which the result listener will be called.
-     * @param resultListener Listener with the result if the operation is successful.
-     *                       If this method returns {@link #SATELLITE_ERROR_NONE}, the result
-     *                       listener will return {@code true} if the satellite modem is powered on
-     *                       and {@code false} otherwise.
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback object to which the result will be delivered.
+     *                 If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+     *                 will return a {@code boolean} with value {@code true} if the satellite modem
+     *                 is powered on and {@code false} otherwise.
+     *                 If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+     *                 will return a {@link SatelliteException} with the {@link SatelliteError}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
-     *
-     * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError public int isSatellitePowerOn(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<Boolean> resultListener) {
+    public void requestIsSatelliteEnabled(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
         Objects.requireNonNull(executor);
-        Objects.requireNonNull(resultListener);
+        Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                IBooleanConsumer internalCallback = new IBooleanConsumer.Stub() {
+                ResultReceiver receiver = new ResultReceiver(null) {
                     @Override
-                    public void accept(boolean result) {
-                        executor.execute(() -> Binder.withCleanCallingIdentity(
-                                () -> resultListener.accept(result)));
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_ERROR_NONE) {
+                            if (resultData.containsKey(KEY_SATELLITE_ENABLED)) {
+                                boolean isSatelliteEnabled =
+                                        resultData.getBoolean(KEY_SATELLITE_ENABLED);
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(isSatelliteEnabled)));
+                            } else {
+                                loge("KEY_SATELLITE_ENABLED does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(
+                                                new SatelliteException(SATELLITE_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
                     }
                 };
-
-                return telephony.isSatellitePowerOn(mSubId, internalCallback);
+                telephony.requestIsSatelliteEnabled(mSubId, receiver);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("isSatellitePowerOn() RemoteException:" + ex);
+            loge("requestIsSatelliteEnabled() RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
-     * Check whether the satellite service is supported on the device.
+     * Request to get whether the satellite service is supported on the device.
      *
-     * @param executor The executor on which the result listener will be called.
-     * @param resultListener Listener with the result if the operation is successful.
-     *                       If this method returns {@link #SATELLITE_ERROR_NONE}, the result
-     *                       listener will return {@code true} if the satellite service is supported
-     *                       and {@code false} otherwise.
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback object to which the result will be delivered.
+     *                 If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+     *                 will return a {@code boolean} with value {@code true} if the satellite
+     *                 service is supported on the device and {@code false} otherwise.
+     *                 If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+     *                 will return a {@link SatelliteException} with the {@link SatelliteError}.
      *
-     * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
-     *
-     * @return The result of the operation.
      */
-    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError public int isSatelliteSupported(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<Boolean> resultListener) {
+    public void requestIsSatelliteSupported(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
         Objects.requireNonNull(executor);
-        Objects.requireNonNull(resultListener);
+        Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                IBooleanConsumer internalCallback = new IBooleanConsumer.Stub() {
+                ResultReceiver receiver = new ResultReceiver(null) {
                     @Override
-                    public void accept(boolean result) {
-                        executor.execute(() -> Binder.withCleanCallingIdentity(
-                                () -> resultListener.accept(result)));
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_ERROR_NONE) {
+                            if (resultData.containsKey(KEY_SATELLITE_SUPPORTED)) {
+                                boolean isSatelliteSupported =
+                                        resultData.getBoolean(KEY_SATELLITE_SUPPORTED);
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(isSatelliteSupported)));
+                            } else {
+                                loge("KEY_SATELLITE_SUPPORTED does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(
+                                                new SatelliteException(SATELLITE_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
                     }
                 };
-
-                return telephony.isSatelliteSupported(mSubId, internalCallback);
+                telephony.requestIsSatelliteSupported(mSubId, receiver);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("isSatelliteSupported() RemoteException:" + ex);
+            loge("requestIsSatelliteSupported() RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
-     * Get the {@link SatelliteCapabilities} with all capabilities of the satellite service.
+     * Request to get the {@link SatelliteCapabilities} of the satellite service.
      *
-     * @param executor The executor on which the result listener will be called.
-     * @param resultListener Listener with the result if the operation is successful.
-     *                       If this method returns {@link #SATELLITE_ERROR_NONE}, the result
-     *                       listener will return the current {@link SatelliteCapabilities}.
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback object to which the result will be delivered.
+     *                 If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+     *                 will return the {@link SatelliteCapabilities} of the satellite service.
+     *                 If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+     *                 will return a {@link SatelliteException} with the {@link SatelliteError}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
-     *
-     * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError public int getSatelliteCapabilities(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<SatelliteCapabilities> resultListener) {
+    public void requestSatelliteCapabilities(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<SatelliteCapabilities, SatelliteException> callback) {
         Objects.requireNonNull(executor);
-        Objects.requireNonNull(resultListener);
+        Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                ISatelliteCapabilitiesConsumer internalCallback =
-                        new ISatelliteCapabilitiesConsumer.Stub() {
+                ResultReceiver receiver = new ResultReceiver(null) {
                     @Override
-                    public void accept(SatelliteCapabilities result) {
-                        executor.execute(() -> Binder.withCleanCallingIdentity(
-                                () -> resultListener.accept(result)));
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_ERROR_NONE) {
+                            if (resultData.containsKey(KEY_SATELLITE_CAPABILITIES)) {
+                                SatelliteCapabilities capabilities =
+                                        resultData.getParcelable(KEY_SATELLITE_CAPABILITIES,
+                                                SatelliteCapabilities.class);
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(capabilities)));
+                            } else {
+                                loge("KEY_SATELLITE_CAPABILITIES does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(
+                                                new SatelliteException(SATELLITE_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
                     }
                 };
-
-                return telephony.getSatelliteCapabilities(mSubId, internalCallback);
+                telephony.requestSatelliteCapabilities(mSubId, receiver);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("getSatelliteCapabilities() RemoteException:" + ex);
+            loge("requestSatelliteCapabilities() RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
@@ -403,28 +497,35 @@
      * Satellite position updates are started only on {@link #SATELLITE_ERROR_NONE}.
      * All other results indicate that this operation failed.
      *
-     * @param executor The executor on which the callback will be called.
+     * @param executor The executor on which the callback and error code listener will be called.
+     * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
      * @param callback The callback to notify of changes in satellite position. This
      *                 SatelliteCallback should implement the interface
      *                 {@link SatelliteCallback.SatellitePositionUpdateListener}.
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
-     *
-     * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError
-    public int startSatellitePositionUpdates(
-            @NonNull Executor executor, @NonNull SatelliteCallback callback) {
+    public void startSatellitePositionUpdates(@NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<Integer> errorCodeListener, @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(executor);
+        Objects.requireNonNull(errorCodeListener);
         Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
                 callback.init(executor);
-                return telephony.startSatellitePositionUpdates(mSubId, callback.getCallbackStub());
+                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        executor.execute(() -> Binder.withCleanCallingIdentity(
+                                () -> errorCodeListener.accept(result)));
+                    }
+                };
+                telephony.startSatellitePositionUpdates(mSubId, errorCallback,
+                        callback.getCallbackStub());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -432,7 +533,6 @@
             loge("startSatellitePositionUpdates RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
@@ -441,25 +541,35 @@
      * Satellite position updates are stopped only on {@link #SATELLITE_ERROR_NONE}.
      * All other results indicate that this operation failed.
      *
-     * @param callback The callback that was passed in {@link
-     *                 #startSatellitePositionUpdates(Executor, SatelliteCallback)}.
+     * @param callback The callback that was passed to
+     *       {@link #startSatellitePositionUpdates(Executor, Consumer, SatelliteCallback)}.
+     * @param executor The executor on which the error code listener will be called.
+     * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalArgumentException if the callback is invalid.
      * @throws IllegalStateException if the Telephony process is not currently available.
-     *
-     * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError
-    public int stopSatellitePositionUpdates(
-            @NonNull SatelliteCallback callback) {
+    public void stopSatellitePositionUpdates(@NonNull SatelliteCallback callback,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<Integer> errorCodeListener) {
         Objects.requireNonNull(callback);
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(errorCodeListener);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.stopSatellitePositionUpdates(mSubId, callback.getCallbackStub());
+                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        executor.execute(() -> Binder.withCleanCallingIdentity(
+                                () -> errorCodeListener.accept(result)));
+                    }
+                };
+                telephony.stopSatellitePositionUpdates(mSubId, errorCallback,
+                        callback.getCallbackStub());
                 // TODO: Notify SmsHandler that pointing UI stopped
             } else {
                 throw new IllegalStateException("telephony service is null.");
@@ -468,89 +578,97 @@
             loge("stopSatellitePositionUpdates RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
-     * Get maximum number of characters per text message on satellite.
-     * @param executor - The executor on which the result listener will be called.
-     * @param resultListener - Listener that will be called when the operation is successful.
-     *                       If this method returns {@link #SATELLITE_ERROR_NONE}, listener
-     *                       will be called with maximum characters limit.
+     * Request to get the maximum number of characters per text message on satellite.
+     *
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback object to which the result will be delivered.
+     *                 If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+     *                 will return the maximum number of characters per text message on satellite.
+     *                 If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
-     *
-     * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError
-    public int getMaxCharactersPerSatelliteTextMessage(@NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<Integer> resultListener) {
+    public void requestMaxCharactersPerSatelliteTextMessage(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<Integer, SatelliteException> callback) {
         Objects.requireNonNull(executor);
-        Objects.requireNonNull(resultListener);
+        Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
+                ResultReceiver receiver = new ResultReceiver(null) {
                     @Override
-                    public void accept(int result) {
-                        executor.execute(() -> Binder.withCleanCallingIdentity(
-                                () -> resultListener.accept(result)));
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_ERROR_NONE) {
+                            if (resultData.containsKey(KEY_MAX_CHARACTERS_PER_SATELLITE_TEXT)) {
+                                int maxCharacters =
+                                        resultData.getInt(KEY_MAX_CHARACTERS_PER_SATELLITE_TEXT);
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(maxCharacters)));
+                            } else {
+                                loge("KEY_MAX_CHARACTERS_PER_SATELLITE_TEXT does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(
+                                                new SatelliteException(SATELLITE_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
                     }
                 };
-
-                return telephony.getMaxCharactersPerSatelliteTextMessage(mSubId, internalCallback);
+                telephony.requestMaxCharactersPerSatelliteTextMessage(mSubId, receiver);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("getMaxCharactersPerSatelliteTextMessage() RemoteException:" + ex);
+            loge("requestMaxCharactersPerSatelliteTextMessage() RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
 
     /**
-     * Register the subscription with a satellite provider. This is needed if the provider allows
-     * dynamic registration.
+     * Provision the device with a satellite provider.
+     * This is needed if the provider allows dynamic registration.
      *
-     * @param features List of features to be provisioned.
-     * @param executor The optional executor to run callbacks on.
-     * @param callback The optional callback to get the error code of the request.
+     * @param token The security token of the device/subscription to be provisioned.
      * @param cancellationSignal The optional signal used by the caller to cancel the provision
      *                           request. Even when the cancellation is signaled, Telephony will
      *                           still trigger the callback to return the result of this request.
+     * @param executor The executor on which the error code listener will be called.
+     * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
+     *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    public void provisionSatelliteService(
-            @NonNull @SatelliteImplBase.Feature int[] features,
-            @Nullable @CallbackExecutor Executor executor,
-            @SatelliteError @Nullable Consumer<Integer> callback,
-            @Nullable CancellationSignal cancellationSignal) {
-        Objects.requireNonNull(features);
+    public void provisionSatelliteService(@NonNull String token,
+            @Nullable CancellationSignal cancellationSignal,
+            @NonNull @CallbackExecutor Executor executor,
+            @SatelliteError @NonNull Consumer<Integer> errorCodeListener) {
+        Objects.requireNonNull(token);
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(errorCodeListener);
 
         ICancellationSignal cancelRemote = null;
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                IIntegerConsumer callbackStub = new IIntegerConsumer.Stub() {
+                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
                     @Override
                     public void accept(int result) {
-                        if (executor == null || callback == null) {
-                            logd("provisionSatelliteService: executor and/or callback is null");
-                            return;
-                        }
-                        Binder.withCleanCallingIdentity(() -> {
-                            executor.execute(() -> callback.accept(result));
-                        });
+                        executor.execute(() -> Binder.withCleanCallingIdentity(
+                                () -> errorCodeListener.accept(result)));
                     }
                 };
-                cancelRemote = telephony.provisionSatelliteService(mSubId, features, callbackStub);
+                cancelRemote = telephony.provisionSatelliteService(mSubId, token, errorCallback);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -566,27 +684,36 @@
     /**
      * Register for the satellite provision state change.
      *
-     * @param executor - The executor on which the callback will be called.
+     * @param executor The executor on which the callback and error code listener will be called.
+     * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
      * @param callback The callback to handle the satellite provision state changed event. This
      *                 SatelliteCallback should implement the interface
      *                 {@link SatelliteCallback.SatelliteProvisionStateListener}.
-     * @return The error code of the request.
+     *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError
-    public int registerForSatelliteProvisionStateChanged(
-            @NonNull Executor executor, @NonNull SatelliteCallback callback) {
+    public void registerForSatelliteProvisionStateChanged(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<Integer> errorCodeListener, @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(executor);
+        Objects.requireNonNull(errorCodeListener);
         Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
                 callback.init(executor);
-                return telephony.registerForSatelliteProvisionStateChanged(
-                        mSubId, callback.getCallbackStub());
+                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        executor.execute(() -> Binder.withCleanCallingIdentity(
+                                () -> errorCodeListener.accept(result)));
+                    }
+                };
+                telephony.registerForSatelliteProvisionStateChanged(
+                        mSubId, errorCallback, callback.getCallbackStub());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -594,33 +721,46 @@
             loge("registerForSatelliteProvisionStateChanged RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
      * Unregister for the satellite provision state change.
      *
      * @param callback The callback that was passed to
-     * {@link #registerForSatelliteProvisionStateChanged(Executor, SatelliteCallback)}
-     * @return The error code of the request.
+     * {@link #registerForSatelliteProvisionStateChanged(Executor, Consumer, SatelliteCallback)}.
+     * @param executor The executor on which the error code listener will be called.
+     * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
+     *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError
-    public int unregisterForSatelliteProvisionStateChanged(@NonNull SatelliteCallback callback) {
+    public void unregisterForSatelliteProvisionStateChanged(@NonNull SatelliteCallback callback,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<Integer> errorCodeListener) {
         Objects.requireNonNull(callback);
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(errorCodeListener);
 
         if (callback.getCallbackStub() == null) {
             loge("unregisterForSatelliteProvisionStateChanged: callbackStub is null");
-            return SATELLITE_INVALID_ARGUMENTS;
+            executor.execute(() -> Binder.withCleanCallingIdentity(
+                    () -> errorCodeListener.accept(SATELLITE_INVALID_ARGUMENTS)));
+            return;
         }
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.unregisterForSatelliteProvisionStateChanged(
-                        mSubId, callback.getCallbackStub());
+                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        executor.execute(() -> Binder.withCleanCallingIdentity(
+                                () -> errorCodeListener.accept(result)));
+                    }
+                };
+                telephony.unregisterForSatelliteProvisionStateChanged(mSubId, errorCallback,
+                        callback.getCallbackStub());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -628,46 +768,60 @@
             loge("unregisterForSatelliteProvisionStateChanged RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
-     * Get the list of provisioned satellite features.
+     * Request to get whether this device is provisioned with a satellite provider.
      *
-     * @param executor The executor to run callbacks on.
-     * @param resultListener The callback to get the list of provisioned features when the request
-     *                       returns success result.
-     * @return The error code of the request.
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback object to which the result will be delivered.
+     *                 If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+     *                 will return a {@code boolean} with value {@code true} if the device is
+     *                 provisioned with a satellite provider and {@code false} otherwise.
+     *                 If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+     *                 will return a {@link SatelliteException} with the {@link SatelliteError}.
+     *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError
-    public int getProvisionedSatelliteFeatures(
-            @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<int[]> resultListener) {
-        Objects.requireNonNull(resultListener);
+    public void requestIsSatelliteProvisioned(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
         Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                IIntArrayConsumer callbackStub = new IIntArrayConsumer.Stub() {
+                ResultReceiver receiver = new ResultReceiver(null) {
                     @Override
-                    public void accept(int[] result) {
-                        Binder.withCleanCallingIdentity(() -> {
-                            executor.execute(() -> resultListener.accept(result));
-                        });
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_ERROR_NONE) {
+                            if (resultData.containsKey(KEY_SATELLITE_PROVISIONED)) {
+                                boolean isSatelliteProvisioned =
+                                        resultData.getBoolean(KEY_SATELLITE_PROVISIONED);
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(isSatelliteProvisioned)));
+                            } else {
+                                loge("KEY_SATELLITE_PROVISIONED does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(
+                                                new SatelliteException(SATELLITE_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
                     }
                 };
-                return telephony.getProvisionedSatelliteFeatures(mSubId, callbackStub);
+                telephony.requestIsSatelliteProvisioned(mSubId, receiver);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("getProvisionedSatelliteFeatures() RemoteException:" + ex);
+            loge("requestIsSatelliteProvisioned() RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_REQUEST_FAILED;
     }
 
     private static ITelephony getITelephony() {
diff --git a/telephony/java/com/android/internal/telephony/IIntArrayConsumer.aidl b/telephony/java/com/android/internal/telephony/IIntArrayConsumer.aidl
deleted file mode 100644
index c208755..0000000
--- a/telephony/java/com/android/internal/telephony/IIntArrayConsumer.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.internal.telephony;
-
-// Copies consumer pattern for an operation that requires an int array result from another
-// process to finish.
-oneway interface IIntArrayConsumer {
-    void accept(in int[] result);
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index baf45cd..07deead 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -68,7 +68,6 @@
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.telephony.ims.aidl.IRcsConfigCallback;
 import android.telephony.satellite.ISatelliteStateListener;
-import android.telephony.satellite.ISatelliteCapabilitiesConsumer;
 import android.telephony.satellite.SatelliteCapabilities;
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.telephony.CellNetworkScanResult;
@@ -76,7 +75,6 @@
 import com.android.internal.telephony.ICallForwardingInfoCallback;
 import com.android.internal.telephony.IccLogicalChannelRequest;
 import com.android.internal.telephony.IImsStateCallback;
-import com.android.internal.telephony.IIntArrayConsumer;
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.OperatorInfo;
@@ -2704,74 +2702,129 @@
     void getCarrierRestrictionStatus(IIntegerConsumer internalCallback, String packageName);
 
     /**
-     * Power on or off the satellite modem.
+     * Enable or disable the satellite modem.
+     *
+     * @param subId The subId of the subscription to enable or disable the satellite modem for.
+     * @param enable True to enable the satellite modem and false to disable.
+     * @param callback The callback to get the error code of the request.
      */
-    int setSatellitePower(int subId, boolean powerOn);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void setSatelliteEnabled(int subId, boolean enable, in IIntegerConsumer callback);
 
     /**
-     * Check whether the satellite modem is powered on.
+     * Request to get whether the satellite modem is enabled.
+     *
+     * @param subId The subId of the subscription to request whether satellite is enabled for.
+     * @param receiver Result receiver to get the error code of the request and whether the
+     *                 satellite modem is enabled.
      */
-    int isSatellitePowerOn(int subId, IBooleanConsumer internalCallback);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void requestIsSatelliteEnabled(int subId, in ResultReceiver receiver);
 
     /**
-     * Check whether the satellite service is supported on the device.
+     * Request to get whether the satellite service is supported on the device.
+     *
+     * @param subId The subId of the subscription to check whether satellite is supported for.
+     * @param receiver Result receiver to get the error code of the request and whether the
+     *                 satellite service is supported on the device.
      */
-    int isSatelliteSupported(int subId, IBooleanConsumer internalCallback);
+    void requestIsSatelliteSupported(int subId, in ResultReceiver receiver);
 
     /**
-     * Get the capabilities of the satellite service.
+     * Request to get the capabilities of the satellite service.
+     *
+     * @param subId The subId of the subscription to get the capabilities for.
+     * @param receiver Result receiver to get the error code of the request and the requested
+     *                 capabilities of the satellite service.
      */
-    int getSatelliteCapabilities(int subId, ISatelliteCapabilitiesConsumer internalCallback);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void requestSatelliteCapabilities(int subId, in ResultReceiver receiver);
 
     /**
      * Start receiving satellite pointing updates.
+     *
+     * @param subId The subId of the subscription to stop satellite position updates for.
+     * @param errorCallback The callback to get the error code of the request.
+     * @param callback The callback to handle position updates.
      */
-    int startSatellitePositionUpdates(int subId, in ISatelliteStateListener callback);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void startSatellitePositionUpdates(int subId, in IIntegerConsumer errorCallback,
+            in ISatelliteStateListener callback);
 
     /**
      * Stop receiving satellite pointing updates.
+     *
+     * @param subId The subId of the subscritpion to stop satellite position updates for.
+     * @param errorCallback The callback to get the error code of the request.
+     * @param callback The callback that was passed to startSatellitePositionUpdates.
      */
-    int stopSatellitePositionUpdates(int subId, ISatelliteStateListener callback);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void stopSatellitePositionUpdates(int subId, in IIntegerConsumer errorCallback,
+            in ISatelliteStateListener callback);
 
     /**
-     * Get maximum number of characters per text message on satellite.
+     * Request to get the maximum number of characters per text message on satellite.
+     *
+     * @param subId The subId to get the maximum number of characters for.
+     * @param receiver Result receiver to get the error code of the request and the requested
+     *                 maximum number of characters per text message on satellite.
      */
-    int getMaxCharactersPerSatelliteTextMessage(int subId, IIntegerConsumer internalCallback);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void requestMaxCharactersPerSatelliteTextMessage(int subId, in ResultReceiver receiver);
 
     /**
      * Register the subscription with a satellite provider.
      * This is needed to register the subscription if the provider allows dynamic registration.
      *
      * @param subId The subId of the subscription to be provisioned.
-     * @param features List of features to be provisioned.
+     * @param token The security token of the device/subscription to be provisioned.
      * @param callback The callback to get the error code of the request.
+     *
      * @return The signal transport used by callers to cancel the provision request.
      */
-    ICancellationSignal provisionSatelliteService(int subId, in int[] features,
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    ICancellationSignal provisionSatelliteService(int subId, in String token,
             in IIntegerConsumer callback);
 
     /**
      * Register for the satellite provision state change.
      *
-     * @param subId The subId of the subscription to be provisioned.
+     * @param subId The subId of the subscription to register for provision state changes for.
+     * @param errorCallback The callback to get the error code of the request.
      * @param callback The callback to handle the satellite provision state changed event.
      */
-    int registerForSatelliteProvisionStateChanged(int subId, ISatelliteStateListener callback);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void registerForSatelliteProvisionStateChanged(int subId,
+            in IIntegerConsumer errorCallback, in ISatelliteStateListener callback);
 
     /**
      * Unregister for the satellite provision state change.
      *
      * @param subId The subId of the subscription associated with the satellite service.
-     * @param callback The callback that was passed to
-     *                   registerForSatelliteProvisionStateChanged.
+     * @param errorCallback The callback to get the error code of the request.
+     * @param callback The callback that was passed to registerForSatelliteProvisionStateChanged.
      */
-    int unregisterForSatelliteProvisionStateChanged(int subId, ISatelliteStateListener callback);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void unregisterForSatelliteProvisionStateChanged(int subId,
+            in IIntegerConsumer errorCallback, in ISatelliteStateListener callback);
 
     /**
-     * Get the list of provisioned satellite features.
+     * Request to get whether the device is provisioned with a satellite provider.
      *
-     * @param subId The subId of the subscription to be provisioned.
-     * @param callback The callback to get the list of provisioned satellite features.
+     * @param subId The subId of the subscription to get whether the device is provisioned for.
+     * @param receiver Result receiver to get the error code of the request and whether the
+     *                 device is provisioned with a satellite provider.
      */
-    int getProvisionedSatelliteFeatures(int subId, IIntArrayConsumer callback);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void requestIsSatelliteProvisioned(int subId, in ResultReceiver receiver);
 }
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index aa337e5..0d6dc35 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -50,6 +50,7 @@
     ],
     target: {
         windows: {
+            compile_multilib: "64",
             enabled: true,
             cflags: ["-Wno-maybe-uninitialized"],
             ldflags: ["-static"],
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
index a40049b..10ef066 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
@@ -101,13 +101,13 @@
             @Override
             public void registerCallback(ISharedConnectivityCallback callback) {
                 checkPermissions();
-                mHandler.post(() -> registerCallback(callback));
+                mHandler.post(() -> onRegisterCallback(callback));
             }
 
             @Override
             public void unregisterCallback(ISharedConnectivityCallback callback) {
                 checkPermissions();
-                mHandler.post(() -> unregisterCallback(callback));
+                mHandler.post(() -> onUnregisterCallback(callback));
             }
 
             @Override
@@ -147,7 +147,7 @@
         };
     }
 
-    private void registerCallback(ISharedConnectivityCallback callback) {
+    private void onRegisterCallback(ISharedConnectivityCallback callback) {
         // Listener gets triggered on first register using cashed data
         if (!notifyTetherNetworkUpdate(callback) || !notifyKnownNetworkUpdate(callback)
                 || !notifySettingsStateUpdate(callback)
@@ -167,7 +167,7 @@
         }
     }
 
-    private void unregisterCallback(ISharedConnectivityCallback callback) {
+    private void onUnregisterCallback(ISharedConnectivityCallback callback) {
         DeathRecipient deathRecipient = mDeathRecipientMap.get(callback);
         if (deathRecipient != null) {
             callback.asBinder().unlinkToDeath(deathRecipient, 0);