Merge "Add derek to the WEAR_OWNERS file" into main
diff --git a/core/api/current.txt b/core/api/current.txt
index 0c11811..4af2c52 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1893,6 +1893,7 @@
     field public static final int windowFullscreen = 16843277; // 0x101020d
     field public static final int windowHideAnimation = 16842935; // 0x10100b7
     field public static final int windowIsFloating = 16842839; // 0x1010057
+    field @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public static final int windowIsFrameRatePowerSavingsBalanced;
     field public static final int windowIsTranslucent = 16842840; // 0x1010058
     field public static final int windowLayoutAffinity = 16844313; // 0x1010619
     field public static final int windowLayoutInDisplayCutoutMode = 16844166; // 0x1010586
@@ -4488,6 +4489,7 @@
     method @CallSuper public void onActionModeStarted(android.view.ActionMode);
     method public void onActivityReenter(int, android.content.Intent);
     method protected void onActivityResult(int, int, android.content.Intent);
+    method @FlaggedApi("android.security.content_uri_permission_apis") public void onActivityResult(int, int, @NonNull android.content.Intent, @NonNull android.app.ComponentCaller);
     method @Deprecated public void onAttachFragment(android.app.Fragment);
     method public void onAttachedToWindow();
     method @Deprecated public void onBackPressed();
@@ -18055,24 +18057,6 @@
     method public android.graphics.pdf.PdfDocument.PageInfo.Builder setContentRect(android.graphics.Rect);
   }
 
-  public final class PdfRenderer implements java.lang.AutoCloseable {
-    ctor public PdfRenderer(@NonNull android.os.ParcelFileDescriptor) throws java.io.IOException;
-    method public void close();
-    method public int getPageCount();
-    method public android.graphics.pdf.PdfRenderer.Page openPage(int);
-    method public boolean shouldScaleForPrinting();
-  }
-
-  public final class PdfRenderer.Page implements java.lang.AutoCloseable {
-    method public void close();
-    method public int getHeight();
-    method public int getIndex();
-    method public int getWidth();
-    method public void render(@NonNull android.graphics.Bitmap, @Nullable android.graphics.Rect, @Nullable android.graphics.Matrix, int);
-    field public static final int RENDER_MODE_FOR_DISPLAY = 1; // 0x1
-    field public static final int RENDER_MODE_FOR_PRINT = 2; // 0x2
-  }
-
 }
 
 package android.graphics.text {
@@ -18596,6 +18580,7 @@
 
   @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public final class OverlayProperties implements android.os.Parcelable {
     method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public int describeContents();
+    method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public boolean isCombinationSupported(int, int);
     method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public boolean isMixedColorSpacesSupported();
     method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public void writeToParcel(@NonNull android.os.Parcel, int);
     field @FlaggedApi("android.hardware.flags.overlayproperties_class_api") @NonNull public static final android.os.Parcelable.Creator<android.hardware.OverlayProperties> CREATOR;
@@ -19329,6 +19314,7 @@
   public abstract static class CameraExtensionSession.ExtensionCaptureCallback {
     ctor public CameraExtensionSession.ExtensionCaptureCallback();
     method public void onCaptureFailed(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest);
+    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureFailed(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest, int);
     method public void onCaptureProcessProgressed(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest, @IntRange(from=0, to=100) int);
     method public void onCaptureProcessStarted(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest);
     method public void onCaptureResultAvailable(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest, @NonNull android.hardware.camera2.TotalCaptureResult);
@@ -26097,7 +26083,6 @@
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.metrics.MediaItemInfo> CREATOR;
     field public static final long DATA_TYPE_AUDIO = 4L; // 0x4L
-    field public static final long DATA_TYPE_CUE_POINTS = 128L; // 0x80L
     field public static final long DATA_TYPE_DEPTH = 16L; // 0x10L
     field public static final long DATA_TYPE_GAIN_MAP = 32L; // 0x20L
     field public static final long DATA_TYPE_GAPLESS = 256L; // 0x100L
@@ -26106,6 +26091,7 @@
     field public static final long DATA_TYPE_IMAGE = 1L; // 0x1L
     field public static final long DATA_TYPE_METADATA = 8L; // 0x8L
     field public static final long DATA_TYPE_SPATIAL_AUDIO = 512L; // 0x200L
+    field public static final long DATA_TYPE_SPEED_SETTING_CUE_POINTS = 128L; // 0x80L
     field public static final long DATA_TYPE_VIDEO = 2L; // 0x2L
     field public static final int SOURCE_TYPE_CAMERA = 2; // 0x2
     field public static final int SOURCE_TYPE_EDITING_SESSION = 3; // 0x3
@@ -54098,6 +54084,7 @@
     method public abstract void invalidatePanelMenu(int);
     method public final boolean isActive();
     method public abstract boolean isFloating();
+    method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public boolean isFrameRatePowerSavingsBalanced();
     method public boolean isNavigationBarContrastEnforced();
     method public abstract boolean isShortcutKey(int, android.view.KeyEvent);
     method @Deprecated public boolean isStatusBarContrastEnforced();
@@ -54147,6 +54134,7 @@
     method public void setFlags(int, int);
     method public void setFormat(int);
     method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRateBoostOnTouchEnabled(boolean);
+    method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRatePowerSavingsBalanced(boolean);
     method public void setGravity(int);
     method @RequiresPermission(android.Manifest.permission.HIDE_OVERLAY_WINDOWS) public final void setHideOverlayWindows(boolean);
     method public void setIcon(@DrawableRes int);
@@ -54518,6 +54506,7 @@
     method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public boolean getFrameRateBoostOnTouchEnabled();
     method public final CharSequence getTitle();
     method public boolean isFitInsetsIgnoringVisibility();
+    method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public boolean isFrameRatePowerSavingsBalanced();
     method public boolean isHdrConversionEnabled();
     method public static boolean mayUseInputMethod(int);
     method public void setBlurBehindRadius(@IntRange(from=0) int);
@@ -54528,6 +54517,7 @@
     method public void setFitInsetsSides(int);
     method public void setFitInsetsTypes(int);
     method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRateBoostOnTouchEnabled(boolean);
+    method @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") public void setFrameRatePowerSavingsBalanced(boolean);
     method public void setHdrConversionEnabled(boolean);
     method public final void setTitle(CharSequence);
     method public void setWallpaperTouchEventsEnabled(boolean);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 15de42a..af5ea21 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4828,7 +4828,7 @@
 
   @FlaggedApi("com.android.internal.camera.flags.concert_mode") public static interface SessionProcessor.CaptureCallback {
     method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureCompleted(long, int, @NonNull android.hardware.camera2.CaptureResult);
-    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureFailed(int);
+    method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureFailed(int, int);
     method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureProcessStarted(int);
     method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureSequenceAborted(int);
     method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void onCaptureSequenceCompleted(int);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index fae9f83..251f823 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -858,11 +858,15 @@
      */
     private ComponentCaller mCaller;
     /**
-     * Caller associated with an Intent within {@link #onNewIntent}. Can be retrieved from
-     * {@link #getCurrentCaller}, or by overriding {@link #onNewIntent(Intent, ComponentCaller)} and
-     * getting the second argument.
+     * Caller associated with an Intent within {@link #onNewIntent} and {@link #onActivityResult}.
+     * Can be retrieved from either of these methods:
+     * - {@link #getCurrentCaller}
+     * - By overriding {@link #onNewIntent(Intent, ComponentCaller)} and getting the second argument
+     * - By overriding {@link #onActivityResult(int, int, Intent, ComponentCaller)} and getting the
+     * fourth argument
      *
-     * <p>The value of this field will be {@code null} outside of {@link #onNewIntent}.
+     * <p>The value of this field will be {@code null} outside of {@link #onNewIntent} and
+     * {@link #onActivityResult}.
      */
     private ComponentCaller mCurrentCaller;
 
@@ -7138,13 +7142,15 @@
 
     /**
      * Returns the ComponentCaller instance of the app that re-launched this activity with a new
-     * intent via {@link #onNewIntent}.
+     * intent via {@link #onNewIntent} or {@link #onActivityResult}.
      *
-     * <p>Note that this method only works within the {@link #onNewIntent} method. If you call this
-     * method outside {@link #onNewIntent}, it will throw an {@link IllegalStateException}.
+     * <p>Note that this method only works within the {@link #onNewIntent} and
+     * {@link #onActivityResult} methods. If you call this method outside {@link #onNewIntent} and
+     * {@link #onActivityResult}, it will throw an {@link IllegalStateException}.
      *
      * <p>You can also retrieve the caller if you override
-     * {@link #onNewIntent(Intent, ComponentCaller)}.
+     * {@link #onNewIntent(Intent, ComponentCaller)} or
+     * {@link #onActivityResult(int, int, Intent, ComponentCaller)}.
      *
      * <p>To keep the ComponentCaller instance for future use, call
      * {@link #setIntent(Intent, ComponentCaller)}, and use {@link #getCaller} to retrieve it.
@@ -7425,6 +7431,31 @@
     }
 
     /**
+     * Same as {@link #onActivityResult(int, int, Intent)}, but with an extra parameter for the
+     * ComponentCaller instance associated with the app that sent the result.
+     *
+     * <p>If you want to retrieve the caller without overriding this method, call
+     * {@link #getCurrentCaller} inside your existing {@link #onActivityResult(int, int, Intent)}.
+     *
+     * <p>Note that you should only override one {@link #onActivityResult} method.
+     *
+     * @param requestCode The integer request code originally supplied to
+     *                    startActivityForResult(), allowing you to identify who this
+     *                    result came from.
+     * @param resultCode The integer result code returned by the child activity
+     *                   through its setResult().
+     * @param data An Intent, which can return result data to the caller
+     *               (various data can be attached to Intent "extras").
+     * @param caller The {@link ComponentCaller} instance associated with the app that sent the
+     *               intent.
+     */
+    @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS)
+    public void onActivityResult(int requestCode, int resultCode, @NonNull Intent data,
+            @NonNull ComponentCaller caller) {
+        onActivityResult(requestCode, resultCode, data);
+    }
+
+    /**
      * Called when an activity you launched with an activity transition exposes this
      * Activity through a returning activity transition, giving you the resultCode
      * and any additional data from it. This method will only be called if the activity
@@ -9268,15 +9299,36 @@
         }
     }
 
+    void dispatchActivityResult(String who, int requestCode, int resultCode, Intent data,
+            ComponentCaller caller, String reason) {
+        internalDispatchActivityResult(who, requestCode, resultCode, data, caller, reason);
+    }
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     void dispatchActivityResult(String who, int requestCode, int resultCode, Intent data,
             String reason) {
+        if (android.security.Flags.contentUriPermissionApis()) {
+            internalDispatchActivityResult(who, requestCode, resultCode, data,
+                    new ComponentCaller(getActivityToken(), /* callerToken */ null), reason);
+        } else {
+            internalDispatchActivityResult(who, requestCode, resultCode, data, null, reason);
+        }
+    }
+
+    private void internalDispatchActivityResult(String who, int requestCode, int resultCode,
+            Intent data, ComponentCaller caller, String reason) {
         if (false) Log.v(
             TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode
             + ", resCode=" + resultCode + ", data=" + data);
         mFragments.noteStateNotSaved();
         if (who == null) {
-            onActivityResult(requestCode, resultCode, data);
+            if (android.security.Flags.contentUriPermissionApis()) {
+                mCurrentCaller = caller;
+                onActivityResult(requestCode, resultCode, data, caller);
+                mCurrentCaller = null;
+            } else {
+                onActivityResult(requestCode, resultCode, data);
+            }
         } else if (who.startsWith(REQUEST_PERMISSIONS_WHO_PREFIX)) {
             who = who.substring(REQUEST_PERMISSIONS_WHO_PREFIX.length());
             if (TextUtils.isEmpty(who)) {
diff --git a/core/java/android/app/ActivityGroup.java b/core/java/android/app/ActivityGroup.java
index cb06eea..21c67edc6 100644
--- a/core/java/android/app/ActivityGroup.java
+++ b/core/java/android/app/ActivityGroup.java
@@ -111,7 +111,7 @@
 
     @Override
     void dispatchActivityResult(String who, int requestCode, int resultCode,
-            Intent data, String reason) {
+            Intent data, ComponentCaller caller, String reason) {
         if (who != null) {
             Activity act = mLocalActivityManager.getActivity(who);
             /*
@@ -125,7 +125,7 @@
                 return;
             }
         }
-        super.dispatchActivityResult(who, requestCode, resultCode, data, reason);
+        super.dispatchActivityResult(who, requestCode, resultCode, data, caller, reason);
     }
 }
 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 00ccd04..926e297 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3758,7 +3758,7 @@
         if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
                 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
         final ArrayList<ResultInfo> list = new ArrayList<>();
-        list.add(new ResultInfo(id, requestCode, resultCode, data));
+        list.add(new ResultInfo(id, requestCode, resultCode, data, activityToken));
         final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread);
         final ActivityResultItem activityResultItem = ActivityResultItem.obtain(
                 activityToken, list);
@@ -5799,8 +5799,14 @@
                 }
                 if (DEBUG_RESULTS) Slog.v(TAG,
                         "Delivering result to activity " + r + " : " + ri);
-                r.activity.dispatchActivityResult(ri.mResultWho,
-                        ri.mRequestCode, ri.mResultCode, ri.mData, reason);
+                if (android.security.Flags.contentUriPermissionApis()) {
+                    ComponentCaller caller = new ComponentCaller(r.token, ri.mCallerToken);
+                    r.activity.dispatchActivityResult(ri.mResultWho,
+                            ri.mRequestCode, ri.mResultCode, ri.mData, caller, reason);
+                } else {
+                    r.activity.dispatchActivityResult(ri.mResultWho,
+                            ri.mRequestCode, ri.mResultCode, ri.mData, reason);
+                }
             } catch (Exception e) {
                 if (!mInstrumentation.onException(r.activity, e)) {
                     throw new RuntimeException(
diff --git a/core/java/android/app/ResultInfo.java b/core/java/android/app/ResultInfo.java
index 535f69f..213c38c 100644
--- a/core/java/android/app/ResultInfo.java
+++ b/core/java/android/app/ResultInfo.java
@@ -20,6 +20,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Intent;
 import android.os.Build;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -36,14 +37,21 @@
     public final int mResultCode;
     @UnsupportedAppUsage
     public final Intent mData;
+    public final IBinder mCallerToken;
 
     @UnsupportedAppUsage
     public ResultInfo(String resultWho, int requestCode, int resultCode,
             Intent data) {
+        this(resultWho, requestCode, resultCode, data, /* callerToken */ null);
+    }
+
+    public ResultInfo(String resultWho, int requestCode, int resultCode,
+            Intent data, IBinder callerToken) {
         mResultWho = resultWho;
         mRequestCode = requestCode;
         mResultCode = resultCode;
         mData = data;
+        mCallerToken = callerToken;
     }
 
     public String toString() {
@@ -65,6 +73,7 @@
         } else {
             out.writeInt(0);
         }
+        out.writeStrongBinder(mCallerToken);
     }
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -88,6 +97,7 @@
         } else {
             mData = null;
         }
+        mCallerToken = in.readStrongBinder();
     }
 
     @Override
@@ -100,7 +110,8 @@
                 : mData.filterEquals(other.mData);
         return intentsEqual && Objects.equals(mResultWho, other.mResultWho)
                 && mResultCode == other.mResultCode
-                && mRequestCode == other.mRequestCode;
+                && mRequestCode == other.mRequestCode
+                && mCallerToken == other.mCallerToken;
     }
 
     @Override
@@ -112,6 +123,7 @@
         if (mData != null) {
             result = 31 * result + mData.filterHashCode();
         }
+        result = 31 * result + Objects.hashCode(mCallerToken);
         return result;
     }
 }
diff --git a/core/java/android/hardware/OverlayProperties.java b/core/java/android/hardware/OverlayProperties.java
index 72586b2..88089ee 100644
--- a/core/java/android/hardware/OverlayProperties.java
+++ b/core/java/android/hardware/OverlayProperties.java
@@ -71,17 +71,36 @@
 
     /**
      * @return True if the device can support fp16, false otherwise.
+     * TODO: Move this to isCombinationSupported once the flag flips
      * @hide
      */
     public boolean isFp16SupportedForHdr() {
         if (mNativeObject == 0) {
             return false;
         }
-        return nSupportFp16ForHdr(mNativeObject);
+        return nIsCombinationSupported(
+                mNativeObject, DataSpace.DATASPACE_SCRGB, HardwareBuffer.RGBA_FP16);
     }
 
     /**
-     * Indicates that hw composition of two or more overlays
+     * Indicates that hardware composition of a buffer encoded with the provided {@link DataSpace}
+     * and {@link HardwareBuffer.Format} is supported on the device.
+     *
+     * @return True if the device can support efficiently compositing the content described by the
+     *         dataspace and format. False if GPOU composition fallback is otherwise required.
+     */
+    @FlaggedApi(Flags.FLAG_OVERLAYPROPERTIES_CLASS_API)
+    public boolean isCombinationSupported(@DataSpace.ColorDataSpace int dataspace,
+            @HardwareBuffer.Format int format) {
+        if (mNativeObject == 0) {
+            return false;
+        }
+
+        return nIsCombinationSupported(mNativeObject, dataspace, format);
+    }
+
+    /**
+     * Indicates that hardware composition of two or more overlays
      * with different colorspaces is supported on the device.
      *
      * @return True if the device can support mixed colorspaces efficiently,
@@ -131,6 +150,8 @@
     private static native long nCreateDefault();
     private static native boolean nSupportFp16ForHdr(long nativeObject);
     private static native boolean nSupportMixedColorSpaces(long nativeObject);
+    private static native boolean nIsCombinationSupported(
+            long nativeObject, int dataspace, int format);
     private static native void nWriteOverlayPropertiesToParcel(long nativeObject, Parcel dest);
     private static native long nReadOverlayPropertiesFromParcel(Parcel in);
 }
diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
index f6b22ed..76c20ce 100644
--- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
@@ -808,13 +808,11 @@
                 extender.init(mCameraId, mCharacteristicsMapNative);
                 CameraMetadataNative metadata =
                         extender.getAvailableCharacteristicsKeyValues(mCameraId);
-                CameraCharacteristics fallbackCharacteristics = mCharacteristicsMap.get(mCameraId);
                 if (metadata == null) {
-                    return fallbackCharacteristics.get(key);
+                    return null;
                 }
                 CameraCharacteristics characteristics = new CameraCharacteristics(metadata);
-                T value = characteristics.get(key);
-                return value == null ? fallbackCharacteristics.get(key) : value;
+                return characteristics.get(key);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to query the extension for the specified key! Extension "
diff --git a/core/java/android/hardware/camera2/CameraExtensionSession.java b/core/java/android/hardware/camera2/CameraExtensionSession.java
index 21fead9..2d9433e 100644
--- a/core/java/android/hardware/camera2/CameraExtensionSession.java
+++ b/core/java/android/hardware/camera2/CameraExtensionSession.java
@@ -16,11 +16,14 @@
 
 package android.hardware.camera2;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.hardware.camera2.utils.HashCodeHelpers;
 
+import com.android.internal.camera.flags.Flags;
+
 import java.util.concurrent.Executor;
 
 /**
@@ -132,6 +135,34 @@
         }
 
         /**
+         * This method is called instead of
+         * {@link #onCaptureProcessStarted} when the camera device failed
+         * to produce the required input for the device-specific extension. The
+         * cause could be a failed camera capture request, a failed
+         * capture result or dropped camera frame. More information about
+         * the reason is included in the 'failure' argument.
+         *
+         * <p>Other requests are unaffected, and some or all image buffers
+         * from the capture may have been pushed to their respective output
+         * streams.</p>
+         *
+         * <p>The default implementation of this method does nothing.</p>
+         *
+         * @param session the session received during
+         *                {@link StateCallback#onConfigured(CameraExtensionSession)}
+         * @param request The request that was given to the CameraDevice
+         * @param failure The capture failure reason
+         *
+         * @see #capture
+         * @see #setRepeatingRequest
+         */
+        @FlaggedApi(Flags.FLAG_CONCERT_MODE)
+        public void onCaptureFailed(@NonNull CameraExtensionSession session,
+                @NonNull CaptureRequest request, @CaptureFailure.FailureReason int failure) {
+            // default empty implementation
+        }
+
+        /**
          * This method is called independently of the others in
          * ExtensionCaptureCallback, when a capture sequence finishes.
          *
diff --git a/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl b/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl
index 02a4690..b1f10ee 100644
--- a/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl
+++ b/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl
@@ -15,6 +15,7 @@
  */
 package android.hardware.camera2.extension;
 
+import android.hardware.camera2.extension.CaptureFailure;
 import android.hardware.camera2.extension.Request;
 import android.hardware.camera2.impl.CameraMetadataNative;
 
@@ -28,4 +29,5 @@
     void onCaptureSequenceAborted(int captureSequenceId);
     void onCaptureCompleted(long shutterTimestamp, int requestId, in CameraMetadataNative results);
     void onCaptureProcessProgressed(int progress);
+    void onCaptureProcessFailed(int captureSequenceId, int captureFailureReason);
 }
diff --git a/core/java/android/hardware/camera2/extension/SessionProcessor.java b/core/java/android/hardware/camera2/extension/SessionProcessor.java
index e7cc5303..d8594e5 100644
--- a/core/java/android/hardware/camera2/extension/SessionProcessor.java
+++ b/core/java/android/hardware/camera2/extension/SessionProcessor.java
@@ -18,8 +18,10 @@
 
 import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CaptureFailure;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.impl.CameraExtensionUtils.HandlerExecutor;
@@ -132,13 +134,14 @@
          * This method is called instead of
          * {@link #onCaptureProcessStarted} when the camera device failed
          * to produce the required input for the device-specific
-         * extension. The cause could be a failed camera capture request,
-         * a failed capture result or dropped camera frame.
+         * extension. The callback allows clients to be notified
+         * about failure reason.
          *
          * @param captureSequenceId id of the current capture sequence
+         * @param failure           The capture failure reason
          */
         @FlaggedApi(Flags.FLAG_CONCERT_MODE)
-        void onCaptureFailed(int captureSequenceId);
+        void onCaptureFailed(int captureSequenceId, @CaptureFailure.FailureReason int failure);
 
         /**
          * This method is called independently of the others in the
@@ -474,9 +477,9 @@
         }
 
         @Override
-        public void onCaptureFailed(int captureSequenceId) {
+        public void onCaptureFailed(int captureSequenceId, int failure) {
             try {
-                mCaptureCallback.onCaptureFailed(captureSequenceId);
+                mCaptureCallback.onCaptureProcessFailed(captureSequenceId, failure);
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to notify capture failure start due to remote exception!");
             }
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index b2032fa..a7d6caf 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -66,6 +66,8 @@
 import android.util.Size;
 import android.view.Surface;
 
+import com.android.internal.camera.flags.Flags;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -779,6 +781,22 @@
         }
 
         @Override
+        public void onCaptureProcessFailed(int captureSequenceId, int captureFailureReason) {
+            if (Flags.concertMode()) {
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    mClientExecutor.execute(
+                            () -> mClientCallbacks.onCaptureFailed(
+                                     CameraAdvancedExtensionSessionImpl.this, mClientRequest,
+                                    captureFailureReason
+                            ));
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        }
+
+        @Override
         public void onCaptureSequenceCompleted(int captureSequenceId) {
             final long ident = Binder.clearCallingIdentity();
             try {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9474a69..75deceb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1022,6 +1022,11 @@
     // Used to check if there is a message in the message queue
     // for idleness handling.
     private boolean mHasIdledMessage = false;
+    // Used to allow developers to opt out Toolkit dVRR feature.
+    // This feature allows device to adjust refresh rate
+    // as needed and can be useful for power saving.
+    // Should not enable the dVRR feature if the value is false.
+    private boolean mIsFrameRatePowerSavingsBalanced = true;
     // time for touch boost period.
     private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000;
     // time for checking idle status periodically.
@@ -2533,8 +2538,10 @@
         // Set the frame rate selection strategy to FRAME_RATE_SELECTION_STRATEGY_SELF
         // This strategy ensures that the frame rate specifications do not cascade down to
         // the descendant layers. This is particularly important for applications like Chrome,
-        // where child surfaces should adhere to default behavior instead of no preference
-        if (sToolkitSetFrameRateReadOnlyFlagValue) {
+        // where child surfaces should adhere to default behavior instead of no preference.
+        // This issue only happens when ViewRootImpl calls setFrameRateCategory. This is
+        // no longer needed if the dVRR feature is disabled.
+        if (shouldEnableDvrr()) {
             try {
                 mFrameRateTransaction.setFrameRateSelectionStrategy(sc,
                         sc.FRAME_RATE_SELECTION_STRATEGY_SELF).applyAsyncUnsafe();
@@ -3258,7 +3265,7 @@
                 destroyHardwareResources();
             }
 
-            if (sToolkitSetFrameRateReadOnlyFlagValue && viewVisibility == View.VISIBLE) {
+            if (shouldEnableDvrr() && viewVisibility == View.VISIBLE) {
                 // Boost frame rate when the viewVisibility becomes true.
                 // This is mainly for lanuchers that lanuch new windows.
                 boostFrameRate(FRAME_RATE_TOUCH_BOOST_TIME);
@@ -3973,7 +3980,7 @@
                 }
             }
 
-            if (sToolkitSetFrameRateReadOnlyFlagValue) {
+            if (shouldEnableDvrr()) {
                 // Boost the frame rate when the ViewRootImpl first becomes available.
                 boostFrameRate(FRAME_RATE_TOUCH_BOOST_TIME);
             }
@@ -5187,7 +5194,10 @@
 
         // Force recalculation of transparent regions
         if (accessibilityFocusDirty) {
-            requestLayout();
+            final Rect bounds = mAttachInfo.mTmpInvalRect;
+            if (getAccessibilityFocusedRect(bounds)) {
+                requestLayout();
+            }
         }
 
         mAttachInfo.mDrawingTime =
@@ -12340,12 +12350,12 @@
 
     private boolean shouldSetFrameRateCategory() {
         // use toolkitSetFrameRate flag to gate the change
-        return  mSurface.isValid() && sToolkitSetFrameRateReadOnlyFlagValue;
+        return  mSurface.isValid() && shouldEnableDvrr();
     }
 
     private boolean shouldSetFrameRate() {
         // use toolkitSetFrameRate flag to gate the change
-        return sToolkitSetFrameRateReadOnlyFlagValue;
+        return mSurface.isValid() && mPreferredFrameRate > 0 && shouldEnableDvrr();
     }
 
     private boolean shouldTouchBoost(int motionEventAction, int windowType) {
@@ -12354,7 +12364,7 @@
                 || motionEventAction == MotionEvent.ACTION_UP;
         boolean undesiredType = windowType == TYPE_INPUT_METHOD && mShouldSuppressBoostOnTyping;
         // use toolkitSetFrameRate flag to gate the change
-        return desiredAction && !undesiredType && sToolkitSetFrameRateReadOnlyFlagValue
+        return desiredAction && !undesiredType && shouldEnableDvrr()
                 && getFrameRateBoostOnTouchEnabled();
     }
 
@@ -12476,4 +12486,27 @@
         // Record the largest view of percentage to the display size.
         mLargestChildPercentage = Math.max(percentage, mLargestChildPercentage);
     }
+
+    /**
+     * Get the value of mIsFrameRatePowerSavingsBalanced
+     * Can be used to checked if toolkit dVRR feature is enabled. The default value is true.
+     */
+    @VisibleForTesting
+    public boolean isFrameRatePowerSavingsBalanced() {
+        return mIsFrameRatePowerSavingsBalanced;
+    }
+
+    /**
+     * Set the value of mIsFrameRatePowerSavingsBalanced
+     * Can be used to checked if toolkit dVRR feature is enabled.
+     */
+    public void setFrameRatePowerSavingsBalanced(boolean enabled) {
+        if (sToolkitSetFrameRateReadOnlyFlagValue) {
+            mIsFrameRatePowerSavingsBalanced = enabled;
+        }
+    }
+
+    private boolean shouldEnableDvrr() {
+        return sToolkitSetFrameRateReadOnlyFlagValue && mIsFrameRatePowerSavingsBalanced;
+    }
 }
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 4ba4ee3..6b427fc 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1409,6 +1409,42 @@
     }
 
     /**
+     * Set whether frameratepowersavingsbalance is enabled for this Window.
+     * This allows device to adjust refresh rate
+     * as needed and can be useful for power saving.
+     *
+     * @param enabled whether the frameratepowersavingsbalance is enabled.
+     * @see #isFrameRatePowerSavingsBalanced()
+     * @see WindowManager.LayoutParams#setFrameRatePowerSavingsBalanced(boolean)
+     */
+    @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    public void setFrameRatePowerSavingsBalanced(boolean enabled) {
+        if (sToolkitSetFrameRateReadOnlyFlagValue) {
+            final WindowManager.LayoutParams attrs = getAttributes();
+            attrs.setFrameRatePowerSavingsBalanced(enabled);
+            dispatchWindowAttributesChanged(attrs);
+        }
+    }
+
+    /**
+     * Get whether frameratepowersavingsbalance is enabled for this Window.
+     * This allows device to adjust refresh rate
+     * as needed and can be useful for power saving.
+     * {@link #setFrameRateBoostOnTouchEnabled(boolean)}
+     *
+     * @return whether the frameratepowersavingsbalance is enabled.
+     * @see #setFrameRatePowerSavingsBalanced(boolean)
+     * @see WindowManager.LayoutParams#isFrameRatePowerSavingsBalanced()
+     */
+    @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    public boolean isFrameRatePowerSavingsBalanced() {
+        if (sToolkitSetFrameRateReadOnlyFlagValue) {
+            return getAttributes().isFrameRatePowerSavingsBalanced();
+        }
+        return false;
+    }
+
+    /**
      * If {@code isPreferred} is true, this method requests that the connected display does minimal
      * post processing when this window is visible on the screen. Otherwise, it requests that the
      * display switches back to standard image processing.
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index e4be016..0e17626 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -4439,6 +4439,7 @@
          * For variable refresh rate project.
          */
         private boolean mFrameRateBoostOnTouch = true;
+        private boolean mIsFrameRatePowerSavingsBalanced = true;
         private static boolean sToolkitSetFrameRateReadOnlyFlagValue =
                 android.view.flags.Flags.toolkitSetFrameRateReadOnly();
 
@@ -4903,6 +4904,36 @@
         }
 
         /**
+         * Set the value whether frameratepowersavingsbalance is enabled for this Window.
+         * This allows device to adjust refresh rate
+         * as needed and can be useful for power saving.
+         *
+         * @param enabled Whether we should enable frameratepowersavingsbalance.
+         */
+        @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+        public void setFrameRatePowerSavingsBalanced(boolean enabled) {
+            if (sToolkitSetFrameRateReadOnlyFlagValue) {
+                mIsFrameRatePowerSavingsBalanced = enabled;
+            }
+        }
+
+        /**
+         * Get the value whether frameratepowersavingsbalance is enabled for this Window.
+         * This allows device to adjust refresh rate
+         * as needed and can be useful for power saving.
+         * by {@link #setFrameRatePowerSavingsBalanced(boolean)}
+         *
+         * @return Whether we should enable frameratepowersavingsbalance.
+         */
+        @FlaggedApi(android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+        public boolean isFrameRatePowerSavingsBalanced() {
+            if (sToolkitSetFrameRateReadOnlyFlagValue) {
+                return mIsFrameRatePowerSavingsBalanced;
+            }
+            return true;
+        }
+
+        /**
          * <p>
          * Blurs the screen behind the window. The effect is similar to that of {@link #dimAmount},
          * but instead of dimmed, the content behind the window will be blurred (or combined with
@@ -5055,6 +5086,7 @@
             out.writeFloat(mDesiredHdrHeadroom);
             if (sToolkitSetFrameRateReadOnlyFlagValue) {
                 out.writeBoolean(mFrameRateBoostOnTouch);
+                out.writeBoolean(mIsFrameRatePowerSavingsBalanced);
             }
         }
 
@@ -5130,6 +5162,7 @@
             mDesiredHdrHeadroom = in.readFloat();
             if (sToolkitSetFrameRateReadOnlyFlagValue) {
                 mFrameRateBoostOnTouch = in.readBoolean();
+                mIsFrameRatePowerSavingsBalanced = in.readBoolean();
             }
         }
 
@@ -5473,6 +5506,12 @@
                 changes |= LAYOUT_CHANGED;
             }
 
+            if (sToolkitSetFrameRateReadOnlyFlagValue
+                    && mIsFrameRatePowerSavingsBalanced != o.mIsFrameRatePowerSavingsBalanced) {
+                mIsFrameRatePowerSavingsBalanced = o.mIsFrameRatePowerSavingsBalanced;
+                changes |= LAYOUT_CHANGED;
+            }
+
             return changes;
         }
 
@@ -5700,6 +5739,11 @@
                 sb.append(prefix).append("  frameRateBoostOnTouch=");
                 sb.append(mFrameRateBoostOnTouch);
             }
+            if (sToolkitSetFrameRateReadOnlyFlagValue && mIsFrameRatePowerSavingsBalanced) {
+                sb.append(System.lineSeparator());
+                sb.append(prefix).append("  dvrrWindowFrameRateHint=");
+                sb.append(mIsFrameRatePowerSavingsBalanced);
+            }
             if (paramsForRotation != null && paramsForRotation.length != 0) {
                 sb.append(System.lineSeparator());
                 sb.append(prefix).append("  paramsForRotation:");
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 5239245..0dd01e4 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -363,6 +363,8 @@
 
     private boolean mUseDecorContext = false;
 
+    private boolean mIsFrameRatePowerSavingsBalanced = true;
+
     /** @see ViewRootImpl#mActivityConfigCallback */
     private ActivityConfigCallback mActivityConfigCallback;
 
@@ -2211,6 +2213,7 @@
     void onViewRootImplSet(ViewRootImpl viewRoot) {
         viewRoot.setActivityConfigCallback(mActivityConfigCallback);
         viewRoot.getOnBackInvokedDispatcher().updateContext(getContext());
+        viewRoot.setFrameRatePowerSavingsBalanced(mIsFrameRatePowerSavingsBalanced);
         mProxyOnBackInvokedDispatcher.setActualDispatcher(viewRoot.getOnBackInvokedDispatcher());
         applyDecorFitsSystemWindows();
     }
@@ -2559,6 +2562,10 @@
         if (a.getBoolean(R.styleable.Window_windowActivityTransitions, false)) {
             requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
         }
+        if (a.hasValue(R.styleable.Window_windowIsFrameRatePowerSavingsBalanced)) {
+            mIsFrameRatePowerSavingsBalanced =
+                    a.getBoolean(R.styleable.Window_windowIsFrameRatePowerSavingsBalanced, true);
+        }
 
         mIsTranslucent = a.getBoolean(R.styleable.Window_windowIsTranslucent, false);
 
diff --git a/core/jni/android_hardware_OverlayProperties.cpp b/core/jni/android_hardware_OverlayProperties.cpp
index f6fe3dd..96494b1 100644
--- a/core/jni/android_hardware_OverlayProperties.cpp
+++ b/core/jni/android_hardware_OverlayProperties.cpp
@@ -35,7 +35,6 @@
     jclass clazz;
     jmethodID ctor;
 } gOverlayPropertiesClassInfo;
-
 // ----------------------------------------------------------------------------
 // OverlayProperties lifecycle
 // ----------------------------------------------------------------------------
@@ -52,21 +51,21 @@
 // Accessors
 // ----------------------------------------------------------------------------
 
-static jboolean android_hardware_OverlayProperties_supportFp16ForHdr(JNIEnv* env, jobject thiz,
-                                                                     jlong nativeObject) {
+static jboolean android_hardware_OverlayProperties_isCombinationSupported(JNIEnv* env, jobject thiz,
+                                                                          jlong nativeObject,
+                                                                          jint dataspace,
+                                                                          jint format) {
     gui::OverlayProperties* properties = reinterpret_cast<gui::OverlayProperties*>(nativeObject);
     if (properties != nullptr) {
         for (const auto& i : properties->combinations) {
-            if (std::find(i.pixelFormats.begin(), i.pixelFormats.end(),
-                          static_cast<int32_t>(HAL_PIXEL_FORMAT_RGBA_FP16)) !=
+            if (std::find(i.pixelFormats.begin(), i.pixelFormats.end(), format) !=
                         i.pixelFormats.end() &&
                 std::find(i.standards.begin(), i.standards.end(),
-                          static_cast<int32_t>(HAL_DATASPACE_STANDARD_BT709)) !=
-                        i.standards.end() &&
+                          dataspace & HAL_DATASPACE_STANDARD_MASK) != i.standards.end() &&
                 std::find(i.transfers.begin(), i.transfers.end(),
-                          static_cast<int32_t>(HAL_DATASPACE_TRANSFER_SRGB)) != i.transfers.end() &&
-                std::find(i.ranges.begin(), i.ranges.end(),
-                          static_cast<int32_t>(HAL_DATASPACE_RANGE_EXTENDED)) != i.ranges.end()) {
+                          dataspace & HAL_DATASPACE_TRANSFER_MASK) != i.transfers.end() &&
+                std::find(i.ranges.begin(), i.ranges.end(), dataspace & HAL_DATASPACE_RANGE_MASK) !=
+                        i.ranges.end()) {
                 return true;
             }
         }
@@ -88,7 +87,7 @@
     gui::OverlayProperties* overlayProperties = new gui::OverlayProperties;
     gui::OverlayProperties::SupportedBufferCombinations combination;
     combination.pixelFormats = {HAL_PIXEL_FORMAT_RGBA_8888};
-    combination.standards = {HAL_DATASPACE_BT709};
+    combination.standards = {HAL_DATASPACE_STANDARD_BT709};
     combination.transfers = {HAL_DATASPACE_TRANSFER_SRGB};
     combination.ranges = {HAL_DATASPACE_RANGE_FULL};
     overlayProperties->combinations.emplace_back(combination);
@@ -153,8 +152,8 @@
 // clang-format off
 static const JNINativeMethod gMethods[] = {
     { "nGetDestructor", "()J", (void*) android_hardware_OverlayProperties_getDestructor },
-    { "nSupportFp16ForHdr",  "(J)Z",
-            (void*)  android_hardware_OverlayProperties_supportFp16ForHdr },
+    { "nIsCombinationSupported",  "(JII)Z",
+            (void*)  android_hardware_OverlayProperties_isCombinationSupported },
     { "nSupportMixedColorSpaces", "(J)Z",
             (void*) android_hardware_OverlayProperties_supportMixedColorSpaces },
     { "nWriteOverlayPropertiesToParcel", "(JLandroid/os/Parcel;)V",
@@ -172,6 +171,5 @@
     gOverlayPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
     gOverlayPropertiesClassInfo.ctor =
             GetMethodIDOrDie(env, gOverlayPropertiesClassInfo.clazz, "<init>", "(J)V");
-
     return err;
 }
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index cc6460e..c1fd619 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2514,6 +2514,13 @@
             <!-- The icon is shown unless the launching app specified SPLASH_SCREEN_STYLE_EMPTY -->
             <enum name="icon_preferred" value="1" />
         </attr>
+        <!-- Offer Window the ability to opt out the UI Toolkit discrete variable refresh rate.
+             This feature allows device to adjust refresh rate as needed and
+             can be useful for power saving.
+             Set to false to reduce the frame rate optimizations on devices with
+             variable refresh rate screens.
+             The default is true. -->
+        <attr name="windowIsFrameRatePowerSavingsBalanced" format="boolean"/>
 
         <!-- Flag indicating whether this window would opt-out the edge-to-edge enforcement.
 
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 8af8cb8..c797210 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -165,6 +165,8 @@
     <public name="allowCrossUidActivitySwitchFromBelow"/>
     <!-- @FlaggedApi("com.android.text.flags.use_bounds_for_width") -->
     <public name="shiftDrawingOffsetForStartOverhang" />
+    <!-- @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") -->
+    <public name="windowIsFrameRatePowerSavingsBalanced"/>
   </staging-public-group>
 
   <staging-public-group type="id" first-id="0x01bc0000">
diff --git a/core/tests/coretests/res/values/styles.xml b/core/tests/coretests/res/values/styles.xml
index 32eebb35..78cd1e1 100644
--- a/core/tests/coretests/res/values/styles.xml
+++ b/core/tests/coretests/res/values/styles.xml
@@ -55,4 +55,10 @@
     <style name="ViewDefaultBackground">
         <item name="android:background">#00000000</item>
     </style>
+    <style name="IsFrameRatePowerSavingsBalancedDisabled">
+        <item name="android:windowIsFrameRatePowerSavingsBalanced">false</item>
+    </style>
+    <style name="IsFrameRatePowerSavingsBalancedEnabled">
+        <item name="android:windowIsFrameRatePowerSavingsBalanced">true</item>
+    </style>
 </resources>
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index 433d353..038c00e 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -953,6 +953,22 @@
         });
     }
 
+    /**
+     * Test the IsFrameRatePowerSavingsBalanced values are properly set
+     */
+    @UiThreadTest
+    @Test
+    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    public void votePreferredFrameRate_isFrameRatePowerSavingsBalanced() {
+        ViewRootImpl viewRootImpl = new ViewRootImpl(sContext,
+                sContext.getDisplayNoVerify());
+        assertEquals(viewRootImpl.isFrameRatePowerSavingsBalanced(), true);
+        viewRootImpl.setFrameRatePowerSavingsBalanced(false);
+        assertEquals(viewRootImpl.isFrameRatePowerSavingsBalanced(), false);
+        viewRootImpl.setFrameRatePowerSavingsBalanced(true);
+        assertEquals(viewRootImpl.isFrameRatePowerSavingsBalanced(), true);
+    }
+
     @Test
     public void forceInvertOffDarkThemeOff_forceDarkModeDisabled() {
         mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR);
diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
index 3df3b9d2..b9841ff 100644
--- a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
+++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
@@ -21,17 +21,28 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
 
 import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 
+import android.app.Instrumentation;
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.os.Binder;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.view.ActionMode;
 import android.view.ContextThemeWrapper;
+import android.view.ViewRootImpl;
+import android.view.WindowManager;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -40,6 +51,7 @@
 import com.android.frameworks.coretests.R;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -54,6 +66,12 @@
     private PhoneWindow mPhoneWindow;
     private Context mContext;
 
+    private static Instrumentation sInstrumentation =
+            InstrumentationRegistry.getInstrumentation();
+
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getContext();
@@ -154,6 +172,48 @@
         assertThat(colorDrawable.getColor(), is(Color.BLUE));
     }
 
+    @Test
+    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    public void testWindowFrameRateHint_disabled() {
+        createPhoneWindowWithTheme(R.style.IsFrameRatePowerSavingsBalancedDisabled);
+        installDecor();
+
+        DecorView decorView = (DecorView) mPhoneWindow.getDecorView();
+
+        WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
+        wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check
+
+        sInstrumentation.runOnMainSync(() -> {
+            WindowManager wm = mContext.getSystemService(WindowManager.class);
+            wm.addView(decorView, wmlp);
+        });
+        sInstrumentation.waitForIdleSync();
+
+        ViewRootImpl viewRootImpl = decorView.getViewRootImpl();
+        assertFalse(viewRootImpl.isFrameRatePowerSavingsBalanced());
+    }
+
+    @Test
+    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    public void testWindowFrameRateHint_enabled() {
+        createPhoneWindowWithTheme(R.style.IsFrameRatePowerSavingsBalancedEnabled);
+        installDecor();
+
+        DecorView decorView = (DecorView) mPhoneWindow.getDecorView();
+
+        WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
+        wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check
+
+        sInstrumentation.runOnMainSync(() -> {
+            WindowManager wm = mContext.getSystemService(WindowManager.class);
+            wm.addView(decorView, wmlp);
+        });
+        sInstrumentation.waitForIdleSync();
+
+        ViewRootImpl viewRootImpl = decorView.getViewRootImpl();
+        assertTrue(viewRootImpl.isFrameRatePowerSavingsBalanced());
+    }
+
     private void createPhoneWindowWithTheme(int theme) {
         mPhoneWindow = new PhoneWindow(new ContextThemeWrapper(mContext, theme));
     }
diff --git a/data/etc/com.android.intentresolver.xml b/data/etc/com.android.intentresolver.xml
index af64926..afd4f7c 100644
--- a/data/etc/com.android.intentresolver.xml
+++ b/data/etc/com.android.intentresolver.xml
@@ -17,8 +17,10 @@
 <permissions>
     <privapp-permissions package="com.android.intentresolver">
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.LOG_COMPAT_CHANGE"/>
         <permission name="android.permission.MANAGE_USERS"/>
         <permission name="android.permission.PACKAGE_USAGE_STATS"/>
         <permission name="android.permission.QUERY_CLONED_APPS"/>
+        <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
     </privapp-permissions>
 </permissions>
diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java
index 3cd709e..69e1982 100644
--- a/graphics/java/android/graphics/pdf/PdfEditor.java
+++ b/graphics/java/android/graphics/pdf/PdfEditor.java
@@ -25,7 +25,9 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
+
 import dalvik.system.CloseGuard;
+
 import libcore.io.IoUtils;
 
 import java.io.IOException;
@@ -37,6 +39,12 @@
  */
 public final class PdfEditor {
 
+    /**
+     * Any call the native pdfium code has to be single threaded as the library does not support
+     * parallel use.
+     */
+    private static final Object sPdfiumLock = new Object();
+
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
     private long mNativeDocument;
@@ -79,7 +87,7 @@
         }
         mInput = input;
 
-        synchronized (PdfRenderer.sPdfiumLock) {
+        synchronized (sPdfiumLock) {
             mNativeDocument = nativeOpen(mInput.getFd(), size);
             try {
                 mPageCount = nativeGetPageCount(mNativeDocument);
@@ -112,7 +120,7 @@
         throwIfClosed();
         throwIfPageNotInDocument(pageIndex);
 
-        synchronized (PdfRenderer.sPdfiumLock) {
+        synchronized (sPdfiumLock) {
             mPageCount = nativeRemovePage(mNativeDocument, pageIndex);
         }
     }
@@ -138,12 +146,12 @@
             Point size = new Point();
             getPageSize(pageIndex, size);
 
-            synchronized (PdfRenderer.sPdfiumLock) {
+            synchronized (sPdfiumLock) {
                 nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.ni(),
                         0, 0, size.x, size.y);
             }
         } else {
-            synchronized (PdfRenderer.sPdfiumLock) {
+            synchronized (sPdfiumLock) {
                 nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.ni(),
                         clip.left, clip.top, clip.right, clip.bottom);
             }
@@ -161,7 +169,7 @@
         throwIfOutSizeNull(outSize);
         throwIfPageNotInDocument(pageIndex);
 
-        synchronized (PdfRenderer.sPdfiumLock) {
+        synchronized (sPdfiumLock) {
             nativeGetPageSize(mNativeDocument, pageIndex, outSize);
         }
     }
@@ -177,7 +185,7 @@
         throwIfOutMediaBoxNull(outMediaBox);
         throwIfPageNotInDocument(pageIndex);
 
-        synchronized (PdfRenderer.sPdfiumLock) {
+        synchronized (sPdfiumLock) {
             return nativeGetPageMediaBox(mNativeDocument, pageIndex, outMediaBox);
         }
     }
@@ -193,7 +201,7 @@
         throwIfMediaBoxNull(mediaBox);
         throwIfPageNotInDocument(pageIndex);
 
-        synchronized (PdfRenderer.sPdfiumLock) {
+        synchronized (sPdfiumLock) {
             nativeSetPageMediaBox(mNativeDocument, pageIndex, mediaBox);
         }
     }
@@ -209,7 +217,7 @@
         throwIfOutCropBoxNull(outCropBox);
         throwIfPageNotInDocument(pageIndex);
 
-        synchronized (PdfRenderer.sPdfiumLock) {
+        synchronized (sPdfiumLock) {
             return nativeGetPageCropBox(mNativeDocument, pageIndex, outCropBox);
         }
     }
@@ -225,7 +233,7 @@
         throwIfCropBoxNull(cropBox);
         throwIfPageNotInDocument(pageIndex);
 
-        synchronized (PdfRenderer.sPdfiumLock) {
+        synchronized (sPdfiumLock) {
             nativeSetPageCropBox(mNativeDocument, pageIndex, cropBox);
         }
     }
@@ -238,7 +246,7 @@
     public boolean shouldScaleForPrinting() {
         throwIfClosed();
 
-        synchronized (PdfRenderer.sPdfiumLock) {
+        synchronized (sPdfiumLock) {
             return nativeScaleForPrinting(mNativeDocument);
         }
     }
@@ -255,7 +263,7 @@
         try {
             throwIfClosed();
 
-            synchronized (PdfRenderer.sPdfiumLock) {
+            synchronized (sPdfiumLock) {
                 nativeWrite(mNativeDocument, output.getFd());
             }
         } finally {
@@ -287,7 +295,7 @@
 
     private void doClose() {
         if (mNativeDocument != 0) {
-            synchronized (PdfRenderer.sPdfiumLock) {
+            synchronized (sPdfiumLock) {
                 nativeClose(mNativeDocument);
             }
             mNativeDocument = 0;
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
deleted file mode 100644
index 4666963..0000000
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright (C) 2014 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.graphics.pdf;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Matrix;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-
-import com.android.internal.util.Preconditions;
-
-import dalvik.system.CloseGuard;
-
-import libcore.io.IoUtils;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * <p>
- * This class enables rendering a PDF document. This class is not thread safe.
- * </p>
- * <p>
- * If you want to render a PDF, you create a renderer and for every page you want
- * to render, you open the page, render it, and close the page. After you are done
- * with rendering, you close the renderer. After the renderer is closed it should not
- * be used anymore. Note that the pages are rendered one by one, i.e. you can have
- * only a single page opened at any given time.
- * </p>
- * <p>
- * A typical use of the APIs to render a PDF looks like this:
- * </p>
- * <pre>
- * // create a new renderer
- * PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor());
- *
- * // let us just render all pages
- * final int pageCount = renderer.getPageCount();
- * for (int i = 0; i < pageCount; i++) {
- *     Page page = renderer.openPage(i);
- *
- *     // say we render for showing on the screen
- *     page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY);
- *
- *     // do stuff with the bitmap
- *
- *     // close the page
- *     page.close();
- * }
- *
- * // close the renderer
- * renderer.close();
- * </pre>
- *
- * <h3>Print preview and print output</h3>
- * <p>
- * If you are using this class to rasterize a PDF for printing or show a print
- * preview, it is recommended that you respect the following contract in order
- * to provide a consistent user experience when seeing a preview and printing,
- * i.e. the user sees a preview that is the same as the printout.
- * </p>
- * <ul>
- * <li>
- * Respect the property whether the document would like to be scaled for printing
- * as per {@link #shouldScaleForPrinting()}.
- * </li>
- * <li>
- * When scaling a document for printing the aspect ratio should be preserved.
- * </li>
- * <li>
- * Do not inset the content with any margins from the {@link android.print.PrintAttributes}
- * as the application is responsible to render it such that the margins are respected.
- * </li>
- * <li>
- * If document page size is greater than the printed media size the content should
- * be anchored to the upper left corner of the page for left-to-right locales and
- * top right corner for right-to-left locales.
- * </li>
- * </ul>
- *
- * @see #close()
- */
-public final class PdfRenderer implements AutoCloseable {
-    /**
-     * Any call the native pdfium code has to be single threaded as the library does not support
-     * parallel use.
-     */
-    final static Object sPdfiumLock = new Object();
-
-    private final CloseGuard mCloseGuard = CloseGuard.get();
-
-    private final Point mTempPoint = new Point();
-
-    private long mNativeDocument;
-
-    private final int mPageCount;
-
-    private ParcelFileDescriptor mInput;
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private Page mCurrentPage;
-
-    /** @hide */
-    @IntDef({
-        Page.RENDER_MODE_FOR_DISPLAY,
-        Page.RENDER_MODE_FOR_PRINT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RenderMode {}
-
-    /**
-     * Creates a new instance.
-     * <p>
-     * <strong>Note:</strong> The provided file descriptor must be <strong>seekable</strong>,
-     * i.e. its data being randomly accessed, e.g. pointing to a file.
-     * </p>
-     * <p>
-     * <strong>Note:</strong> This class takes ownership of the passed in file descriptor
-     * and is responsible for closing it when the renderer is closed.
-     * </p>
-     * <p>
-     * If the file is from an untrusted source it is recommended to run the renderer in a separate,
-     * isolated process with minimal permissions to limit the impact of security exploits.
-     * </p>
-     *
-     * @param input Seekable file descriptor to read from.
-     *
-     * @throws java.io.IOException If an error occurs while reading the file.
-     * @throws java.lang.SecurityException If the file requires a password or
-     *         the security scheme is not supported.
-     */
-    public PdfRenderer(@NonNull ParcelFileDescriptor input) throws IOException {
-        if (input == null) {
-            throw new NullPointerException("input cannot be null");
-        }
-
-        final long size;
-        try {
-            Os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET);
-            size = Os.fstat(input.getFileDescriptor()).st_size;
-        } catch (ErrnoException ee) {
-            throw new IllegalArgumentException("file descriptor not seekable");
-        }
-        mInput = input;
-
-        synchronized (sPdfiumLock) {
-            mNativeDocument = nativeCreate(mInput.getFd(), size);
-            try {
-                mPageCount = nativeGetPageCount(mNativeDocument);
-            } catch (Throwable t) {
-                nativeClose(mNativeDocument);
-                mNativeDocument = 0;
-                throw t;
-            }
-        }
-
-        mCloseGuard.open("close");
-    }
-
-    /**
-     * Closes this renderer. You should not use this instance
-     * after this method is called.
-     */
-    public void close() {
-        throwIfClosed();
-        throwIfPageOpened();
-        doClose();
-    }
-
-    /**
-     * Gets the number of pages in the document.
-     *
-     * @return The page count.
-     */
-    public int getPageCount() {
-        throwIfClosed();
-        return mPageCount;
-    }
-
-    /**
-     * Gets whether the document prefers to be scaled for printing.
-     * You should take this info account if the document is rendered
-     * for printing and the target media size differs from the page
-     * size.
-     *
-     * @return If to scale the document.
-     */
-    public boolean shouldScaleForPrinting() {
-        throwIfClosed();
-
-        synchronized (sPdfiumLock) {
-            return nativeScaleForPrinting(mNativeDocument);
-        }
-    }
-
-    /**
-     * Opens a page for rendering.
-     *
-     * @param index The page index.
-     * @return A page that can be rendered.
-     *
-     * @see android.graphics.pdf.PdfRenderer.Page#close() PdfRenderer.Page.close()
-     */
-    public Page openPage(int index) {
-        throwIfClosed();
-        throwIfPageOpened();
-        throwIfPageNotInDocument(index);
-        mCurrentPage = new Page(index);
-        return mCurrentPage;
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (mCloseGuard != null) {
-                mCloseGuard.warnIfOpen();
-            }
-
-            doClose();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private void doClose() {
-        if (mCurrentPage != null) {
-            mCurrentPage.close();
-            mCurrentPage = null;
-        }
-
-        if (mNativeDocument != 0) {
-            synchronized (sPdfiumLock) {
-                nativeClose(mNativeDocument);
-            }
-            mNativeDocument = 0;
-        }
-
-        if (mInput != null) {
-            IoUtils.closeQuietly(mInput);
-            mInput = null;
-        }
-        mCloseGuard.close();
-    }
-
-    private void throwIfClosed() {
-        if (mInput == null) {
-            throw new IllegalStateException("Already closed");
-        }
-    }
-
-    private void throwIfPageOpened() {
-        if (mCurrentPage != null) {
-            throw new IllegalStateException("Current page not closed");
-        }
-    }
-
-    private void throwIfPageNotInDocument(int pageIndex) {
-        if (pageIndex < 0 || pageIndex >= mPageCount) {
-            throw new IllegalArgumentException("Invalid page index");
-        }
-    }
-
-    /**
-     * This class represents a PDF document page for rendering.
-     */
-    public final class Page implements AutoCloseable {
-
-        private final CloseGuard mCloseGuard = CloseGuard.get();
-
-        /**
-         * Mode to render the content for display on a screen.
-         */
-        public static final int RENDER_MODE_FOR_DISPLAY = 1;
-
-        /**
-         * Mode to render the content for printing.
-         */
-        public static final int RENDER_MODE_FOR_PRINT = 2;
-
-        private final int mIndex;
-        private final int mWidth;
-        private final int mHeight;
-
-        private long mNativePage;
-
-        private Page(int index) {
-            Point size = mTempPoint;
-            synchronized (sPdfiumLock) {
-                mNativePage = nativeOpenPageAndGetSize(mNativeDocument, index, size);
-            }
-            mIndex = index;
-            mWidth = size.x;
-            mHeight = size.y;
-            mCloseGuard.open("close");
-        }
-
-        /**
-         * Gets the page index.
-         *
-         * @return The index.
-         */
-        public int getIndex() {
-            return  mIndex;
-        }
-
-        /**
-         * Gets the page width in points (1/72").
-         *
-         * @return The width in points.
-         */
-        public int getWidth() {
-            return mWidth;
-        }
-
-        /**
-         * Gets the page height in points (1/72").
-         *
-         * @return The height in points.
-         */
-        public int getHeight() {
-            return mHeight;
-        }
-
-        /**
-         * Renders a page to a bitmap.
-         * <p>
-         * You may optionally specify a rectangular clip in the bitmap bounds. No rendering
-         * outside the clip will be performed, hence it is your responsibility to initialize
-         * the bitmap outside the clip.
-         * </p>
-         * <p>
-         * You may optionally specify a matrix to transform the content from page coordinates
-         * which are in points (1/72") to bitmap coordinates which are in pixels. If this
-         * matrix is not provided this method will apply a transformation that will fit the
-         * whole page to the destination clip if provided or the destination bitmap if no
-         * clip is provided.
-         * </p>
-         * <p>
-         * The clip and transformation are useful for implementing tile rendering where the
-         * destination bitmap contains a portion of the image, for example when zooming.
-         * Another useful application is for printing where the size of the bitmap holding
-         * the page is too large and a client can render the page in stripes.
-         * </p>
-         * <p>
-         * <strong>Note: </strong> The destination bitmap format must be
-         * {@link Config#ARGB_8888 ARGB}.
-         * </p>
-         * <p>
-         * <strong>Note: </strong> The optional transformation matrix must be affine as per
-         * {@link android.graphics.Matrix#isAffine() Matrix.isAffine()}. Hence, you can specify
-         * rotation, scaling, translation but not a perspective transformation.
-         * </p>
-         *
-         * @param destination Destination bitmap to which to render.
-         * @param destClip Optional clip in the bitmap bounds.
-         * @param transform Optional transformation to apply when rendering.
-         * @param renderMode The render mode.
-         *
-         * @see #RENDER_MODE_FOR_DISPLAY
-         * @see #RENDER_MODE_FOR_PRINT
-         */
-        public void render(@NonNull Bitmap destination, @Nullable Rect destClip,
-                           @Nullable Matrix transform, @RenderMode int renderMode) {
-            if (mNativePage == 0) {
-                throw new NullPointerException();
-            }
-
-            destination = Preconditions.checkNotNull(destination, "bitmap null");
-
-            if (destination.getConfig() != Config.ARGB_8888) {
-                throw new IllegalArgumentException("Unsupported pixel format");
-            }
-
-            if (destClip != null) {
-                if (destClip.left < 0 || destClip.top < 0
-                        || destClip.right > destination.getWidth()
-                        || destClip.bottom > destination.getHeight()) {
-                    throw new IllegalArgumentException("destBounds not in destination");
-                }
-            }
-
-            if (transform != null && !transform.isAffine()) {
-                 throw new IllegalArgumentException("transform not affine");
-            }
-
-            if (renderMode != RENDER_MODE_FOR_PRINT && renderMode != RENDER_MODE_FOR_DISPLAY) {
-                throw new IllegalArgumentException("Unsupported render mode");
-            }
-
-            if (renderMode == RENDER_MODE_FOR_PRINT && renderMode == RENDER_MODE_FOR_DISPLAY) {
-                throw new IllegalArgumentException("Only single render mode supported");
-            }
-
-            final int contentLeft = (destClip != null) ? destClip.left : 0;
-            final int contentTop = (destClip != null) ? destClip.top : 0;
-            final int contentRight = (destClip != null) ? destClip.right
-                    : destination.getWidth();
-            final int contentBottom = (destClip != null) ? destClip.bottom
-                    : destination.getHeight();
-
-            // If transform is not set, stretch page to whole clipped area
-            if (transform == null) {
-                int clipWidth = contentRight - contentLeft;
-                int clipHeight = contentBottom - contentTop;
-
-                transform = new Matrix();
-                transform.postScale((float)clipWidth / getWidth(),
-                        (float)clipHeight / getHeight());
-                transform.postTranslate(contentLeft, contentTop);
-            }
-
-            // FIXME: This code is planned to be outside the UI rendering module, so it should not
-            // be able to access native instances from Bitmap, Matrix, etc.
-            final long transformPtr = transform.ni();
-
-            synchronized (sPdfiumLock) {
-                nativeRenderPage(mNativeDocument, mNativePage, destination.getNativeInstance(),
-                        contentLeft, contentTop, contentRight, contentBottom, transformPtr,
-                        renderMode);
-            }
-        }
-
-        /**
-         * Closes this page.
-         *
-         * @see android.graphics.pdf.PdfRenderer#openPage(int)
-         */
-        @Override
-        public void close() {
-            throwIfClosed();
-            doClose();
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                if (mCloseGuard != null) {
-                    mCloseGuard.warnIfOpen();
-                }
-
-                doClose();
-            } finally {
-                super.finalize();
-            }
-        }
-
-        private void doClose() {
-            if (mNativePage != 0) {
-                synchronized (sPdfiumLock) {
-                    nativeClosePage(mNativePage);
-                }
-                mNativePage = 0;
-            }
-
-            mCloseGuard.close();
-            mCurrentPage = null;
-        }
-
-        private void throwIfClosed() {
-            if (mNativePage == 0) {
-                throw new IllegalStateException("Already closed");
-            }
-        }
-    }
-
-    private static native long nativeCreate(int fd, long size);
-    private static native void nativeClose(long documentPtr);
-    private static native int nativeGetPageCount(long documentPtr);
-    private static native boolean nativeScaleForPrinting(long documentPtr);
-    private static native void nativeRenderPage(long documentPtr, long pagePtr, long bitmapHandle,
-            int clipLeft, int clipTop, int clipRight, int clipBottom, long transformPtr,
-            int renderMode);
-    private static native long nativeOpenPageAndGetSize(long documentPtr, int pageIndex,
-            Point outSize);
-    private static native void nativeClosePage(long pagePtr);
-}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 4e330da..e4f3e2d 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -427,7 +427,6 @@
                 "jni/MovieImpl.cpp",
                 "jni/pdf/PdfDocument.cpp",
                 "jni/pdf/PdfEditor.cpp",
-                "jni/pdf/PdfRenderer.cpp",
                 "jni/pdf/PdfUtils.cpp",
             ],
             shared_libs: [
diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp
index 883f273..fb0cdb0 100644
--- a/libs/hwui/apex/jni_runtime.cpp
+++ b/libs/hwui/apex/jni_runtime.cpp
@@ -70,7 +70,6 @@
 extern int register_android_graphics_fonts_FontFamily(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env);
-extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
 extern int register_android_graphics_text_MeasuredText(JNIEnv* env);
 extern int register_android_graphics_text_LineBreaker(JNIEnv *env);
 extern int register_android_graphics_text_TextShaper(JNIEnv *env);
@@ -142,7 +141,6 @@
             REG_JNI(register_android_graphics_fonts_FontFamily),
             REG_JNI(register_android_graphics_pdf_PdfDocument),
             REG_JNI(register_android_graphics_pdf_PdfEditor),
-            REG_JNI(register_android_graphics_pdf_PdfRenderer),
             REG_JNI(register_android_graphics_text_MeasuredText),
             REG_JNI(register_android_graphics_text_LineBreaker),
             REG_JNI(register_android_graphics_text_TextShaper),
diff --git a/libs/hwui/jni/pdf/PdfRenderer.cpp b/libs/hwui/jni/pdf/PdfRenderer.cpp
deleted file mode 100644
index cc1f961..0000000
--- a/libs/hwui/jni/pdf/PdfRenderer.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#include "PdfUtils.h"
-
-#include "GraphicsJNI.h"
-#include "SkBitmap.h"
-#include "SkMatrix.h"
-#include "fpdfview.h"
-
-#include <vector>
-#include <utils/Log.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace android {
-
-static const int RENDER_MODE_FOR_DISPLAY = 1;
-static const int RENDER_MODE_FOR_PRINT = 2;
-
-static struct {
-    jfieldID x;
-    jfieldID y;
-} gPointClassInfo;
-
-static jlong nativeOpenPageAndGetSize(JNIEnv* env, jclass thiz, jlong documentPtr,
-        jint pageIndex, jobject outSize) {
-    FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr);
-
-    FPDF_PAGE page = FPDF_LoadPage(document, pageIndex);
-    if (!page) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-                "cannot load page");
-        return -1;
-    }
-
-    double width = 0;
-    double height = 0;
-
-    int result = FPDF_GetPageSizeByIndex(document, pageIndex, &width, &height);
-    if (!result) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-                    "cannot get page size");
-        return -1;
-    }
-
-    env->SetIntField(outSize, gPointClassInfo.x, width);
-    env->SetIntField(outSize, gPointClassInfo.y, height);
-
-    return reinterpret_cast<jlong>(page);
-}
-
-static void nativeClosePage(JNIEnv* env, jclass thiz, jlong pagePtr) {
-    FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
-    FPDF_ClosePage(page);
-}
-
-static void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong pagePtr,
-        jlong bitmapPtr, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom,
-        jlong transformPtr, jint renderMode) {
-    FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
-
-    SkBitmap skBitmap;
-    bitmap::toBitmap(bitmapPtr).getSkBitmap(&skBitmap);
-
-    const int stride = skBitmap.width() * 4;
-
-    FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap.width(), skBitmap.height(),
-            FPDFBitmap_BGRA, skBitmap.getPixels(), stride);
-
-    int renderFlags = FPDF_REVERSE_BYTE_ORDER;
-    if (renderMode == RENDER_MODE_FOR_DISPLAY) {
-        renderFlags |= FPDF_LCD_TEXT;
-    } else if (renderMode == RENDER_MODE_FOR_PRINT) {
-        renderFlags |= FPDF_PRINTING;
-    }
-
-    SkMatrix matrix = *reinterpret_cast<SkMatrix*>(transformPtr);
-    SkScalar transformValues[6];
-    if (!matrix.asAffine(transformValues)) {
-        jniThrowException(env, "java/lang/IllegalArgumentException",
-                "transform matrix has perspective. Only affine matrices are allowed.");
-        return;
-    }
-
-    FS_MATRIX transform = {transformValues[SkMatrix::kAScaleX], transformValues[SkMatrix::kASkewY],
-                           transformValues[SkMatrix::kASkewX], transformValues[SkMatrix::kAScaleY],
-                           transformValues[SkMatrix::kATransX],
-                           transformValues[SkMatrix::kATransY]};
-
-    FS_RECTF clip = {(float) clipLeft, (float) clipTop, (float) clipRight, (float) clipBottom};
-
-    FPDF_RenderPageBitmapWithMatrix(bitmap, page, &transform, &clip, renderFlags);
-
-    skBitmap.notifyPixelsChanged();
-}
-
-static const JNINativeMethod gPdfRenderer_Methods[] = {
-    {"nativeCreate", "(IJ)J", (void*) nativeOpen},
-    {"nativeClose", "(J)V", (void*) nativeClose},
-    {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount},
-    {"nativeScaleForPrinting", "(J)Z", (void*) nativeScaleForPrinting},
-    {"nativeRenderPage", "(JJJIIIIJI)V", (void*) nativeRenderPage},
-    {"nativeOpenPageAndGetSize", "(JILandroid/graphics/Point;)J", (void*) nativeOpenPageAndGetSize},
-    {"nativeClosePage", "(J)V", (void*) nativeClosePage}
-};
-
-int register_android_graphics_pdf_PdfRenderer(JNIEnv* env) {
-    int result = RegisterMethodsOrDie(
-            env, "android/graphics/pdf/PdfRenderer", gPdfRenderer_Methods,
-            NELEM(gPdfRenderer_Methods));
-
-    jclass clazz = FindClassOrDie(env, "android/graphics/Point");
-    gPointClassInfo.x = GetFieldIDOrDie(env, clazz, "x", "I");
-    gPointClassInfo.y = GetFieldIDOrDie(env, clazz, "y", "I");
-
-    return result;
-};
-
-};
diff --git a/media/java/android/media/metrics/EditingEndedEvent.java b/media/java/android/media/metrics/EditingEndedEvent.java
index 9b3477f..54496bf 100644
--- a/media/java/android/media/metrics/EditingEndedEvent.java
+++ b/media/java/android/media/metrics/EditingEndedEvent.java
@@ -199,7 +199,7 @@
     /** Input audio was edited. */
     public static final long OPERATION_TYPE_AUDIO_EDIT = 1L << 3;
 
-    /** Input video samples were writted (muxed) directly to the output file without transcoding. */
+    /** Input video samples were written (muxed) directly to the output file without transcoding. */
     public static final long OPERATION_TYPE_VIDEO_TRANSMUX = 1L << 4;
 
     /** Input audio samples were written (muxed) directly to the output file without transcoding. */
@@ -272,7 +272,8 @@
     }
 
     /**
-     * Returns the name of the library implementing the exporting operation, or {@code null} if
+     * Returns the name of the library implementing the exporting operation, for example, a Maven
+     * artifact ID like "androidx.media3.media3-transformer:1.3.0-beta01", or {@code null} if
      * unknown.
      */
     @Nullable
@@ -281,8 +282,8 @@
     }
 
     /**
-     * Returns the name of the library implementing the media muxing operation, or {@code null} if
-     * unknown.
+     * Returns the name of the library implementing the media muxing operation, for example, a Maven
+     * artifact ID like "androidx.media3.media3-muxer:1.3.0-beta01", or {@code null} if unknown.
      */
     @Nullable
     public String getMuxerName() {
diff --git a/media/java/android/media/metrics/MediaItemInfo.java b/media/java/android/media/metrics/MediaItemInfo.java
index 63dd3cc..338697f 100644
--- a/media/java/android/media/metrics/MediaItemInfo.java
+++ b/media/java/android/media/metrics/MediaItemInfo.java
@@ -92,7 +92,7 @@
                 DATA_TYPE_DEPTH,
                 DATA_TYPE_GAIN_MAP,
                 DATA_TYPE_HIGH_FRAME_RATE,
-                DATA_TYPE_CUE_POINTS,
+                DATA_TYPE_SPEED_SETTING_CUE_POINTS,
                 DATA_TYPE_GAPLESS,
                 DATA_TYPE_SPATIAL_AUDIO,
                 DATA_TYPE_HIGH_DYNAMIC_RANGE_VIDEO,
@@ -109,7 +109,10 @@
     /** The media item includes audio data. */
     public static final long DATA_TYPE_AUDIO = 1L << 2;
 
-    /** The media item includes metadata. */
+    /**
+     * The media item includes static media container metadata (for example, capture frame rate or
+     * location information).
+     */
     public static final long DATA_TYPE_METADATA = 1L << 3;
 
     /** The media item includes depth (z-distance) information. */
@@ -121,8 +124,11 @@
     /** The media item includes high frame rate video data. */
     public static final long DATA_TYPE_HIGH_FRAME_RATE = 1L << 6;
 
-    /** The media item includes time-dependent speed setting metadata. */
-    public static final long DATA_TYPE_CUE_POINTS = 1L << 7;
+    /**
+     * The media item includes time-dependent speed information (for example, slow motion cue
+     * points).
+     */
+    public static final long DATA_TYPE_SPEED_SETTING_CUE_POINTS = 1L << 7;
 
     /** The media item includes gapless audio metadata. */
     public static final long DATA_TYPE_GAPLESS = 1L << 8;
diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
index 6766afc..b5951e8 100644
--- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
+++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
@@ -40,7 +40,6 @@
 import android.sysprop.CrashRecoveryProperties;
 import android.text.TextUtils;
 import android.util.ArraySet;
-import android.util.ExceptionUtils;
 import android.util.Log;
 import android.util.Slog;
 
@@ -136,7 +135,7 @@
         }
 
         // We're disabled on all engineering devices
-        if (Build.IS_ENG) {
+        if (Build.TYPE.equals("eng")) {
             Slog.v(TAG, "Disabled because of eng build");
             return true;
         }
@@ -144,7 +143,7 @@
         // We're disabled on userdebug devices connected over USB, since that's
         // a decent signal that someone is actively trying to debug the device,
         // or that it's in a lab environment.
-        if (Build.IS_USERDEBUG && isUsbActive()) {
+        if (Build.TYPE.equals("userdebug") && isUsbActive()) {
             Slog.v(TAG, "Disabled because of active USB connection");
             return true;
         }
@@ -478,9 +477,18 @@
         }
     }
 
+    private static String getCompleteMessage(Throwable t) {
+        final StringBuilder builder = new StringBuilder();
+        builder.append(t.getMessage());
+        while ((t = t.getCause()) != null) {
+            builder.append(": ").append(t.getMessage());
+        }
+        return builder.toString();
+    }
+
     private static void logRescueException(int level, @Nullable String failedPackageName,
             Throwable t) {
-        final String msg = ExceptionUtils.getCompleteMessage(t);
+        final String msg = getCompleteMessage(t);
         EventLogTags.writeRescueFailure(level, msg);
         String failureMsg = "Failed rescue level " + levelToString(level);
         if (!TextUtils.isEmpty(failedPackageName)) {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
index d949396..621ddf7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt
@@ -557,13 +557,18 @@
         targetState = message,
         label = "Bouncer message",
         animationSpec = if (message.isUpdateAnimated) tween() else snap(),
-        modifier = modifier,
+        modifier = modifier.fillMaxWidth(),
     ) {
-        Text(
-            text = it.text,
-            color = MaterialTheme.colorScheme.onSurface,
-            style = MaterialTheme.typography.bodyLarge,
-        )
+        Box(
+            contentAlignment = Alignment.Center,
+            modifier = Modifier.fillMaxWidth(),
+        ) {
+            Text(
+                text = it.text,
+                color = MaterialTheme.colorScheme.onSurface,
+                style = MaterialTheme.typography.bodyLarge,
+            )
+        }
     }
 }
 
diff --git a/packages/SystemUI/plugin/proguard_plugins.flags b/packages/SystemUI/plugin/proguard_plugins.flags
index abac27f..23ba8d0 100644
--- a/packages/SystemUI/plugin/proguard_plugins.flags
+++ b/packages/SystemUI/plugin/proguard_plugins.flags
@@ -7,3 +7,13 @@
 -keep class com.android.systemui.log.core.** {
     *;
 }
+
+# This type is used in the plugin API boundary, so ensure the used public methods are kept.
+-keepclassmembers class androidx.constraintlayout.widget.ConstraintSet {
+    public void connect(int, int, int, int, int);
+    public void constrainWidth(int, int);
+    public void constrainHeight(int, int);
+    public int getHeight(int);
+    public int getWidth(int);
+    public void setGoneMargin(int, int, int);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagDependenciesBase.kt b/packages/SystemUI/src/com/android/systemui/flags/FlagDependenciesBase.kt
index 14fda5e..efbd59f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FlagDependenciesBase.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FlagDependenciesBase.kt
@@ -48,10 +48,14 @@
     private var unmetDependencies = emptyList<Dependency>()
 
     override fun start() {
+        if (!handler.enableDependencies) {
+            return
+        }
         defineDependencies()
         allDependencies = workingDependencies.toList()
         unmetDependencies = workingDependencies.filter { !it.isMet }
         workingDependencies.clear()
+        handler.onCollected(allDependencies)
         if (unmetDependencies.isNotEmpty()) {
             handler.warnAboutBadFlagConfiguration(all = allDependencies, unmet = unmetDependencies)
         }
@@ -106,14 +110,24 @@
 
     /** Add a dependency to the working list */
     private fun addDependency(first: FlagToken, second: FlagToken) {
-        if (!Compile.IS_DEBUG) return // `user` builds should omit all this code
+        if (!handler.enableDependencies) return
         workingDependencies.add(
             Dependency(first.name, first.isEnabled, second.name, second.isEnabled)
         )
     }
 
-    /** An interface which handles a warning about a bad flag configuration. */
+    /** An interface which handles dependency collection. */
     interface Handler {
+        /**
+         * Should FlagDependencies do anything?
+         *
+         * @return false for user builds so that we skip this overhead.
+         */
+        val enableDependencies: Boolean
+            get() = Compile.IS_DEBUG
+        /** Handle the complete list of dependencies. */
+        fun onCollected(all: List<Dependency>) {}
+        /** Handle a bad flag configuration. */
         fun warnAboutBadFlagConfiguration(all: List<Dependency>, unmet: List<Dependency>)
     }
 }
@@ -133,7 +147,7 @@
         all: List<FlagDependenciesBase.Dependency>,
         unmet: List<FlagDependenciesBase.Dependency>
     ) {
-        val title = "Invalid flag dependencies: ${unmet.size} of ${all.size}"
+        val title = "Invalid flag dependencies: ${unmet.size}"
         val details = unmet.joinToString("\n") { it.shortUnmetString() }
         Log.e("FlagDependencies", "$title:\n$details")
         val channel = NotificationChannel("FLAGS", "Flags", NotificationManager.IMPORTANCE_DEFAULT)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
index 94cc7e9..f2b8482 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
@@ -76,6 +76,6 @@
         // Show/hide the feedback icon
         controller.setFeedbackIcon(mAssistantFeedbackController.getFeedbackIcon(entry))
         // Show the "alerted" bell icon
-        controller.setLastAudiblyAlertedMs(entry.lastAudiblyAlertedMs)
+        controller.setLastAudibleMs(entry.lastAudiblyAlertedMs)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/LaunchFullScreenIntentProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/LaunchFullScreenIntentProvider.kt
index 74ff78e..e8c59f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/LaunchFullScreenIntentProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/LaunchFullScreenIntentProvider.kt
@@ -33,7 +33,7 @@
     private val listeners = ListenerSet<Listener>()
 
     /**
-     * Registers a listener with this provider. These listeners will be alerted whenever a full
+     * Registers a listener with this provider. These listeners will be updated whenever a full
      * screen intent should be launched for a notification entry.
      */
     fun registerListener(listener: Listener) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt
index 5ee94ba..82b7e14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt
@@ -29,10 +29,10 @@
     fun setSystemExpanded(systemExpanded: Boolean)
 
     /**
-     * Sets the timestamp that the notification was last audibly alerted, which the row uses to
+     * Sets the timestamp that the notification was last audible, which the row uses to
      * show a bell icon in the header which indicates to the user which notification made a noise.
      */
-    fun setLastAudiblyAlertedMs(lastAudiblyAlertedMs: Long)
+    fun setLastAudibleMs(lastAudibleMs: Long)
 
     /** Shows the given feedback icon, or hides the icon if null. */
     fun setFeedbackIcon(icon: FeedbackIcon?)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 0afdefa..5614f3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -431,8 +431,8 @@
     }
 
     @Override
-    public void setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) {
-        mView.setLastAudiblyAlertedMs(lastAudiblyAlertedMs);
+    public void setLastAudibleMs(long lastAudibleMs) {
+        mView.setLastAudiblyAlertedMs(lastAudibleMs);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt
index 668b143..ca5ea3b 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt
@@ -45,7 +45,6 @@
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
-import java.lang.IllegalArgumentException
 import java.util.Optional
 import java.util.concurrent.Executor
 import java.util.function.Consumer
@@ -71,7 +70,7 @@
     private val displayTracker: DisplayTracker,
     @Background private val applicationScope: CoroutineScope,
     @Main private val executor: Executor,
-    @Assisted private val displaySelector: Sequence<DisplayInfo>.() -> DisplayInfo?,
+    @Assisted private val displaySelector: List<DisplayInfo>.() -> DisplayInfo?,
     @Assisted private val lightRevealEffectFactory: (rotation: Int) -> LightRevealEffect,
     @Assisted private val overlayContainerName: String
 ) {
@@ -84,13 +83,11 @@
     private var scrimView: LightRevealScrim? = null
 
     private val rotationWatcher = RotationWatcher()
-    private val internalDisplayInfos: Sequence<DisplayInfo>
-        get() =
-            displayManager
-                .getDisplays(DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)
-                .asSequence()
-                .map { DisplayInfo().apply { it.getDisplayInfo(this) } }
-                .filter { it.type == Display.TYPE_INTERNAL }
+    private val internalDisplayInfos: List<DisplayInfo> =
+        displayManager
+            .getDisplays(DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)
+            .map { DisplayInfo().apply { it.getDisplayInfo(this) } }
+            .filter { it.type == Display.TYPE_INTERNAL }
 
     var isTouchBlocked: Boolean = false
         set(value) {
@@ -252,7 +249,7 @@
     @AssistedFactory
     interface Factory {
         fun create(
-            displaySelector: Sequence<DisplayInfo>.() -> DisplayInfo?,
+            displaySelector: List<DisplayInfo>.() -> DisplayInfo?,
             effectFactory: (rotation: Int) -> LightRevealEffect,
             overlayContainerName: String
         ): FullscreenLightRevealAnimationController
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java
index 50d1547..e10d1cb 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Events.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java
@@ -60,6 +60,7 @@
     public static final int EVENT_DISMISS_USB_OVERHEAT_ALARM = 20; // (reason|int) (keyguard|bool)
     public static final int EVENT_ODI_CAPTIONS_CLICK = 21;
     public static final int EVENT_ODI_CAPTIONS_TOOLTIP_CLICK = 22;
+    public static final int EVENT_SLIDER_TOUCH_TRACKING = 23; // (tracking|bool)
 
     private static final String[] EVENT_TAGS = {
             "show_dialog",
@@ -84,7 +85,8 @@
             "show_usb_overheat_alarm",
             "dismiss_usb_overheat_alarm",
             "odi_captions_click",
-            "odi_captions_tooltip_click"
+            "odi_captions_tooltip_click",
+            "slider_touch_tracking"
     };
 
     public static final int DISMISS_REASON_UNKNOWN = 0;
@@ -234,6 +236,10 @@
         VOLUME_DIALOG_SLIDER(150),
         @UiEvent(doc = "The audio stream was set to silent via slider")
         VOLUME_DIALOG_SLIDER_TO_ZERO(151),
+        @UiEvent(doc = "The right-most slider started tracking touch")
+        VOLUME_DIALOG_SLIDER_STARTED_TRACKING_TOUCH(1620),
+        @UiEvent(doc = "The right-most slider stopped tracking touch")
+        VOLUME_DIALOG_SLIDER_STOPPED_TRACKING_TOUCH(1621),
         @UiEvent(doc = "ODI captions was clicked")
         VOLUME_DIALOG_ODI_CAPTIONS_CLICKED(1503),
         @UiEvent(doc = "ODI captions tooltip dismiss was clicked")
@@ -491,6 +497,15 @@
                             .append(" keyguard=").append(keyguard);
                 }
                 break;
+            case EVENT_SLIDER_TOUCH_TRACKING:
+                final boolean startedTracking = (boolean) list[0];
+                final VolumeDialogEvent event;
+                if (startedTracking) {
+                    event = VolumeDialogEvent.VOLUME_DIALOG_SLIDER_STARTED_TRACKING_TOUCH;
+                } else {
+                    event = VolumeDialogEvent.VOLUME_DIALOG_SLIDER_STOPPED_TRACKING_TOUCH;
+                }
+                sUiEventLogger.log(event);
             default:
                 sb.append(Arrays.asList(list));
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 90c5c62..4045630 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -2518,6 +2518,7 @@
         @Override
         public void onStartTrackingTouch(SeekBar seekBar) {
             if (D.BUG) Log.d(TAG, "onStartTrackingTouch"+ " " + mRow.stream);
+            Events.writeEvent(Events.EVENT_SLIDER_TOUCH_TRACKING, /* startedTracking= */true);
             if (mRow.mHapticPlugin != null) {
                 mRow.mHapticPlugin.onStartTrackingTouch(seekBar);
             }
@@ -2528,6 +2529,7 @@
         @Override
         public void onStopTrackingTouch(SeekBar seekBar) {
             if (D.BUG) Log.d(TAG, "onStopTrackingTouch"+ " " + mRow.stream);
+            Events.writeEvent(Events.EVENT_SLIDER_TOUCH_TRACKING, /* startedTracking= */false);
             if (mRow.mHapticPlugin != null) {
                 mRow.mHapticPlugin.onStopTrackingTouch(seekBar);
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt
index 936aa8b..91da88e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.flags
 
 import android.testing.AndroidTestingRunner
+import android.util.Log
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import java.io.PrintWriter
@@ -41,14 +42,21 @@
         FlagDependencies(TestFeatureFlags(teamfood = teamfood), TestHandler())
 
     private class TestHandler : FlagDependenciesBase.Handler {
+        override val enableDependencies: Boolean
+            get() = true
         override fun warnAboutBadFlagConfiguration(
             all: List<FlagDependenciesBase.Dependency>,
             unmet: List<FlagDependenciesBase.Dependency>
         ) {
-            val title = "${unmet.size} invalid of ${all.size} flag dependencies"
+            val title = "Invalid flag dependencies: ${unmet.size}"
             val details = unmet.joinToString("\n")
             fail("$title:\n$details")
         }
+
+        override fun onCollected(all: List<FlagDependenciesBase.Dependency>) {
+            Log.d("FlagDependencies", "All: ${all.size}")
+            all.forEach { Log.d("FlagDependencies", "  $it") }
+        }
     }
 
     private class TestFeatureFlags(val teamfood: Boolean) : FeatureFlagsClassic {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
index 3f3de00..fa669fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
@@ -105,7 +105,7 @@
     @Test
     fun testSetLastAudiblyAlerted() {
         afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
-        verify(controller1).setLastAudiblyAlertedMs(eq(17.toLong()))
+        verify(controller1).setLastAudibleMs(eq(17.toLong()))
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 25a0bc4..1a3cb87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -58,6 +58,7 @@
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.ImageButton;
+import android.widget.SeekBar;
 
 import androidx.test.core.view.MotionEventBuilder;
 import androidx.test.filters.SmallTest;
@@ -111,6 +112,7 @@
     View mDrawerVibrate;
     View mDrawerMute;
     View mDrawerNormal;
+    ViewGroup mDialogRowsView;
     CaptionsToggleImageButton mODICaptionsIcon;
 
     private TestableLooper mTestableLooper;
@@ -222,6 +224,8 @@
         }
         mODICaptionsIcon = mDialog.getDialogView().findViewById(R.id.odi_captions_icon);
 
+        mDialogRowsView = mDialog.getDialogView().findViewById(R.id.volume_dialog_rows);
+
         Prefs.putInt(mContext,
                 Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT,
                 VolumePrefs.SHOW_RINGER_TOAST_COUNT + 1);
@@ -671,6 +675,45 @@
     }
 
     @Test
+    public void volumeSliderTracksTouch_logsStartAndStopTrackingUiEvents() {
+        UiEventLoggerFake logger = new UiEventLoggerFake();
+        Events.sUiEventLogger = logger;
+
+        mDialog.show(SHOW_REASON_UNKNOWN);
+        mTestableLooper.processAllMessages();
+
+        MotionEvent down = MotionEventBuilder.newBuilder()
+                .setAction(MotionEvent.ACTION_DOWN).build();
+        MotionEvent up = MotionEventBuilder.newBuilder().setAction(MotionEvent.ACTION_UP).build();
+
+        SeekBar slider =
+                mDialogRowsView.getChildAt(0).findViewById(R.id.volume_row_slider);
+        slider.onTouchEvent(down);
+        slider.onTouchEvent(up);
+        mTestableLooper.moveTimeForward(300);
+        mTestableLooper.processAllMessages();
+
+        boolean foundStartTrackingTouch = false;
+        boolean foundStopTrackingTouch = false;
+        for (UiEventLoggerFake.FakeUiEvent event : logger.getLogs()) {
+            if (event.eventId
+                    == Events.VolumeDialogEvent.VOLUME_DIALOG_SLIDER_STARTED_TRACKING_TOUCH.getId()
+            ) {
+                foundStartTrackingTouch = true;
+            }
+            if (event.eventId
+                    == Events.VolumeDialogEvent.VOLUME_DIALOG_SLIDER_STOPPED_TRACKING_TOUCH.getId()
+            ) {
+                foundStopTrackingTouch = true;
+            }
+        }
+        Assert.assertTrue("Did not log the event of start tracking touch.",
+                foundStartTrackingTouch);
+        Assert.assertTrue("Did not log the event of stop tracking touch.",
+                foundStopTrackingTouch);
+    }
+
+    @Test
     public void turnOnDnD_volumeSliderIconChangesToDnd() {
         State state = createShellState();
         state.zenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
index b62b3a2..353d970 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
@@ -46,6 +46,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.uiautomator.UiDevice;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.systemui.broadcast.FakeBroadcastDispatcher;
 import com.android.systemui.flags.SceneContainerRule;
 
@@ -170,6 +171,7 @@
 
     @Before
     public void SysuiSetup() throws Exception {
+        ProtoLog.REQUIRE_PROTOLOGTOOL = false;
         mSysuiDependency = new SysuiTestDependency(mContext, shouldFailOnLeakedReceiver());
         mDependency = mSysuiDependency.install();
         // TODO(b/292141694): build out Ravenwood support for Instrumentation
diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
index c134a4c..d8a94d8 100644
--- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
+++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
@@ -1204,23 +1204,26 @@
                 List<Pair<CameraCharacteristics.Key, Object>> entries =
                         mAdvancedExtender.getAvailableCharacteristicsKeyValues();
 
-                if ((entries != null) && !entries.isEmpty()) {
-                    CameraMetadataNative ret = new CameraMetadataNative();
-                    long vendorId = mMetadataVendorIdMap.containsKey(cameraId)
-                            ? mMetadataVendorIdMap.get(cameraId) : Long.MAX_VALUE;
-                    ret.setVendorId(vendorId);
-                    int[] characteristicsKeyTags = new int[entries.size()];
-                    int i = 0;
-                    for (Pair<CameraCharacteristics.Key, Object> entry : entries) {
-                        int tag = CameraMetadataNative.getTag(entry.first.getName(), vendorId);
-                        characteristicsKeyTags[i++] = tag;
-                        ret.set(entry.first, entry.second);
-                    }
-                    ret.set(CameraCharacteristics.REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
-                            characteristicsKeyTags);
-
-                    return ret;
+                if (entries == null || entries.isEmpty()) {
+                    throw new RuntimeException("A valid set of key/value pairs are required that "
+                            + "are supported by the extension.");
                 }
+
+                CameraMetadataNative ret = new CameraMetadataNative();
+                long vendorId = mMetadataVendorIdMap.containsKey(cameraId)
+                        ? mMetadataVendorIdMap.get(cameraId) : Long.MAX_VALUE;
+                ret.setVendorId(vendorId);
+                int[] characteristicsKeyTags = new int[entries.size()];
+                int i = 0;
+                for (Pair<CameraCharacteristics.Key, Object> entry : entries) {
+                    int tag = CameraMetadataNative.getTag(entry.first.getName(), vendorId);
+                    characteristicsKeyTags[i++] = tag;
+                    ret.set(entry.first, entry.second);
+                }
+                ret.set(CameraCharacteristics.REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
+                        characteristicsKeyTags);
+
+                return ret;
             }
 
             return null;
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 1ca3923..d5863a7 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1638,21 +1638,10 @@
                     // SDR brightness is unchanged, so animate quickly as this is only impacting
                     // a likely minority amount of display content
                     // ie, the highlights of an HDR video or UltraHDR image
+                    // Ideally we'd do this as fast as possible (ie, skip the animation entirely),
+                    // but this requires display support and would need an entry in the
+                    // display configuration. For now just do the fast animation
                     slowChange = false;
-
-                    // Going from HDR to no HDR; visually this should be a "no-op" anyway
-                    // as the remaining SDR content's brightness should be holding steady
-                    // due to the sdr brightness not shifting
-                    if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, animateValue)) {
-                        skipAnimation = true;
-                    }
-
-                    // Going from no HDR to HDR; visually this is a significant scene change
-                    // and the animation just prevents advanced clients from doing their own
-                    // handling of enter/exit animations if they would like to do such a thing
-                    if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, currentBrightness)) {
-                        skipAnimation = true;
-                    }
                 }
                 if (skipAnimation) {
                     animateScreenBrightness(animateValue, sdrAnimateValue,
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 8cb5cef..f97f6d2 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -105,6 +105,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -151,7 +152,9 @@
     private boolean mHasFeatureLeanback;
     private ActivityManagerInternal mActivityManagerInternal;
     private UsageStatsManagerInternal mUsageStatsManagerInternal;
-    private final Set<Integer> mUserEngagingSessions = new HashSet<>();
+
+    /* Maps uid with all user engaging session tokens associated to it */
+    private final Map<Integer, Set<MediaSession.Token>> mUserEngagingSessions = new HashMap<>();
 
     // The FullUserRecord of the current users. (i.e. The foreground user that isn't a profile)
     // It's always not null after the MediaSessionService is started.
@@ -615,32 +618,36 @@
     }
 
     private void reportMediaInteractionEvent(MediaSessionRecordImpl record, boolean userEngaged) {
-           if (!android.app.usage.Flags.userInteractionTypeApi()) {
-                return;
-            }
+        if (!android.app.usage.Flags.userInteractionTypeApi()
+                || !(record instanceof MediaSessionRecord)) {
+            return;
+        }
 
-            String packageName = record.getPackageName();
-            int sessionUid = record.getUid();
-            String actionToLog = null;
-            if (userEngaged) {
-                if (!mUserEngagingSessions.contains(sessionUid)) {
-                    actionToLog = "start";
-                }
-                mUserEngagingSessions.add(sessionUid);
-            } else {
-                if (mUserEngagingSessions.contains(sessionUid)) {
-                    actionToLog = "stop";
-                }
+        String packageName = record.getPackageName();
+        int sessionUid = record.getUid();
+        String actionToLog = null;
+        MediaSession.Token token = ((MediaSessionRecord) record).getSessionToken();
+        if (userEngaged) {
+            if (!mUserEngagingSessions.containsKey(sessionUid)) {
+                mUserEngagingSessions.put(sessionUid, new HashSet<>());
+                actionToLog = "start";
+            }
+            mUserEngagingSessions.get(sessionUid).add(token);
+        } else if (mUserEngagingSessions.containsKey(sessionUid)) {
+            mUserEngagingSessions.get(sessionUid).remove(token);
+            if (mUserEngagingSessions.get(sessionUid).isEmpty()) {
+                actionToLog = "stop";
                 mUserEngagingSessions.remove(sessionUid);
             }
+        }
 
-            if (actionToLog != null) {
-                PersistableBundle extras = new PersistableBundle();
-                extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, "android.media");
-                extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, actionToLog);
-                mUsageStatsManagerInternal.reportUserInteractionEvent(
-                        packageName, record.getUserId(), extras);
-            }
+        if (actionToLog != null) {
+            PersistableBundle extras = new PersistableBundle();
+            extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, "android.media");
+            extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, actionToLog);
+            mUsageStatsManagerInternal.reportUserInteractionEvent(
+                    packageName, record.getUserId(), extras);
+        }
     }
 
     void tempAllowlistTargetPkgIfPossible(int targetUid, String targetPackage,
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d751186..53ae60b 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1879,11 +1879,11 @@
                                 true, record.getUserId(), REASON_TIMEOUT, null);
                         // If cancellation will be prevented due to lifetime extension, we send an
                         // update to system UI.
+                        final int packageImportance = getPackageImportanceWithIdentity(
+                                record.getSbn().getPackageName());
                         synchronized (mNotificationLock) {
                             maybeNotifySystemUiListenerLifetimeExtendedLocked(record,
-                                    record.getSbn().getPackageName(),
-                                    mActivityManager.getPackageImportance(
-                                            record.getSbn().getPackageName()));
+                                    record.getSbn().getPackageName(), packageImportance);
                         }
                     } else {
                         cancelNotification(record.getSbn().getUid(),
@@ -3852,7 +3852,7 @@
                 // If cancellation will be prevented due to lifetime extension, we send an update to
                 // system UI.
                 NotificationRecord record = null;
-                final int packageImportance = mActivityManager.getPackageImportance(pkg);
+                final int packageImportance = getPackageImportanceWithIdentity(pkg);
                 synchronized (mNotificationLock) {
                     record = findNotificationLocked(pkg, tag, id, userId);
                     maybeNotifySystemUiListenerLifetimeExtendedLocked(record, pkg,
@@ -3877,10 +3877,9 @@
                         pkg, null, 0, FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB
                                 | FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY,
                         userId, REASON_APP_CANCEL_ALL);
+                final int packageImportance = getPackageImportanceWithIdentity(pkg);
                 // If cancellation will be prevented due to lifetime extension, we send updates
                 // to system UI.
-                // In this case, we need to hold the lock to access these lists.
-                final int packageImportance = mActivityManager.getPackageImportance(pkg);
                 synchronized (mNotificationLock) {
                     notifySystemUiListenerLifetimeExtendedListLocked(mNotificationList,
                             packageImportance);
@@ -5029,7 +5028,7 @@
                     pkg = info.component.getPackageName();
                 }
                 if (lifetimeExtensionRefactor()) {
-                    packageImportance = mActivityManager.getPackageImportance(pkg);
+                    packageImportance = getPackageImportanceWithIdentity(pkg);
                 } else {
                     packageImportance = IMPORTANCE_NONE;
                 }
@@ -5348,7 +5347,7 @@
             final int packageImportance;
             try {
                 if (lifetimeExtensionRefactor()) {
-                    packageImportance = mActivityManager.getPackageImportance(pkg);
+                    packageImportance = getPackageImportanceWithIdentity(pkg);
                 } else {
                     packageImportance = IMPORTANCE_NONE;
                 }
@@ -7609,14 +7608,9 @@
             }
         }
 
-        // Need escalated privileges to get package importance
-        final long token = Binder.clearCallingIdentity();
-        boolean isAppForeground;
-        try {
-            isAppForeground = mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
+        // Need escalated privileges to get package importance.
+        final int packageImportance = getPackageImportanceWithIdentity(pkg);
+        boolean isAppForeground = packageImportance == IMPORTANCE_FOREGROUND;
         mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground, tracker));
         return true;
     }
@@ -7944,9 +7938,9 @@
                         NotificationRecord r = mNotificationsByKey.get(key);
                         packageName = r != null ? r.getSbn().getPackageName() : null;
                     }
+                    final int packageImportance = getPackageImportanceWithIdentity(packageName);
                     boolean isAppForeground = packageName != null
-                            && mActivityManager.getPackageImportance(packageName)
-                            == IMPORTANCE_FOREGROUND;
+                            && packageImportance == IMPORTANCE_FOREGROUND;
                     synchronized (mNotificationLock) {
                         NotificationRecord r = mNotificationsByKey.get(key);
                         if (r != null) {
@@ -11867,6 +11861,18 @@
         }
     }
 
+    @FlaggedApi(FLAG_LIFETIME_EXTENSION_REFACTOR)
+    private int getPackageImportanceWithIdentity(String pkg) {
+        final long token = Binder.clearCallingIdentity();
+        final int packageImportance;
+        try {
+            packageImportance = mActivityManager.getPackageImportance(pkg);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return packageImportance;
+    }
+
     public class NotificationListeners extends ManagedServices {
         static final String TAG_ENABLED_NOTIFICATION_LISTENERS = "enabled_listeners";
         static final String TAG_REQUESTED_LISTENERS = "request_listeners";
diff --git a/services/core/java/com/android/server/selinux/OWNERS b/services/core/java/com/android/server/selinux/OWNERS
index 6ca4da2..4cf2066 100644
--- a/services/core/java/com/android/server/selinux/OWNERS
+++ b/services/core/java/com/android/server/selinux/OWNERS
@@ -1,3 +1,4 @@
 # Bug component: 1117393
 
 sandrom@google.com
+melisacz@google.com
diff --git a/services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java b/services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java
index 0219645..03822aa 100644
--- a/services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java
+++ b/services/core/java/com/android/server/selinux/SelinuxAuditLogsCollector.java
@@ -88,7 +88,7 @@
             if (eventTime.isAfter(latestTimestamp)) {
                 latestTimestamp = eventTime;
             }
-            if (eventTime.isBefore(mLastWrite)) {
+            if (eventTime.compareTo(mLastWrite) <= 0) {
                 continue;
             }
             Object eventData = event.getData();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b3a8b78..c36df8d 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3545,6 +3545,20 @@
                 mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(resultGrants,
                         resultTo.getUriPermissionsLocked());
             }
+            IBinder callerToken = new Binder();
+            if (android.security.Flags.contentUriPermissionApis()) {
+                try {
+                    resultTo.computeCallerInfo(callerToken, intent, this.getUid(),
+                            mAtmService.getPackageManager().getNameForUid(this.getUid()),
+                            /* isShareIdentityEnabled */ false);
+                    // Result callers cannot share their identity via
+                    // {@link ActivityOptions#setShareIdentityEnabled(boolean)} since
+                    // {@link android.app.Activity#setResult} doesn't have a
+                    // {@link android.os.Bundle}.
+                } catch (RemoteException e) {
+                    throw new RuntimeException(e);
+                }
+            }
             if (mForceSendResultForMediaProjection || resultTo.isState(RESUMED)) {
                 // Sending the result to the resultTo activity asynchronously to prevent the
                 // resultTo activity getting results before this Activity paused.
@@ -3552,12 +3566,13 @@
                 mAtmService.mH.post(() -> {
                     synchronized (mAtmService.mGlobalLock) {
                         resultToActivity.sendResult(this.getUid(), resultWho, requestCode,
-                                resultCode, resultData, resultGrants,
+                                resultCode, resultData, callerToken, resultGrants,
                                 mForceSendResultForMediaProjection);
                     }
                 });
             } else {
-                resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData);
+                resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData,
+                        callerToken);
             }
             resultTo = null;
         } else if (DEBUG_RESULTS) {
@@ -4841,9 +4856,9 @@
 
     void addResultLocked(ActivityRecord from, String resultWho,
             int requestCode, int resultCode,
-            Intent resultData) {
+            Intent resultData, IBinder callerToken) {
         ActivityResult r = new ActivityResult(from, resultWho,
-                requestCode, resultCode, resultData);
+                requestCode, resultCode, resultData, callerToken);
         if (results == null) {
             results = new ArrayList<ResultInfo>();
         }
@@ -4869,13 +4884,27 @@
     }
 
     void sendResult(int callingUid, String resultWho, int requestCode, int resultCode,
-            Intent data, NeededUriGrants dataGrants) {
-        sendResult(callingUid, resultWho, requestCode, resultCode, data, dataGrants,
+            Intent data, IBinder callerToken, NeededUriGrants dataGrants) {
+        sendResult(callingUid, resultWho, requestCode, resultCode, data, callerToken, dataGrants,
                 false /* forceSendForMediaProjection */);
     }
 
     void sendResult(int callingUid, String resultWho, int requestCode, int resultCode,
-            Intent data, NeededUriGrants dataGrants, boolean forceSendForMediaProjection) {
+            Intent data, IBinder callerToken, NeededUriGrants dataGrants,
+            boolean forceSendForMediaProjection) {
+        if (android.security.Flags.contentUriPermissionApis()
+                && !mCallerState.hasCaller(callerToken)) {
+            try {
+                computeCallerInfo(callerToken, data, callingUid,
+                        mAtmService.getPackageManager().getNameForUid(callingUid),
+                        false /* isShareIdentityEnabled */);
+                // Result callers cannot share their identity via
+                // {@link ActivityOptions#setShareIdentityEnabled(boolean)} since
+                // {@link android.app.Activity#setResult} doesn't have a {@link android.os.Bundle}.
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
         if (callingUid > 0) {
             mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(dataGrants,
                     getUriPermissionsLocked());
@@ -4891,7 +4920,7 @@
         if (isState(RESUMED) && attachedToProcess()) {
             try {
                 final ArrayList<ResultInfo> list = new ArrayList<>();
-                list.add(new ResultInfo(resultWho, requestCode, resultCode, data));
+                list.add(new ResultInfo(resultWho, requestCode, resultCode, data, callerToken));
                 mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
                         ActivityResultItem.obtain(token, list));
                 return;
@@ -4905,7 +4934,8 @@
                 STOPPING, STOPPED)) {
             // Build result to be returned immediately.
             final ActivityResultItem activityResultItem = ActivityResultItem.obtain(
-                    token, List.of(new ResultInfo(resultWho, requestCode, resultCode, data)));
+                    token, List.of(new ResultInfo(resultWho, requestCode, resultCode, data,
+                            callerToken)));
             // When the activity result is delivered, the activity will transition to RESUMED.
             // Since the activity is only resumed so the result can be immediately delivered,
             // return it to its original lifecycle state.
@@ -4929,7 +4959,7 @@
             return;
         }
 
-        addResultLocked(null /* from */, resultWho, requestCode, resultCode, data);
+        addResultLocked(null /* from */, resultWho, requestCode, resultCode, data, callerToken);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/ActivityResult.java b/services/core/java/com/android/server/wm/ActivityResult.java
index f2510de..c5c51b5 100644
--- a/services/core/java/com/android/server/wm/ActivityResult.java
+++ b/services/core/java/com/android/server/wm/ActivityResult.java
@@ -18,16 +18,17 @@
 
 import android.app.ResultInfo;
 import android.content.Intent;
+import android.os.IBinder;
 
 /**
  * Pending result information to send back to an activity.
  */
 final class ActivityResult extends ResultInfo {
     final ActivityRecord mFrom;
-    
+
     public ActivityResult(ActivityRecord from, String resultWho,
-            int requestCode, int resultCode, Intent data) {
-        super(resultWho, requestCode, resultCode, data);
+            int requestCode, int resultCode, Intent data, IBinder callerToken) {
+        super(resultWho, requestCode, resultCode, data, callerToken);
         mFrom = from;
     }
 }
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 65d01efc..cfd04950 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1103,7 +1103,7 @@
         if (err != START_SUCCESS) {
             if (resultRecord != null) {
                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
-                        null /* data */, null /* dataGrants */);
+                        null /* data */, null /* callerToken */, null /* dataGrants */);
             }
             SafeActivityOptions.abort(options);
             return err;
@@ -1128,7 +1128,8 @@
                         .filterAppAccess(targetPackageName, callingUid, userId)) {
                     if (resultRecord != null) {
                         resultRecord.sendResult(INVALID_UID, resultWho, requestCode,
-                                RESULT_CANCELED, null /* data */, null /* dataGrants */);
+                                RESULT_CANCELED, null /* data */, null /* callerToken */,
+                                null /* dataGrants */);
                     }
                     SafeActivityOptions.abort(options);
                     return ActivityManager.START_CLASS_NOT_FOUND;
@@ -1216,7 +1217,7 @@
         if (abort) {
             if (resultRecord != null) {
                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
-                        null /* data */, null /* dataGrants */);
+                        null /* data */, null /* callerToken */, null /* dataGrants */);
             }
             // We pretend to the caller that it was really started, but they will just get a
             // cancel result.
@@ -1380,7 +1381,7 @@
         int requestCode = r.requestCode;
         if (resultRecord != null) {
             resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
-                    null /* data */, null /* dataGrants */);
+                    null /* data */, null /* callerToken */, null /* dataGrants */);
         }
         // We pretend to the caller that it was really started to make it backward compatible, but
         // they will just get a cancel result.
@@ -1727,7 +1728,7 @@
         if (startResult != START_SUCCESS) {
             if (r.resultTo != null) {
                 r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED,
-                        null /* data */, null /* dataGrants */);
+                        null /* data */, null /* callerToken */, null /* dataGrants */);
             }
             return startResult;
         }
@@ -2226,7 +2227,7 @@
         if (mStartActivity.resultTo != null) {
             mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
                     mStartActivity.requestCode, RESULT_CANCELED,
-                    null /* data */, null /* dataGrants */);
+                    null /* data */, null /* callerToken */, null /* dataGrants */);
             mStartActivity.resultTo = null;
         }
 
@@ -2607,7 +2608,7 @@
             Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
             mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
                     mStartActivity.requestCode, RESULT_CANCELED,
-                    null /* data */, null /* dataGrants */);
+                    null /* data */, null /* callerToken */, null /* dataGrants */);
             mStartActivity.resultTo = null;
         }
     }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 445295a..52fdfda 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6334,7 +6334,8 @@
             final NeededUriGrants dataGrants = collectGrants(data, r);
 
             synchronized (mGlobalLock) {
-                r.sendResult(callingUid, resultWho, requestCode, resultCode, data, dataGrants);
+                r.sendResult(callingUid, resultWho, requestCode, resultCode, data, new Binder(),
+                        dataGrants);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 49df396..09f5eda 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1118,7 +1118,8 @@
                 || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
             if (resultRecord != null) {
                 resultRecord.sendResult(INVALID_UID, resultWho, requestCode,
-                        Activity.RESULT_CANCELED, null /* data */, null /* dataGrants */);
+                        Activity.RESULT_CANCELED, null /* data */, null /* callerToken */,
+                        null /* dataGrants */);
             }
             final String msg;
             if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index 57b8632..807774f 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -725,8 +725,8 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_FAST_HDR_TRANSITIONS)
     public void testDisplayBrightnessHdr_SkipAnimationOnHdrAppearance() {
+        when(mDisplayManagerFlagsMock.isFastHdrTransitionsEnabled()).thenReturn(true);
         Settings.System.putInt(mContext.getContentResolver(),
                 Settings.System.SCREEN_BRIGHTNESS_MODE,
                 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
@@ -757,12 +757,12 @@
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_FAST_HDR_TRANSITIONS)
     public void testDisplayBrightnessHdr_SkipAnimationOnHdrRemoval() {
+        when(mDisplayManagerFlagsMock.isFastHdrTransitionsEnabled()).thenReturn(true);
         Settings.System.putInt(mContext.getContentResolver(),
                 Settings.System.SCREEN_BRIGHTNESS_MODE,
                 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
@@ -797,7 +797,7 @@
         advanceTime(1); // Run updatePowerState
 
         verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness),
-                eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false));
+                eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 31d6fa3..67c528c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -769,7 +769,8 @@
         activity.setState(STOPPED, "Testing");
 
         ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(task).build();
-        activity.addResultLocked(topActivity, "resultWho", 0, 0, new Intent());
+        activity.addResultLocked(topActivity, "resultWho", 0, 0, new Intent(),
+                /* callerToken */ null);
         topActivity.finishing = true;
 
         doReturn(TASK_FRAGMENT_VISIBILITY_VISIBLE).when(task).getVisibility(null);
@@ -1298,8 +1299,8 @@
         targetActivity.finishIfPossible(0, new Intent(), null, "test", false /* oomAdj */);
         waitUntilHandlersIdle();
 
-        verify(resultToActivity).sendResult(anyInt(), eq(null), anyInt(), anyInt(), any(), eq(null),
-                anyBoolean());
+        verify(resultToActivity).sendResult(anyInt(), eq(null), anyInt(), anyInt(), any(), any(),
+                eq(null), anyBoolean());
     }
 
     /**
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index d5eeaa7..6132ee3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -1857,7 +1857,7 @@
         startActivityInner(starter, targetRecord, sourceRecord, null /* options */,
                 null /* inTask */, null /* inTaskFragment */);
         verify(sourceRecord).sendResult(anyInt(), any(), anyInt(), eq(RESULT_CANCELED), any(),
-                any());
+                any(), any());
     }
 
     @Test