Merge "Disabled two-finger dragging on TouchpadDebugView" into main
diff --git a/core/api/current.txt b/core/api/current.txt
index 1667f2e..5d134c6 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -33228,6 +33228,7 @@
   }
 
   public interface IBinder {
+    method @FlaggedApi("android.os.binder_frozen_state_change_callback") public default void addFrozenStateChangeCallback(@NonNull android.os.IBinder.FrozenStateChangeCallback) throws android.os.RemoteException;
     method public void dump(@NonNull java.io.FileDescriptor, @Nullable String[]) throws android.os.RemoteException;
     method public void dumpAsync(@NonNull java.io.FileDescriptor, @Nullable String[]) throws android.os.RemoteException;
     method @Nullable public String getInterfaceDescriptor() throws android.os.RemoteException;
@@ -33236,6 +33237,7 @@
     method public void linkToDeath(@NonNull android.os.IBinder.DeathRecipient, int) throws android.os.RemoteException;
     method public boolean pingBinder();
     method @Nullable public android.os.IInterface queryLocalInterface(@NonNull String);
+    method @FlaggedApi("android.os.binder_frozen_state_change_callback") public default boolean removeFrozenStateChangeCallback(@NonNull android.os.IBinder.FrozenStateChangeCallback);
     method public boolean transact(int, @NonNull android.os.Parcel, @Nullable android.os.Parcel, int) throws android.os.RemoteException;
     method public boolean unlinkToDeath(@NonNull android.os.IBinder.DeathRecipient, int);
     field public static final int DUMP_TRANSACTION = 1598311760; // 0x5f444d50
@@ -33253,6 +33255,12 @@
     method public default void binderDied(@NonNull android.os.IBinder);
   }
 
+  @FlaggedApi("android.os.binder_frozen_state_change_callback") public static interface IBinder.FrozenStateChangeCallback {
+    method public void onFrozenStateChanged(@NonNull android.os.IBinder, int);
+    field public static final int STATE_FROZEN = 0; // 0x0
+    field public static final int STATE_UNFROZEN = 1; // 0x1
+  }
+
   public interface IInterface {
     method public android.os.IBinder asBinder();
   }
@@ -44070,7 +44078,7 @@
   }
 
   public static final class CarrierConfigManager.Gps {
-    field @FlaggedApi("android.location.flags.enable_ni_supl_message_injection_by_carrier_config") public static final String KEY_ENABLE_NI_SUPL_MESSAGE_INJECTION_BOOL = "gps.enable_ni_supl_message_injection_bool";
+    field @FlaggedApi("android.location.flags.enable_ni_supl_message_injection_by_carrier_config_bugfix") public static final String KEY_ENABLE_NI_SUPL_MESSAGE_INJECTION_BOOL = "gps.enable_ni_supl_message_injection_bool";
     field public static final String KEY_PERSIST_LPP_MODE_BOOL = "gps.persist_lpp_mode_bool";
     field public static final String KEY_PREFIX = "gps.";
   }
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index c22f46c..80546cd 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -650,13 +650,13 @@
      * weakly referenced by JNI so the strong references here are needed to keep the callbacks
      * around until the proxy is GC'ed.
      */
-    private List<IFrozenStateChangeCallback> mFrozenStateChangeCallbacks =
+    private List<FrozenStateChangeCallback> mFrozenStateChangeCallbacks =
             Collections.synchronizedList(new ArrayList<>());
 
     /**
-     * See {@link IBinder#addFrozenStateChangeCallback(IFrozenStateChangeCallback)}
+     * See {@link IBinder#addFrozenStateChangeCallback(FrozenStateChangeCallback)}
      */
-    public void addFrozenStateChangeCallback(IFrozenStateChangeCallback callback)
+    public void addFrozenStateChangeCallback(FrozenStateChangeCallback callback)
             throws RemoteException {
         addFrozenStateChangeCallbackNative(callback);
         mFrozenStateChangeCallbacks.add(callback);
@@ -665,16 +665,16 @@
     /**
      * See {@link IBinder#removeFrozenStateChangeCallback}
      */
-    public boolean removeFrozenStateChangeCallback(IFrozenStateChangeCallback callback) {
+    public boolean removeFrozenStateChangeCallback(FrozenStateChangeCallback callback) {
         mFrozenStateChangeCallbacks.remove(callback);
         return removeFrozenStateChangeCallbackNative(callback);
     }
 
-    private native void addFrozenStateChangeCallbackNative(IFrozenStateChangeCallback callback)
+    private native void addFrozenStateChangeCallbackNative(FrozenStateChangeCallback callback)
             throws RemoteException;
 
     private native boolean removeFrozenStateChangeCallbackNative(
-            IFrozenStateChangeCallback callback);
+            FrozenStateChangeCallback callback);
 
     /**
      * Perform a dump on the remote object
@@ -762,10 +762,9 @@
     }
 
     private static void invokeFrozenStateChangeCallback(
-            IFrozenStateChangeCallback callback, IBinder binderProxy, int stateIndex) {
+            FrozenStateChangeCallback callback, IBinder binderProxy, int stateIndex) {
         try {
-            callback.onFrozenStateChanged(binderProxy,
-                    IFrozenStateChangeCallback.State.values()[stateIndex]);
+            callback.onFrozenStateChanged(binderProxy, stateIndex);
         } catch (RuntimeException exc) {
             Log.w("BinderNative", "Uncaught exception from frozen state change callback",
                     exc);
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 8185e8e..a997f4c 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -16,11 +16,15 @@
 
 package android.os;
 
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 
 import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * Base interface for a remotable object, the core part of a lightweight
@@ -377,9 +381,24 @@
      */
     public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags);
 
-    /** @hide */
-    interface IFrozenStateChangeCallback {
-        enum State {FROZEN, UNFROZEN};
+    /**
+     * A callback interface for receiving frozen state change events.
+     */
+    @FlaggedApi(Flags.FLAG_BINDER_FROZEN_STATE_CHANGE_CALLBACK)
+    interface FrozenStateChangeCallback {
+        /**
+         * @hide
+         */
+        @IntDef(prefix = {"STATE_"}, value = {
+                STATE_FROZEN,
+                STATE_UNFROZEN,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        @interface State {
+        }
+
+        int STATE_FROZEN = 0;
+        int STATE_UNFROZEN = 1;
 
         /**
          * Interface for receiving a callback when the process hosting an IBinder
@@ -387,13 +406,13 @@
          * @param who The IBinder whose hosting process has changed state.
          * @param state The latest state.
          */
-        void onFrozenStateChanged(@NonNull IBinder who, State state);
+        void onFrozenStateChanged(@NonNull IBinder who, @State int state);
     }
 
     /**
-     * {@link addFrozenStateChangeCallback} provides a callback mechanism to notify about process
-     * frozen/unfrozen events. Upon registration and any subsequent state changes, the callback is
-     * invoked with the latest process frozen state.
+     * This method provides a callback mechanism to notify about process frozen/unfrozen events.
+     * Upon registration and any subsequent state changes, the callback is invoked with the latest
+     * process frozen state.
      *
      * <p>If the listener process (the one using this API) is itself frozen, state change events
      * might be combined into a single one with the latest frozen state. This single event would
@@ -410,19 +429,19 @@
      *
      * <p>@throws {@link UnsupportedOperationException} if the kernel binder driver does not support
      * this feature.
-     * @hide
      */
-    default void addFrozenStateChangeCallback(@NonNull IFrozenStateChangeCallback callback)
+    @FlaggedApi(Flags.FLAG_BINDER_FROZEN_STATE_CHANGE_CALLBACK)
+    default void addFrozenStateChangeCallback(@NonNull FrozenStateChangeCallback callback)
             throws RemoteException {
         throw new UnsupportedOperationException();
     }
 
     /**
-     * Unregister a {@link IFrozenStateChangeCallback}. The callback will no longer be invoked when
+     * Unregister a {@link FrozenStateChangeCallback}. The callback will no longer be invoked when
      * the hosting process changes its frozen state.
-     * @hide
      */
-    default boolean removeFrozenStateChangeCallback(@NonNull IFrozenStateChangeCallback callback) {
+    @FlaggedApi(Flags.FLAG_BINDER_FROZEN_STATE_CHANGE_CALLBACK)
+    default boolean removeFrozenStateChangeCallback(@NonNull FrozenStateChangeCallback callback) {
         throw new UnsupportedOperationException();
     }
 }
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 39bd15c..738d129 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -153,6 +153,14 @@
 }
 
 flag {
+    name: "binder_frozen_state_change_callback"
+    is_exported: true
+    namespace: "system_performance"
+    description: "Guards the frozen state change callback API."
+    bug: "361157077"
+}
+
+flag {
     name: "message_queue_tail_tracking"
     namespace: "system_performance"
     description: "track tail of message queue."
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e32625e..0ada993 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -111,6 +111,7 @@
 import java.lang.annotation.Target;
 import java.lang.reflect.Field;
 import java.net.URISyntaxException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -3022,6 +3023,9 @@
     /** @hide - Private call() method to query the 'configuration' table */
     public static final String CALL_METHOD_LIST_CONFIG = "LIST_config";
 
+    /** @hide - Private call() method to query the 'configuration' tables' namespaces */
+    public static final String CALL_METHOD_LIST_NAMESPACES_CONFIG = "LIST_namespaces_config";
+
     /** @hide - Private call() method to disable / re-enable syncs to the 'configuration' table */
     public static final String CALL_METHOD_SET_SYNC_DISABLED_MODE_CONFIG =
             "SET_SYNC_DISABLED_MODE_config";
@@ -20458,6 +20462,10 @@
          *
          * The keys take the form {@code namespace/flag}, and the values are the flag values.
          *
+         * Note: this API is _not_ performant, and may make a large number of
+         * Binder calls. It is intended for use in testing and debugging, and
+         * should not be used in performance-sensitive code.
+         *
          * @hide
          */
         @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@@ -20469,13 +20477,33 @@
                 Bundle arg = new Bundle();
                 arg.putInt(Settings.CALL_METHOD_USER_KEY, resolver.getUserId());
                 IContentProvider cp = sProviderHolder.getProvider(resolver);
-                Bundle b = cp.call(resolver.getAttributionSource(),
-                        sProviderHolder.mUri.getAuthority(), CALL_METHOD_LIST_CONFIG, null, arg);
-                if (b != null) {
-                    Map<String, String> flagsToValues =
-                            (HashMap) b.getSerializable(Settings.NameValueTable.VALUE,
-                                            java.util.HashMap.class);
-                    allFlags.putAll(flagsToValues);
+
+                if (Flags.reduceBinderTransactionSizeForGetAllProperties()) {
+                    Bundle b = cp.call(resolver.getAttributionSource(),
+                            sProviderHolder.mUri.getAuthority(),
+                                CALL_METHOD_LIST_NAMESPACES_CONFIG, null, arg);
+                    if (b != null) {
+                        HashSet<String> namespaces =
+                                (HashSet) b.getSerializable(Settings.NameValueTable.VALUE,
+                                                java.util.HashSet.class);
+                        for (String namespace : namespaces) {
+                            Map<String, String> keyValues =
+                                    getStrings(namespace, new ArrayList());
+                            for (String key : keyValues.keySet()) {
+                                allFlags.put(namespace + "/" + key, keyValues.get(key));
+                            }
+                        }
+                    }
+                } else {
+                    Bundle b = cp.call(resolver.getAttributionSource(),
+                            sProviderHolder.mUri.getAuthority(),
+                            CALL_METHOD_LIST_CONFIG, null, arg);
+                    if (b != null) {
+                        Map<String, String> flagsToValues =
+                                (HashMap) b.getSerializable(Settings.NameValueTable.VALUE,
+                                                java.util.HashMap.class);
+                        allFlags.putAll(flagsToValues);
+                    }
                 }
             } catch (RemoteException e) {
                 Log.w(TAG, "Can't query configuration table for " + CONTENT_URI, e);
diff --git a/core/java/android/provider/flags.aconfig b/core/java/android/provider/flags.aconfig
index 5c0f873..4c63673 100644
--- a/core/java/android/provider/flags.aconfig
+++ b/core/java/android/provider/flags.aconfig
@@ -52,3 +52,14 @@
     description: "Enable the new ContactsContract Default Account APIs."
     bug: "359957527"
 }
+
+flag {
+    name: "reduce_binder_transaction_size_for_get_all_properties"
+    namespace: "core_experiments_team_internal"
+    description: "Reduce Binder transaction size in getAllProperties calls"
+    bug: "362652574"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 6b4340a..15a4715 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -38,6 +38,7 @@
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.window.flags.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -55,7 +56,6 @@
 import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
 import java.util.Objects;
@@ -146,7 +146,7 @@
                 forceConsumingTypes |= type;
             }
 
-            if (Flags.enableCaptionCompatInsetForceConsumptionAlways()
+            if (ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS.isEnabled()
                     && (flags & FLAG_FORCE_CONSUMING_OPAQUE_CAPTION_BAR) != 0) {
                 forceConsumingOpaqueCaptionBar = true;
             }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9ff5031..33e7905 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -125,11 +125,11 @@
 import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER;
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INSETS_CONTROLLER;
+import static android.window.flags.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
 import static com.android.text.flags.Flags.disableHandwritingInitiatorForIme;
 import static com.android.window.flags.Flags.enableBufferTransformHintFromDisplay;
-import static com.android.window.flags.Flags.enableCaptionCompatInsetForceConsumption;
 import static com.android.window.flags.Flags.insetsControlChangedItem;
 import static com.android.window.flags.Flags.insetsControlSeq;
 import static com.android.window.flags.Flags.setScPropertiesInClient;
@@ -3214,10 +3214,10 @@
             typesToShow |= Type.navigationBars();
         }
         if (captionIsHiddenByFlags && !captionWasHiddenByFlags
-                && enableCaptionCompatInsetForceConsumption()) {
+                && ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION.isEnabled()) {
             typesToHide |= Type.captionBar();
         } else if (!captionIsHiddenByFlags && captionWasHiddenByFlags
-                && enableCaptionCompatInsetForceConsumption()) {
+                && ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION.isEnabled()) {
             typesToShow |= Type.captionBar();
         }
         if (typesToHide != 0) {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index e1154ca..06820cd 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1003,6 +1003,55 @@
         public int getActionTag() {
             return SET_EMPTY_VIEW_ACTION_TAG;
         }
+
+        @Override
+        public boolean canWriteToProto() {
+            return true;
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) {
+            final long token = out.start(RemoteViewsProto.Action.SET_EMPTY_VIEW_ACTION);
+            out.write(RemoteViewsProto.SetEmptyViewAction.VIEW_ID,
+                    appResources.getResourceName(mViewId));
+            out.write(RemoteViewsProto.SetEmptyViewAction.EMPTY_VIEW_ID,
+                    appResources.getResourceName(mViewId));
+            out.end(token);
+        }
+
+        public static PendingResources<Action> createFromProto(ProtoInputStream in)
+                throws Exception {
+            final LongSparseArray<Object> values = new LongSparseArray<>();
+
+            final long token = in.start(RemoteViewsProto.Action.SET_EMPTY_VIEW_ACTION);
+            while (in.nextField() != NO_MORE_FIELDS) {
+                switch (in.getFieldNumber()) {
+                    case (int) RemoteViewsProto.SetEmptyViewAction.VIEW_ID:
+                        values.put(RemoteViewsProto.SetEmptyViewAction.VIEW_ID,
+                                in.readString(RemoteViewsProto.SetEmptyViewAction.VIEW_ID));
+                        break;
+                    case (int) RemoteViewsProto.SetEmptyViewAction.EMPTY_VIEW_ID:
+                        values.put(RemoteViewsProto.SetEmptyViewAction.EMPTY_VIEW_ID,
+                                in.readString(RemoteViewsProto.SetEmptyViewAction.EMPTY_VIEW_ID));
+                        break;
+                    default:
+                        Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                + ProtoUtils.currentFieldToString(in));
+                }
+            }
+            in.end(token);
+
+            checkContainsKeys(values, new long[]{RemoteViewsProto.SetEmptyViewAction.VIEW_ID,
+                    RemoteViewsProto.SetEmptyViewAction.EMPTY_VIEW_ID});
+
+            return (context, resources, rootData, depth) -> {
+                int viewId = getAsIdentifier(resources, values,
+                        RemoteViewsProto.SetEmptyViewAction.VIEW_ID);
+                int emptyViewId = getAsIdentifier(resources, values,
+                        RemoteViewsProto.SetEmptyViewAction.EMPTY_VIEW_ID);
+                return new SetEmptyView(viewId, emptyViewId);
+            };
+        }
     }
 
     private static class SetPendingIntentTemplate extends Action {
@@ -1243,6 +1292,68 @@
 
             mItems.visitUris(visitor);
         }
+
+        @Override
+        public boolean canWriteToProto() {
+            // Skip actions that do not contain items (intent only actions)
+            return mItems != null;
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) {
+            if (mItems == null) return;
+            final long token = out.start(
+                    RemoteViewsProto.Action.SET_REMOTE_COLLECTION_ITEM_LIST_ADAPTER_ACTION);
+            out.write(RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.VIEW_ID,
+                    appResources.getResourceName(mViewId));
+            final long itemsToken = out.start(
+                    RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.ITEMS);
+            mItems.writeToProto(context, out, /* attached= */ true);
+            out.end(itemsToken);
+            out.end(token);
+        }
+    }
+
+    private PendingResources<Action> createSetRemoteCollectionItemListAdapterActionFromProto(
+            ProtoInputStream in) throws Exception {
+        final LongSparseArray<Object> values = new LongSparseArray<>();
+
+        final long token = in.start(
+                RemoteViewsProto.Action.SET_REMOTE_COLLECTION_ITEM_LIST_ADAPTER_ACTION);
+        while (in.nextField() != NO_MORE_FIELDS) {
+            switch (in.getFieldNumber()) {
+                case (int) RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.VIEW_ID:
+                    values.put(RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.VIEW_ID,
+                            in.readString(
+                                    RemoteViewsProto
+                                            .SetRemoteCollectionItemListAdapterAction.VIEW_ID));
+                    break;
+                case (int) RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.ITEMS:
+                    final long itemsToken = in.start(
+                            RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.ITEMS);
+                    values.put(RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.ITEMS,
+                            RemoteCollectionItems.createFromProto(in));
+                    in.end(itemsToken);
+                    break;
+                default:
+                    Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                            + ProtoUtils.currentFieldToString(in));
+            }
+        }
+        in.end(token);
+
+        checkContainsKeys(values,
+                new long[]{RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.VIEW_ID,
+                        RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.ITEMS});
+
+        return (context, resources, rootData, depth) -> {
+            int viewId = getAsIdentifier(resources, values,
+                    RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.VIEW_ID);
+            return new SetRemoteCollectionItemListAdapterAction(viewId,
+                    ((PendingResources<RemoteCollectionItems>) values.get(
+                            RemoteViewsProto.SetRemoteCollectionItemListAdapterAction.ITEMS))
+                            .create(context, resources, rootData, depth));
+        };
     }
 
     /**
@@ -2036,6 +2147,68 @@
         public int getActionTag() {
             return SET_DRAWABLE_TINT_TAG;
         }
+
+        @Override
+        public boolean canWriteToProto() {
+            return true;
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) {
+            final long token = out.start(RemoteViewsProto.Action.SET_DRAWABLE_TINT_ACTION);
+            out.write(RemoteViewsProto.SetDrawableTintAction.VIEW_ID,
+                    appResources.getResourceName(mViewId));
+            out.write(RemoteViewsProto.SetDrawableTintAction.COLOR_FILTER, mColorFilter);
+            out.write(RemoteViewsProto.SetDrawableTintAction.FILTER_MODE,
+                    PorterDuff.modeToInt(mFilterMode));
+            out.write(RemoteViewsProto.SetDrawableTintAction.TARGET_BACKGROUND, mTargetBackground);
+            out.end(token);
+        }
+
+        public static PendingResources<Action> createFromProto(ProtoInputStream in)
+                throws Exception {
+            final LongSparseArray<Object> values = new LongSparseArray<>();
+
+            final long token = in.start(RemoteViewsProto.Action.SET_DRAWABLE_TINT_ACTION);
+            while (in.nextField() != NO_MORE_FIELDS) {
+                switch (in.getFieldNumber()) {
+                    case (int) RemoteViewsProto.SetDrawableTintAction.VIEW_ID:
+                        values.put(RemoteViewsProto.SetDrawableTintAction.VIEW_ID,
+                                in.readString(RemoteViewsProto.SetDrawableTintAction.VIEW_ID));
+                        break;
+                    case (int) RemoteViewsProto.SetDrawableTintAction.TARGET_BACKGROUND:
+                        values.put(RemoteViewsProto.SetDrawableTintAction.TARGET_BACKGROUND,
+                                in.readBoolean(
+                                        RemoteViewsProto.SetDrawableTintAction.TARGET_BACKGROUND));
+                        break;
+                    case (int) RemoteViewsProto.SetDrawableTintAction.COLOR_FILTER:
+                        values.put(RemoteViewsProto.SetDrawableTintAction.COLOR_FILTER,
+                                in.readInt(RemoteViewsProto.SetDrawableTintAction.COLOR_FILTER));
+                        break;
+                    case (int) RemoteViewsProto.SetDrawableTintAction.FILTER_MODE:
+                        values.put(RemoteViewsProto.SetDrawableTintAction.FILTER_MODE,
+                                PorterDuff.intToMode(in.readInt(
+                                        RemoteViewsProto.SetDrawableTintAction.FILTER_MODE)));
+                        break;
+                    default:
+                        Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                + ProtoUtils.currentFieldToString(in));
+                }
+            }
+            in.end(token);
+
+            checkContainsKeys(values, new long[]{RemoteViewsProto.SetDrawableTintAction.VIEW_ID});
+
+            return (context, resources, rootData, depth) -> {
+                int viewId = getAsIdentifier(resources, values,
+                        RemoteViewsProto.SetDrawableTintAction.VIEW_ID);
+                return new SetDrawableTint(viewId, (boolean) values.get(
+                        RemoteViewsProto.SetDrawableTintAction.TARGET_BACKGROUND, false),
+                        (int) values.get(RemoteViewsProto.SetDrawableTintAction.COLOR_FILTER, 0),
+                        (PorterDuff.Mode) values.get(
+                                RemoteViewsProto.SetDrawableTintAction.FILTER_MODE));
+            };
+        }
     }
 
     /**
@@ -2047,7 +2220,7 @@
      * target {@link View#getBackground()}.
      * <p>
      */
-    private class SetRippleDrawableColor extends Action {
+    private static class SetRippleDrawableColor extends Action {
         ColorStateList mColorStateList;
 
         SetRippleDrawableColor(@IdRes int id, ColorStateList colorStateList) {
@@ -2082,6 +2255,58 @@
         public int getActionTag() {
             return SET_RIPPLE_DRAWABLE_COLOR_TAG;
         }
+
+        @Override
+        public boolean canWriteToProto() {
+            return true;
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) {
+            final long token = out.start(RemoteViewsProto.Action.SET_RIPPLE_DRAWABLE_COLOR_ACTION);
+            out.write(RemoteViewsProto.SetRippleDrawableColorAction.VIEW_ID,
+                    appResources.getResourceName(mViewId));
+            writeColorStateListToProto(out, mColorStateList,
+                    RemoteViewsProto.SetRippleDrawableColorAction.COLOR_STATE_LIST);
+            out.end(token);
+        }
+
+        public static PendingResources<Action> createFromProto(ProtoInputStream in)
+                throws Exception {
+            final LongSparseArray<Object> values = new LongSparseArray<>();
+
+            final long token = in.start(RemoteViewsProto.Action.SET_RIPPLE_DRAWABLE_COLOR_ACTION);
+            while (in.nextField() != NO_MORE_FIELDS) {
+                switch (in.getFieldNumber()) {
+                    case (int) RemoteViewsProto.SetRippleDrawableColorAction.VIEW_ID:
+                        values.put(RemoteViewsProto.SetRippleDrawableColorAction.VIEW_ID,
+                                in.readString(
+                                        RemoteViewsProto.SetRippleDrawableColorAction.VIEW_ID));
+                        break;
+                    case (int) RemoteViewsProto.SetRippleDrawableColorAction.COLOR_STATE_LIST:
+                        values.put(RemoteViewsProto.SetRippleDrawableColorAction.COLOR_STATE_LIST,
+                                createColorStateListFromProto(in,
+                                        RemoteViewsProto
+                                                .SetRippleDrawableColorAction.COLOR_STATE_LIST));
+                        break;
+                    default:
+                        Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                + ProtoUtils.currentFieldToString(in));
+                }
+            }
+            in.end(token);
+
+            checkContainsKeys(values,
+                    new long[]{RemoteViewsProto.SetRippleDrawableColorAction.VIEW_ID,
+                            RemoteViewsProto.SetRippleDrawableColorAction.COLOR_STATE_LIST});
+
+            return (context, resources, rootData, depth) -> {
+                int viewId = getAsIdentifier(resources, values,
+                        RemoteViewsProto.SetRippleDrawableColorAction.VIEW_ID);
+                return new SetRippleDrawableColor(viewId, (ColorStateList) values.get(
+                        RemoteViewsProto.SetRippleDrawableColorAction.COLOR_STATE_LIST));
+            };
+        }
     }
 
     /**
@@ -2987,6 +3212,82 @@
         public int getActionTag() {
             return RESOURCE_REFLECTION_ACTION_TAG;
         }
+
+        @Override
+        public boolean canWriteToProto() {
+            return true;
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) {
+            final long token = out.start(RemoteViewsProto.Action.RESOURCE_REFLECTION_ACTION);
+            out.write(RemoteViewsProto.ResourceReflectionAction.VIEW_ID,
+                    appResources.getResourceName(mViewId));
+            out.write(RemoteViewsProto.ResourceReflectionAction.METHOD_NAME, mMethodName);
+            out.write(RemoteViewsProto.ResourceReflectionAction.PARAMETER_TYPE, mType);
+            out.write(RemoteViewsProto.ResourceReflectionAction.RESOURCE_TYPE, mResourceType);
+            if (mResId != 0) {
+                out.write(RemoteViewsProto.ResourceReflectionAction.RES_ID,
+                        appResources.getResourceName(mResId));
+            }
+            out.end(token);
+        }
+
+        public static PendingResources<Action> createFromProto(ProtoInputStream in)
+                throws Exception {
+            final LongSparseArray<Object> values = new LongSparseArray<>();
+
+            final long token = in.start(RemoteViewsProto.Action.RESOURCE_REFLECTION_ACTION);
+            while (in.nextField() != NO_MORE_FIELDS) {
+                switch (in.getFieldNumber()) {
+                    case (int) RemoteViewsProto.ResourceReflectionAction.VIEW_ID:
+                        values.put(RemoteViewsProto.ResourceReflectionAction.VIEW_ID,
+                                in.readString(RemoteViewsProto.ResourceReflectionAction.VIEW_ID));
+                        break;
+                    case (int) RemoteViewsProto.ResourceReflectionAction.METHOD_NAME:
+                        values.put(RemoteViewsProto.ResourceReflectionAction.METHOD_NAME,
+                                in.readString(
+                                        RemoteViewsProto.ResourceReflectionAction.METHOD_NAME));
+                        break;
+                    case (int) RemoteViewsProto.ResourceReflectionAction.RESOURCE_TYPE:
+                        values.put(RemoteViewsProto.ResourceReflectionAction.RESOURCE_TYPE,
+                                in.readInt(
+                                        RemoteViewsProto.ResourceReflectionAction.RESOURCE_TYPE));
+                        break;
+                    case (int) RemoteViewsProto.ResourceReflectionAction.RES_ID:
+                        values.put(RemoteViewsProto.ResourceReflectionAction.RES_ID,
+                                in.readString(RemoteViewsProto.ResourceReflectionAction.RES_ID));
+                        break;
+                    case (int) RemoteViewsProto.ResourceReflectionAction.PARAMETER_TYPE:
+                        values.put(RemoteViewsProto.ResourceReflectionAction.PARAMETER_TYPE,
+                                in.readInt(
+                                        RemoteViewsProto.ResourceReflectionAction.PARAMETER_TYPE));
+                        break;
+                    default:
+                        Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                + ProtoUtils.currentFieldToString(in));
+                }
+            }
+            in.end(token);
+
+            checkContainsKeys(values, new long[]{RemoteViewsProto.ResourceReflectionAction.VIEW_ID,
+                    RemoteViewsProto.ResourceReflectionAction.METHOD_NAME,
+                    RemoteViewsProto.ResourceReflectionAction.PARAMETER_TYPE});
+
+            return (context, resources, rootData, depth) -> {
+                int viewId = getAsIdentifier(resources, values,
+                        RemoteViewsProto.ResourceReflectionAction.VIEW_ID);
+
+                int resId = (values.indexOfKey(RemoteViewsProto.ResourceReflectionAction.RES_ID)
+                        >= 0) ? getAsIdentifier(resources, values,
+                        RemoteViewsProto.ResourceReflectionAction.RES_ID) : 0;
+                return new ResourceReflectionAction(viewId,
+                        (String) values.get(RemoteViewsProto.ResourceReflectionAction.METHOD_NAME),
+                        (int) values.get(RemoteViewsProto.ResourceReflectionAction.PARAMETER_TYPE),
+                        (int) values.get(RemoteViewsProto.ResourceReflectionAction.RESOURCE_TYPE,
+                                0), resId);
+            };
+        }
     }
 
     private static final class AttributeReflectionAction extends BaseReflectionAction {
@@ -4593,6 +4894,61 @@
         public int getActionTag() {
             return SET_INT_TAG_TAG;
         }
+
+        @Override
+        public boolean canWriteToProto() {
+            return true;
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) {
+            final long token = out.start(RemoteViewsProto.Action.SET_INT_TAG_ACTION);
+            out.write(RemoteViewsProto.SetIntTagAction.VIEW_ID,
+                    appResources.getResourceName(mViewId));
+            out.write(RemoteViewsProto.SetIntTagAction.KEY,
+                    appResources.getResourceName(mKey)); // rebase
+            out.write(RemoteViewsProto.SetIntTagAction.TAG, mTag);
+            out.end(token);
+        }
+
+        public static PendingResources<Action> createFromProto(ProtoInputStream in)
+                throws Exception {
+            final LongSparseArray<Object> values = new LongSparseArray<>();
+
+            final long token = in.start(RemoteViewsProto.Action.SET_INT_TAG_ACTION);
+            while (in.nextField() != NO_MORE_FIELDS) {
+                switch (in.getFieldNumber()) {
+                    case (int) RemoteViewsProto.SetIntTagAction.VIEW_ID:
+                        values.put(RemoteViewsProto.SetIntTagAction.VIEW_ID,
+                                in.readString(RemoteViewsProto.SetIntTagAction.VIEW_ID));
+                        break;
+                    case (int) RemoteViewsProto.SetIntTagAction.KEY:
+                        values.put(RemoteViewsProto.SetIntTagAction.KEY,
+                                in.readString(RemoteViewsProto.SetIntTagAction.KEY));
+                        break;
+                    case (int) RemoteViewsProto.SetIntTagAction.TAG:
+                        values.put(RemoteViewsProto.SetIntTagAction.TAG,
+                                in.readInt(RemoteViewsProto.SetIntTagAction.TAG));
+                        break;
+                    default:
+                        Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                + ProtoUtils.currentFieldToString(in));
+                }
+            }
+            in.end(token);
+
+            checkContainsKeys(values, new long[]{RemoteViewsProto.SetIntTagAction.VIEW_ID,
+                    RemoteViewsProto.SetIntTagAction.KEY});
+
+            return (context, resources, rootData, depth) -> {
+                int viewId = getAsIdentifier(resources, values,
+                        RemoteViewsProto.SetIntTagAction.VIEW_ID);
+                int keyId = getAsIdentifier(resources, values,
+                        RemoteViewsProto.SetIntTagAction.KEY);
+                return new SetIntTagAction(viewId, keyId,
+                        (int) values.get(RemoteViewsProto.SetIntTagAction.TAG, 0));
+            };
+        }
     }
 
     private static class SetCompoundButtonCheckedAction extends Action {
@@ -4643,6 +4999,56 @@
         public int getActionTag() {
             return SET_COMPOUND_BUTTON_CHECKED_TAG;
         }
+
+        @Override
+        public boolean canWriteToProto() {
+            return true;
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) {
+            final long token = out.start(
+                    RemoteViewsProto.Action.SET_COMPOUND_BUTTON_CHECKED_ACTION);
+            out.write(RemoteViewsProto.SetCompoundButtonCheckedAction.VIEW_ID,
+                    appResources.getResourceName(mViewId));
+            out.write(RemoteViewsProto.SetCompoundButtonCheckedAction.CHECKED, mChecked);
+            out.end(token);
+        }
+
+        public static PendingResources<Action> createFromProto(ProtoInputStream in)
+                throws Exception {
+            final LongSparseArray<Object> values = new LongSparseArray<>();
+
+            final long token = in.start(RemoteViewsProto.Action.SET_COMPOUND_BUTTON_CHECKED_ACTION);
+            while (in.nextField() != NO_MORE_FIELDS) {
+                switch (in.getFieldNumber()) {
+                    case (int) RemoteViewsProto.SetCompoundButtonCheckedAction.VIEW_ID:
+                        values.put(RemoteViewsProto.SetCompoundButtonCheckedAction.VIEW_ID,
+                                in.readString(
+                                        RemoteViewsProto.SetCompoundButtonCheckedAction.VIEW_ID));
+                        break;
+                    case (int) RemoteViewsProto.SetCompoundButtonCheckedAction.CHECKED:
+                        values.put(RemoteViewsProto.SetCompoundButtonCheckedAction.CHECKED,
+                                in.readBoolean(
+                                        RemoteViewsProto.SetCompoundButtonCheckedAction.CHECKED));
+                        break;
+                    default:
+                        Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                + ProtoUtils.currentFieldToString(in));
+                }
+            }
+            in.end(token);
+
+            checkContainsKeys(values,
+                    new long[]{RemoteViewsProto.SetCompoundButtonCheckedAction.VIEW_ID});
+
+            return (context, resources, rootData, depth) -> {
+                int viewId = getAsIdentifier(resources, values,
+                        RemoteViewsProto.SetCompoundButtonCheckedAction.VIEW_ID);
+                return new SetCompoundButtonCheckedAction(viewId, (boolean) values.get(
+                        RemoteViewsProto.SetCompoundButtonCheckedAction.CHECKED, false));
+            };
+        }
     }
 
     private static class SetRadioGroupCheckedAction extends Action {
@@ -4707,6 +5113,61 @@
         public int getActionTag() {
             return SET_RADIO_GROUP_CHECKED;
         }
+
+        @Override
+        public boolean canWriteToProto() {
+            return true;
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream out, Context context, Resources appResources) {
+            final long token = out.start(RemoteViewsProto.Action.SET_RADIO_GROUP_CHECKED_ACTION);
+            out.write(RemoteViewsProto.SetRadioGroupCheckedAction.VIEW_ID,
+                    appResources.getResourceName(mViewId));
+            if (mCheckedId != -1) {
+                out.write(RemoteViewsProto.SetRadioGroupCheckedAction.CHECKED_ID,
+                        appResources.getResourceName(mCheckedId));
+            }
+            out.end(token);
+        }
+
+        public static PendingResources<Action> createFromProto(ProtoInputStream in)
+                throws Exception {
+            final LongSparseArray<Object> values = new LongSparseArray<>();
+
+            final long token = in.start(RemoteViewsProto.Action.SET_RADIO_GROUP_CHECKED_ACTION);
+            while (in.nextField() != NO_MORE_FIELDS) {
+                switch (in.getFieldNumber()) {
+                    case (int) RemoteViewsProto.SetRadioGroupCheckedAction.VIEW_ID:
+                        values.put(RemoteViewsProto.SetRadioGroupCheckedAction.VIEW_ID,
+                                in.readString(RemoteViewsProto.SetRadioGroupCheckedAction.VIEW_ID));
+                        break;
+                    case (int) RemoteViewsProto.SetRadioGroupCheckedAction.CHECKED_ID:
+                        values.put(RemoteViewsProto.SetRadioGroupCheckedAction.CHECKED_ID,
+                                in.readString(
+                                        RemoteViewsProto.SetRadioGroupCheckedAction.CHECKED_ID));
+                        break;
+                    default:
+                        Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                + ProtoUtils.currentFieldToString(in));
+                }
+            }
+            in.end(token);
+
+            checkContainsKeys(values,
+                    new long[]{RemoteViewsProto.SetRadioGroupCheckedAction.VIEW_ID});
+
+            return (context, resources, rootData, depth) -> {
+                int viewId = getAsIdentifier(resources, values,
+                        RemoteViewsProto.SetRadioGroupCheckedAction.VIEW_ID);
+
+                int checkedId = (values.indexOfKey(
+                        RemoteViewsProto.SetRadioGroupCheckedAction.CHECKED_ID) >= 0)
+                        ? getAsIdentifier(resources, values,
+                        RemoteViewsProto.SetRadioGroupCheckedAction.CHECKED_ID) : -1;
+                return new SetRadioGroupCheckedAction(viewId, checkedId);
+            };
+        }
     }
 
     private static class SetViewOutlinePreferredRadiusAction extends Action {
@@ -8450,6 +8911,7 @@
         public static PendingResources<RemoteCollectionItems> createFromProto(ProtoInputStream in)
                 throws Exception {
             final LongSparseArray<Object> values = new LongSparseArray<>();
+
             values.put(RemoteViewsProto.RemoteCollectionItems.IDS, new ArrayList<Long>());
             values.put(RemoteViewsProto.RemoteCollectionItems.VIEWS,
                     new ArrayList<PendingResources<RemoteViews>>());
@@ -9207,6 +9669,22 @@
                 return ReflectionAction.createFromProto(in);
             case (int) RemoteViewsProto.Action.REMOVE_FROM_PARENT_ACTION:
                 return RemoveFromParentAction.createFromProto(in);
+            case (int) RemoteViewsProto.Action.RESOURCE_REFLECTION_ACTION:
+                return ResourceReflectionAction.createFromProto(in);
+            case (int) RemoteViewsProto.Action.SET_COMPOUND_BUTTON_CHECKED_ACTION:
+                return SetCompoundButtonCheckedAction.createFromProto(in);
+            case (int) RemoteViewsProto.Action.SET_DRAWABLE_TINT_ACTION:
+                return SetDrawableTint.createFromProto(in);
+            case (int) RemoteViewsProto.Action.SET_EMPTY_VIEW_ACTION:
+                return SetEmptyView.createFromProto(in);
+            case (int) RemoteViewsProto.Action.SET_INT_TAG_ACTION:
+                return SetIntTagAction.createFromProto(in);
+            case (int) RemoteViewsProto.Action.SET_RADIO_GROUP_CHECKED_ACTION:
+                return SetRadioGroupCheckedAction.createFromProto(in);
+            case (int) RemoteViewsProto.Action.SET_REMOTE_COLLECTION_ITEM_LIST_ADAPTER_ACTION:
+                return rv.createSetRemoteCollectionItemListAdapterActionFromProto(in);
+            case (int) RemoteViewsProto.Action.SET_RIPPLE_DRAWABLE_COLOR_ACTION:
+                return SetRippleDrawableColor.createFromProto(in);
             default:
                 throw new RuntimeException("Unhandled field while reading Action proto!\n"
                         + ProtoUtils.currentFieldToString(in));
diff --git a/core/java/android/window/flags/DesktopModeFlags.java b/core/java/android/window/flags/DesktopModeFlags.java
index 5c53d66..701b6be 100644
--- a/core/java/android/window/flags/DesktopModeFlags.java
+++ b/core/java/android/window/flags/DesktopModeFlags.java
@@ -17,7 +17,9 @@
 package android.window.flags;
 
 import android.annotation.Nullable;
-import android.content.Context;
+import android.app.ActivityThread;
+import android.app.Application;
+import android.content.ContentResolver;
 import android.provider.Settings;
 import android.util.Log;
 
@@ -39,9 +41,13 @@
  */
 public enum DesktopModeFlags {
     // All desktop mode related flags to be overridden by developer option toggle will be added here
-    DESKTOP_WINDOWING_MODE(
+    ENABLE_DESKTOP_WINDOWING_MODE(
             Flags::enableDesktopWindowingMode, /* shouldOverrideByDevOption= */ true),
-    DYNAMIC_INITIAL_BOUNDS(Flags::enableWindowingDynamicInitialBounds, false);
+    ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS(Flags::enableWindowingDynamicInitialBounds, false),
+    ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION(
+            Flags::enableCaptionCompatInsetForceConsumption, true),
+    ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS(
+            Flags::enableCaptionCompatInsetForceConsumptionAlways, true);
 
     private static final String TAG = "DesktopModeFlagsUtil";
     // Function called to obtain aconfig flag value.
@@ -62,14 +68,15 @@
      * Determines state of flag based on the actual flag and desktop mode developer option
      * overrides.
      */
-    public boolean isEnabled(Context context) {
+    public boolean isEnabled() {
+        Application application = ActivityThread.currentApplication();
         if (!Flags.showDesktopWindowingDevOption()
                 || !mShouldOverrideByDevOption
-                || context.getContentResolver() == null) {
+                || application == null) {
             return mFlagFunction.get();
         } else {
             boolean shouldToggleBeEnabledByDefault = Flags.enableDesktopWindowingMode();
-            return switch (getToggleOverride(context)) {
+            return switch (getToggleOverride(application.getContentResolver())) {
                 case OVERRIDE_UNSET -> mFlagFunction.get();
                 // When toggle override matches its default state, don't override flags. This
                 // helps users reset their feature overrides.
@@ -79,14 +86,14 @@
         }
     }
 
-    private ToggleOverride getToggleOverride(Context context) {
+    private ToggleOverride getToggleOverride(ContentResolver contentResolver) {
         // If cached, return it
         if (sCachedToggleOverride != null) {
             return sCachedToggleOverride;
         }
 
         // Otherwise, fetch and cache it
-        ToggleOverride override = getToggleOverrideFromSystem(context);
+        ToggleOverride override = getToggleOverrideFromSystem(contentResolver);
         sCachedToggleOverride = override;
         Log.d(TAG, "Toggle override initialized to: " + override);
         return override;
@@ -95,9 +102,9 @@
     /**
      *  Returns {@link ToggleOverride} from Settings.Global set by toggle.
      */
-    private ToggleOverride getToggleOverrideFromSystem(Context context) {
+    private ToggleOverride getToggleOverrideFromSystem(ContentResolver contentResolver) {
         int settingValue = Settings.Global.getInt(
-                context.getContentResolver(),
+                contentResolver,
                 Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES,
                 ToggleOverride.OVERRIDE_UNSET.getSetting()
         );
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 4708be8..84dfc49 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -38,6 +38,8 @@
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.flags.Flags.customizableWindowHeaders;
+import static android.window.flags.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION;
+import static android.window.flags.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS;
 
 import static com.android.internal.policy.PhoneWindow.FEATURE_OPTIONS_PANEL;
 
@@ -114,7 +116,6 @@
 import com.android.internal.widget.ActionBarContextView;
 import com.android.internal.widget.BackgroundFallback;
 import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
-import com.android.window.flags.Flags;
 
 import java.util.List;
 import java.util.concurrent.Executor;
@@ -1217,14 +1218,15 @@
 
         final boolean hideCaptionBar = fullscreen
                 || (requestedVisibleTypes & WindowInsets.Type.captionBar()) == 0;
-        final boolean consumingCaptionBar = Flags.enableCaptionCompatInsetForceConsumption()
-                && ((mLastForceConsumingTypes & WindowInsets.Type.captionBar()) != 0
+        final boolean consumingCaptionBar =
+                ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION.isEnabled()
+                        && ((mLastForceConsumingTypes & WindowInsets.Type.captionBar()) != 0
                         && hideCaptionBar);
 
         final boolean isOpaqueCaptionBar = customizableWindowHeaders()
                 && (appearance & APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND) == 0;
         final boolean consumingOpaqueCaptionBar =
-                Flags.enableCaptionCompatInsetForceConsumptionAlways()
+                ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS.isEnabled()
                         && mLastForceConsumingOpaqueCaptionBar
                         && isOpaqueCaptionBar;
 
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 90cb10a..9a4ff8f 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -290,7 +290,6 @@
                 "libasync_safe",
                 "libbinderthreadstateutils",
                 "libdmabufinfo",
-                "libgif",
                 "libgui_window_info_static",
                 "libkernelconfigs",
                 "libnativehelper_lazy",
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index f2c70b5..8003bb7 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -1747,9 +1747,9 @@
     {"linkToDeathNative",   "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
     {"unlinkToDeathNative", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
     {"addFrozenStateChangeCallbackNative",
-        "(Landroid/os/IBinder$IFrozenStateChangeCallback;)V", (void*)android_os_BinderProxy_addFrozenStateChangeCallback},
+        "(Landroid/os/IBinder$FrozenStateChangeCallback;)V", (void*)android_os_BinderProxy_addFrozenStateChangeCallback},
     {"removeFrozenStateChangeCallbackNative",
-        "(Landroid/os/IBinder$IFrozenStateChangeCallback;)Z", (void*)android_os_BinderProxy_removeFrozenStateChangeCallback},
+        "(Landroid/os/IBinder$FrozenStateChangeCallback;)Z", (void*)android_os_BinderProxy_removeFrozenStateChangeCallback},
     {"getNativeFinalizer",  "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
     {"getExtension",        "()Landroid/os/IBinder;", (void*)android_os_BinderProxy_getExtension},
 };
@@ -1774,7 +1774,7 @@
                                    "(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
     gBinderProxyOffsets.mInvokeFrozenStateChangeCallback =
             GetStaticMethodIDOrDie(env, clazz, "invokeFrozenStateChangeCallback",
-                                   "(Landroid/os/IBinder$IFrozenStateChangeCallback;Landroid/os/"
+                                   "(Landroid/os/IBinder$FrozenStateChangeCallback;Landroid/os/"
                                    "IBinder;I)V");
     gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
 
diff --git a/core/jni/jni_wrappers.h b/core/jni/jni_wrappers.h
index 3b29e30..21b5b13 100644
--- a/core/jni/jni_wrappers.h
+++ b/core/jni/jni_wrappers.h
@@ -69,9 +69,47 @@
     return static_cast<T>(res);
 }
 
+//  Inline variable that specifies the method binding format.
+//  The expected format is 'XX${method}XX', where ${method} represents the original method name.
+//  This variable is shared across all translation units. This is treated as a global variable as
+//  per C++ 17.
+inline std::string jniMethodFormat;
+
+inline static void setJniMethodFormat(std::string value) {
+    jniMethodFormat = value;
+}
+
+// Potentially translates the given JNINativeMethods if setJniMethodFormat has been set.
+// Has no effect otherwise
+inline const JNINativeMethod* maybeRenameJniMethods(const JNINativeMethod* gMethods,
+                                                    int numMethods) {
+    if (jniMethodFormat.empty()) {
+        return gMethods;
+    }
+    // Make a copy of gMethods with reformatted method names.
+    JNINativeMethod* modifiedMethods = new JNINativeMethod[numMethods];
+    LOG_ALWAYS_FATAL_IF(!modifiedMethods, "Failed to allocate a copy of the JNI methods");
+
+    size_t methodNamePos = jniMethodFormat.find("${method}");
+    LOG_ALWAYS_FATAL_IF(methodNamePos == std::string::npos,
+                        "Invalid jniMethodFormat: could not find '${method}' in pattern");
+
+    for (int i = 0; i < numMethods; i++) {
+        modifiedMethods[i] = gMethods[i];
+        std::string modifiedName = jniMethodFormat;
+        modifiedName.replace(methodNamePos, 9, gMethods[i].name);
+        char* modifiedNameChars = new char[modifiedName.length() + 1];
+        LOG_ALWAYS_FATAL_IF(!modifiedNameChars, "Failed to allocate the new method name");
+        std::strcpy(modifiedNameChars, modifiedName.c_str());
+        modifiedMethods[i].name = modifiedNameChars;
+    }
+    return modifiedMethods;
+}
+
 static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className,
                                        const JNINativeMethod* gMethods, int numMethods) {
-    int res = jniRegisterNativeMethods(env, className, gMethods, numMethods);
+    const JNINativeMethod* modifiedMethods = maybeRenameJniMethods(gMethods, numMethods);
+    int res = jniRegisterNativeMethods(env, className, modifiedMethods, numMethods);
     LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
     return res;
 }
diff --git a/core/proto/android/widget/remoteviews.proto b/core/proto/android/widget/remoteviews.proto
index 47c97b0..f477d32 100644
--- a/core/proto/android/widget/remoteviews.proto
+++ b/core/proto/android/widget/remoteviews.proto
@@ -299,6 +299,14 @@
             NightModeReflectionAction night_mode_reflection_action = 5;
             ReflectionAction reflection_action = 6;
             RemoveFromParentAction remove_from_parent_action = 7;
+            ResourceReflectionAction resource_reflection_action = 8;
+            SetCompoundButtonCheckedAction set_compound_button_checked_action = 9;
+            SetDrawableTintAction set_drawable_tint_action = 10;
+            SetEmptyViewAction set_empty_view_action = 11;
+            SetIntTagAction set_int_tag_action = 12;
+            SetRadioGroupCheckedAction set_radio_group_checked_action = 13;
+            SetRemoteCollectionItemListAdapterAction set_remote_collection_item_list_adapter_action = 14;
+            SetRippleDrawableColorAction set_ripple_drawable_color_action = 15;
         }
     }
 
@@ -374,6 +382,52 @@
     message RemoveFromParentAction {
         optional string view_id = 1;
     }
+
+    message ResourceReflectionAction {
+        optional string view_id = 1;
+        optional string method_name = 2;
+        optional int32 resource_type = 3;
+        optional string res_id = 4;
+        optional int32 parameter_type = 5;
+    }
+
+    message SetCompoundButtonCheckedAction {
+        optional string view_id = 1;
+        optional bool checked = 2;
+    }
+
+    message SetDrawableTintAction {
+        optional string view_id = 1;
+        optional bool target_background = 2;
+        optional int32 color_filter = 3;
+        optional int32 filter_mode = 4;
+    }
+
+    message SetEmptyViewAction {
+        optional string view_id = 1;
+        optional string empty_view_id = 2;
+    }
+
+    message SetIntTagAction {
+        optional string view_id = 1;
+        optional string key = 2;
+        optional int32 tag = 3;
+    }
+
+    message SetRadioGroupCheckedAction {
+        optional string view_id = 1;
+        optional string checked_id = 2;
+    }
+
+    message SetRemoteCollectionItemListAdapterAction {
+        optional string view_id = 1;
+        optional RemoteCollectionItems items = 2;
+    }
+
+    message SetRippleDrawableColorAction {
+        optional string view_id = 1;
+        optional android.content.res.ColorStateListProto color_state_list = 2;
+    }
 }
 
 
diff --git a/core/res/res/layout/miniresolver.xml b/core/res/res/layout/miniresolver.xml
index e60e0b0..db1c779 100644
--- a/core/res/res/layout/miniresolver.xml
+++ b/core/res/res/layout/miniresolver.xml
@@ -122,7 +122,8 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_alignParentStart="true"
-                android:maxLines="2"
+                android:layout_toStartOf="@id/button_open"
+                android:layout_marginEnd="8dp"
                 android:background="@drawable/resolver_outlined_button_bg"
                 style="?android:attr/borderlessButtonStyle"
                 android:paddingHorizontal="16dp"
@@ -136,7 +137,6 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_alignParentEnd="true"
-                android:maxLines="2"
                 android:paddingHorizontal="16dp"
                 android:background="@drawable/resolver_button_bg"
                 style="?android:attr/borderlessButtonStyle"
diff --git a/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java
index 77e8a40..fe54aa8 100644
--- a/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java
+++ b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java
@@ -30,31 +30,30 @@
 
 public class BfsccTestAppCmdService extends Service {
     private IBfsccTestAppCmdService.Stub mBinder = new IBfsccTestAppCmdService.Stub() {
-        private final LinkedBlockingQueue<IBinder.IFrozenStateChangeCallback.State> mNotifications =
+        private final LinkedBlockingQueue<Integer> mNotifications =
                 new LinkedBlockingQueue<>();
 
         @Override
         public void listenTo(IBinder binder) throws RemoteException {
             binder.addFrozenStateChangeCallback(
-                    (IBinder who, IBinder.IFrozenStateChangeCallback.State state)
-                            -> mNotifications.offer(state));
+                    (IBinder who, int state) -> mNotifications.offer(state));
         }
 
         @Override
         public boolean[] waitAndConsumeNotifications() {
             List<Boolean> results = new ArrayList<>();
             try {
-                IBinder.IFrozenStateChangeCallback.State state =
-                        mNotifications.poll(5, TimeUnit.SECONDS);
+                Integer state = mNotifications.poll(5, TimeUnit.SECONDS);
                 if (state != null) {
-                    results.add(state == IBinder.IFrozenStateChangeCallback.State.FROZEN);
+                    results.add(
+                            state.intValue() == IBinder.FrozenStateChangeCallback.STATE_FROZEN);
                 }
             } catch (InterruptedException e) {
                 return null;
             }
             while (mNotifications.size() > 0) {
-                results.add(mNotifications.poll()
-                        == IBinder.IFrozenStateChangeCallback.State.FROZEN);
+                results.add(mNotifications.poll().intValue()
+                        == IBinder.FrozenStateChangeCallback.STATE_FROZEN);
             }
             boolean[] convertedResults = new boolean[results.size()];
             for (int i = 0; i < results.size(); i++) {
diff --git a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
index ee2e7e0..195a18a 100644
--- a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
+++ b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
@@ -52,7 +52,7 @@
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
- * Tests functionality of {@link android.os.IBinder.IFrozenStateChangeCallback}.
+ * Tests functionality of {@link android.os.IBinder.FrozenStateChangeCallback}.
  */
 @RunWith(AndroidJUnit4.class)
 @IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
@@ -157,7 +157,7 @@
     @Test
     public void onStateChangeNotCalledAfterCallbackRemoved() throws Exception {
         final LinkedBlockingQueue<Boolean> results = new LinkedBlockingQueue<>();
-        IBinder.IFrozenStateChangeCallback callback;
+        IBinder.FrozenStateChangeCallback callback;
         if ((callback = createCallback(mBfsccTestAppCmdService.asBinder(), results)) == null) {
             return;
         }
@@ -171,7 +171,7 @@
     public void multipleCallbacks() throws Exception {
         final LinkedBlockingQueue<Boolean> results1 = new LinkedBlockingQueue<>();
         final LinkedBlockingQueue<Boolean> results2 = new LinkedBlockingQueue<>();
-        IBinder.IFrozenStateChangeCallback callback1;
+        IBinder.FrozenStateChangeCallback callback1;
         if ((callback1 = createCallback(mBfsccTestAppCmdService.asBinder(), results1)) == null) {
             return;
         }
@@ -197,8 +197,8 @@
     public void onStateChangeCalledWithTheRightBinder() throws Exception {
         final IBinder binder = mBfsccTestAppCmdService.asBinder();
         final LinkedBlockingQueue<IBinder> results = new LinkedBlockingQueue<>();
-        IBinder.IFrozenStateChangeCallback callback =
-                (IBinder who, IBinder.IFrozenStateChangeCallback.State state) -> results.offer(who);
+        IBinder.FrozenStateChangeCallback callback =
+                (IBinder who, int state) -> results.offer(who);
         try {
             binder.addFrozenStateChangeCallback(callback);
         } catch (UnsupportedOperationException e) {
@@ -221,12 +221,12 @@
         }
     }
 
-    private IBinder.IFrozenStateChangeCallback createCallback(IBinder binder, Queue<Boolean> queue)
+    private IBinder.FrozenStateChangeCallback createCallback(IBinder binder, Queue<Boolean> queue)
             throws RemoteException {
         try {
-            final IBinder.IFrozenStateChangeCallback callback =
-                    (IBinder who, IBinder.IFrozenStateChangeCallback.State state) ->
-                            queue.offer(state == IBinder.IFrozenStateChangeCallback.State.FROZEN);
+            final IBinder.FrozenStateChangeCallback callback =
+                    (IBinder who, int state) ->
+                            queue.offer(state == IBinder.FrozenStateChangeCallback.STATE_FROZEN);
             binder.addFrozenStateChangeCallback(callback);
             return callback;
         } catch (UnsupportedOperationException e) {
diff --git a/core/tests/coretests/src/android/window/flags/DesktopModeFlagsTest.java b/core/tests/coretests/src/android/window/flags/DesktopModeFlagsTest.java
index 32345e6..dd40695 100644
--- a/core/tests/coretests/src/android/window/flags/DesktopModeFlagsTest.java
+++ b/core/tests/coretests/src/android/window/flags/DesktopModeFlagsTest.java
@@ -16,7 +16,7 @@
 
 package android.window.flags;
 
-import static android.window.flags.DesktopModeFlags.DESKTOP_WINDOWING_MODE;
+import static android.window.flags.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODE;
 
 import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE;
 import static com.android.window.flags.Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS;
@@ -75,7 +75,7 @@
     public void isEnabled_devOptionFlagDisabled_overrideOff_featureFlagOn_returnsTrue() {
         setOverride(OVERRIDE_OFF_SETTING);
         // In absence of dev options, follow flag
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isTrue();
     }
 
 
@@ -84,7 +84,7 @@
     public void isEnabled_devOptionFlagDisabled_overrideOn_featureFlagOff_returnsFalse() {
         setOverride(OVERRIDE_ON_SETTING);
 
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isFalse();
     }
 
     @Test
@@ -93,7 +93,7 @@
         setOverride(OVERRIDE_UNSET_SETTING);
 
         // For overridableFlag, for unset overrides, follow flag
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isTrue();
     }
 
     @Test
@@ -103,7 +103,7 @@
         setOverride(OVERRIDE_UNSET_SETTING);
 
         // For overridableFlag, for unset overrides, follow flag
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isFalse();
     }
 
     @Test
@@ -112,7 +112,7 @@
         setOverride(null);
 
         // For overridableFlag, in absence of overrides, follow flag
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isTrue();
     }
 
     @Test
@@ -122,7 +122,7 @@
         setOverride(null);
 
         // For overridableFlag, in absence of overrides, follow flag
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isFalse();
     }
 
     @Test
@@ -131,7 +131,7 @@
         setOverride(-2);
 
         // For overridableFlag, for unrecognized overrides, follow flag
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isTrue();
     }
 
     @Test
@@ -141,7 +141,7 @@
         setOverride(-2);
 
         // For overridableFlag, for unrecognizable overrides, follow flag
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isFalse();
     }
 
     @Test
@@ -150,7 +150,7 @@
         setOverride(OVERRIDE_OFF_SETTING);
 
         // For overridableFlag, follow override if they exist
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isFalse();
     }
 
     @Test
@@ -160,7 +160,7 @@
         setOverride(OVERRIDE_ON_SETTING);
 
         // For overridableFlag, follow override if they exist
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isTrue();
     }
 
     @Test
@@ -169,12 +169,12 @@
         setOverride(OVERRIDE_OFF_SETTING);
 
         // For overridableFlag, follow override if they exist
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isFalse();
 
         setOverride(OVERRIDE_ON_SETTING);
 
         // Keep overrides constant through the process
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isFalse();
     }
 
     @Test
@@ -184,12 +184,12 @@
         setOverride(OVERRIDE_ON_SETTING);
 
         // For overridableFlag, follow override if they exist
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isTrue();
 
         setOverride(OVERRIDE_OFF_SETTING);
 
         // Keep overrides constant through the process
-        assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue();
+        assertThat(ENABLE_DESKTOP_WINDOWING_MODE.isEnabled()).isTrue();
     }
 
     @Test
@@ -199,7 +199,7 @@
         setOverride(OVERRIDE_UNSET_SETTING);
 
         // For unset overrides, follow flag
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isTrue();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isTrue();
     }
 
     @Test
@@ -208,7 +208,7 @@
     public void isEnabled_dwFlagOn_overrideUnset_featureFlagOff_returnsFalse() {
         setOverride(OVERRIDE_UNSET_SETTING);
         // For unset overrides, follow flag
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isFalse();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isFalse();
     }
 
     @Test
@@ -221,7 +221,7 @@
         setOverride(OVERRIDE_ON_SETTING);
 
         // When toggle override matches its default state (dw flag), don't override flags
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isTrue();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isTrue();
     }
 
     @Test
@@ -231,7 +231,7 @@
         setOverride(OVERRIDE_ON_SETTING);
 
         // When toggle override matches its default state (dw flag), don't override flags
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isFalse();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isFalse();
     }
 
     @Test
@@ -244,7 +244,7 @@
         setOverride(OVERRIDE_OFF_SETTING);
 
         // Follow override if they exist, and is not equal to default toggle state (dw flag)
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isTrue();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isTrue();
     }
 
     @Test
@@ -254,7 +254,7 @@
         setOverride(OVERRIDE_OFF_SETTING);
 
         // Follow override if they exist, and is not equal to default toggle state (dw flag)
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isFalse();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isFalse();
     }
 
     @Test
@@ -267,7 +267,7 @@
         setOverride(OVERRIDE_UNSET_SETTING);
 
         // For unset overrides, follow flag
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isTrue();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isTrue();
     }
 
     @Test
@@ -280,7 +280,7 @@
         setOverride(OVERRIDE_UNSET_SETTING);
 
         // For unset overrides, follow flag
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isFalse();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isFalse();
     }
 
     @Test
@@ -293,7 +293,7 @@
         setOverride(OVERRIDE_ON_SETTING);
 
         // Follow override if they exist, and is not equal to default toggle state (dw flag)
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isTrue();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isTrue();
     }
 
     @Test
@@ -306,7 +306,7 @@
         setOverride(OVERRIDE_ON_SETTING);
 
         // Follow override if they exist, and is not equal to default toggle state (dw flag)
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isFalse();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isFalse();
     }
 
     @Test
@@ -319,7 +319,7 @@
         setOverride(OVERRIDE_OFF_SETTING);
 
         // When toggle override matches its default state (dw flag), don't override flags
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isTrue();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isTrue();
     }
 
     @Test
@@ -332,7 +332,7 @@
         setOverride(OVERRIDE_OFF_SETTING);
 
         // When toggle override matches its default state (dw flag), don't override flags
-        assertThat(DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(mContext)).isFalse();
+        assertThat(DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()).isFalse();
     }
 
     private void setOverride(Integer setting) {
diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
index e0823b8..d6b2a78 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -24,7 +24,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
@@ -190,25 +189,6 @@
         assertThat(generateSessionName(cujName, tooLongTag)).isEqualTo(expectedTrimmedName);
     }
 
-    @Test
-    public void validateConfiguration_surfaceOnlyAndNotDeferMonitor_throwsError() {
-        Configuration.Builder builder = Configuration.Builder.withSurface(1,
-                mActivity.getApplicationContext(), mSurfaceControl,
-                mActivity.getMainThreadHandler()).setDeferMonitorForAnimationStart(false);
-
-        assertThrows(IllegalStateException.class, builder::build);
-    }
-
-    @Test
-    public void validateConfiguration_surfaceOnlyAndDeferMonitor_doesNotThrowError() {
-        Configuration.Builder builder = Configuration.Builder.withSurface(1,
-                mActivity.getApplicationContext(),
-                mSurfaceControl, mActivity.getMainThreadHandler()).setDeferMonitorForAnimationStart(
-                true);
-
-        builder.build(); // no exception.
-    }
-
     private InteractionJankMonitor createMockedInteractionJankMonitor() {
         InteractionJankMonitor monitor = spy(new InteractionJankMonitor(mWorker));
         doReturn(true).when(monitor).shouldMonitor();
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
index 397cdcf..67de25e 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
@@ -125,12 +125,12 @@
         }
 
         @Override
-        public void addFrozenStateChangeCallback(IFrozenStateChangeCallback callback)
+        public void addFrozenStateChangeCallback(FrozenStateChangeCallback callback)
                 throws RemoteException {
         }
 
         @Override
-        public boolean removeFrozenStateChangeCallback(IFrozenStateChangeCallback callback) {
+        public boolean removeFrozenStateChangeCallback(FrozenStateChangeCallback callback) {
             return false;
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index dc27c82..02c818f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -862,6 +862,15 @@
                 handleCaptionThroughStatusBar(e, decoration);
                 final boolean wasDragging = mIsDragging;
                 updateDragStatus(e.getActionMasked());
+                final boolean upOrCancel = e.getActionMasked() == ACTION_UP
+                        || e.getActionMasked() == ACTION_CANCEL;
+                if (wasDragging && upOrCancel) {
+                    // When finishing a drag the event will be consumed, which means the pressed
+                    // state of the App Handle must be manually reset to scale its drawable back to
+                    // its original shape. This is necessary for drag gestures of the Handle that
+                    // result in a cancellation (dragging back to the top).
+                    v.setPressed(false);
+                }
                 // Only prevent onClick from receiving this event if it's a drag.
                 return wasDragging;
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index b1fc55f..16036be 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -24,6 +24,8 @@
 import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_UP;
+import static android.window.flags.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION;
+import static android.window.flags.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS;
 
 import static com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT;
 import static com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON;
@@ -604,13 +606,13 @@
                 // their custom content.
                 relayoutParams.mInputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
             } else {
-                if (Flags.enableCaptionCompatInsetForceConsumption()) {
+                if (ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION.isEnabled()) {
                     // Force-consume the caption bar insets when the app tries to hide the caption.
                     // This improves app compatibility of immersive apps.
                     relayoutParams.mInsetSourceFlags |= FLAG_FORCE_CONSUMING;
                 }
             }
-            if (Flags.enableCaptionCompatInsetForceConsumptionAlways()) {
+            if (ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS.isEnabled()) {
                 // Always force-consume the caption bar insets for maximum app compatibility,
                 // including non-immersive apps that just don't handle caption insets properly.
                 relayoutParams.mInsetSourceFlags |= FLAG_FORCE_CONSUMING_OPAQUE_CAPTION_BAR;
diff --git a/libs/input/MouseCursorController.cpp b/libs/input/MouseCursorController.cpp
index 1afef75..d993b87 100644
--- a/libs/input/MouseCursorController.cpp
+++ b/libs/input/MouseCursorController.cpp
@@ -64,25 +64,6 @@
     mLocked.pointerSprite.clear();
 }
 
-std::optional<FloatRect> MouseCursorController::getBounds() const {
-    std::scoped_lock lock(mLock);
-
-    return getBoundsLocked();
-}
-
-std::optional<FloatRect> MouseCursorController::getBoundsLocked() const REQUIRES(mLock) {
-    if (!mLocked.viewport.isValid()) {
-        return {};
-    }
-
-    return FloatRect{
-            static_cast<float>(mLocked.viewport.logicalLeft),
-            static_cast<float>(mLocked.viewport.logicalTop),
-            static_cast<float>(mLocked.viewport.logicalRight - 1),
-            static_cast<float>(mLocked.viewport.logicalBottom - 1),
-    };
-}
-
 void MouseCursorController::move(float deltaX, float deltaY) {
 #if DEBUG_MOUSE_CURSOR_UPDATES
     ALOGD("Move pointer by deltaX=%0.3f, deltaY=%0.3f", deltaX, deltaY);
@@ -105,11 +86,20 @@
 }
 
 void MouseCursorController::setPositionLocked(float x, float y) REQUIRES(mLock) {
-    const auto bounds = getBoundsLocked();
-    if (!bounds) return;
+    const auto& v = mLocked.viewport;
+    if (!v.isValid()) return;
 
-    mLocked.pointerX = std::max(bounds->left, std::min(bounds->right, x));
-    mLocked.pointerY = std::max(bounds->top, std::min(bounds->bottom, y));
+    // The valid bounds for a mouse cursor. Since the right and bottom edges are considered outside
+    // the display, clip the bounds by one pixel instead of letting the cursor get arbitrarily
+    // close to the outside edge.
+    const FloatRect bounds{
+            static_cast<float>(mLocked.viewport.logicalLeft),
+            static_cast<float>(mLocked.viewport.logicalTop),
+            static_cast<float>(mLocked.viewport.logicalRight - 1),
+            static_cast<float>(mLocked.viewport.logicalBottom - 1),
+    };
+    mLocked.pointerX = std::max(bounds.left, std::min(bounds.right, x));
+    mLocked.pointerY = std::max(bounds.top, std::min(bounds.bottom, y));
 
     updatePointerLocked();
 }
@@ -216,9 +206,11 @@
     // Reset cursor position to center if size or display changed.
     if (oldViewport.displayId != viewport.displayId || oldDisplayWidth != newDisplayWidth ||
         oldDisplayHeight != newDisplayHeight) {
-        if (const auto bounds = getBoundsLocked(); bounds) {
-            mLocked.pointerX = (bounds->left + bounds->right) * 0.5f;
-            mLocked.pointerY = (bounds->top + bounds->bottom) * 0.5f;
+        if (viewport.isValid()) {
+            // Use integer coordinates as the starting point for the cursor location.
+            // We usually expect display sizes to be even numbers, so the flooring is precautionary.
+            mLocked.pointerX = std::floor((viewport.logicalLeft + viewport.logicalRight) / 2);
+            mLocked.pointerY = std::floor((viewport.logicalTop + viewport.logicalBottom) / 2);
             // Reload icon resources for density may be changed.
             loadResourcesLocked(getAdditionalMouseResources);
         } else {
diff --git a/libs/input/MouseCursorController.h b/libs/input/MouseCursorController.h
index 8600341..12b31a8 100644
--- a/libs/input/MouseCursorController.h
+++ b/libs/input/MouseCursorController.h
@@ -43,7 +43,6 @@
     MouseCursorController(PointerControllerContext& context);
     ~MouseCursorController();
 
-    std::optional<FloatRect> getBounds() const;
     void move(float deltaX, float deltaY);
     void setPosition(float x, float y);
     FloatPoint getPosition() const;
@@ -104,7 +103,6 @@
 
     } mLocked GUARDED_BY(mLock);
 
-    std::optional<FloatRect> getBoundsLocked() const;
     void setPositionLocked(float x, float y);
 
     void updatePointerLocked();
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 5ae967b..78d7d3a 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -138,10 +138,6 @@
     return mDisplayInfoListener->mLock;
 }
 
-std::optional<FloatRect> PointerController::getBounds() const {
-    return mCursorController.getBounds();
-}
-
 void PointerController::move(float deltaX, float deltaY) {
     const ui::LogicalDisplayId displayId = mCursorController.getDisplayId();
     vec2 transformed;
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index 4d1e1d7..ee8d121 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -51,7 +51,6 @@
 
     ~PointerController() override;
 
-    std::optional<FloatRect> getBounds() const override;
     void move(float deltaX, float deltaY) override;
     void setPosition(float x, float y) override;
     FloatPoint getPosition() const override;
@@ -166,9 +165,6 @@
 
     ~TouchPointerController() override;
 
-    std::optional<FloatRect> getBounds() const override {
-        LOG_ALWAYS_FATAL("Should not be called");
-    }
     void move(float, float) override {
         LOG_ALWAYS_FATAL("Should not be called");
     }
diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig
index dcf5c5b..cddc337 100644
--- a/location/java/android/location/flags/location.aconfig
+++ b/location/java/android/location/flags/location.aconfig
@@ -111,6 +111,17 @@
 }
 
 flag {
+    name: "enable_ni_supl_message_injection_by_carrier_config_bugfix"
+    namespace: "location"
+    description: "Flag for enabling NI SUPL message injection by carrier config"
+    bug: "242105192"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "enable_ni_supl_message_injection_by_carrier_config"
     namespace: "location"
     description: "Flag for enabling NI SUPL message injection by carrier config"
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index e2e7a46..cdb517b3 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -6318,7 +6318,14 @@
     /**
      * @hide
      * Get the audio devices that would be used for the routing of the given audio attributes.
-     * @param attributes the {@link AudioAttributes} for which the routing is being queried
+     * @param attributes the {@link AudioAttributes} for which the routing is being queried.
+     *   For queries about output devices (playback use cases), a valid usage must be specified in
+     *   the audio attributes via AudioAttributes.Builder.setUsage(). The capture preset MUST NOT
+     *   be changed from default.
+     *   For queries about input devices (capture use case), a valid capture preset MUST be
+     *   specified in the audio attributes via AudioAttributes.Builder.setCapturePreset(). If a
+     *   capture preset is present, then this has precedence over any usage or content type also
+     *   present in the audio attrirutes.
      * @return an empty list if there was an issue with the request, a list of audio devices
      *   otherwise (typically one device, except for duplicated paths).
      */
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 0b094a2..34e33c0 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1639,7 +1639,7 @@
     <string name="cached_apps_freezer_reboot_dialog_text">Your device must be rebooted for this change to apply. Reboot now or cancel.</string>
 
     <!-- Name of the 3.5mm and usb audio device. [CHAR LIMIT=50] -->
-    <string name="media_transfer_wired_usb_device_name">Wired headphone</string>
+    <string name="media_transfer_wired_headphone_name">Wired headphone</string>
 
     <!-- Name of the 3.5mm headphone, used in desktop devices. [CHAR LIMIT=50] -->
     <string name="media_transfer_headphone_name">Headphone</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index 116de56..0b8fb22ce 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -90,7 +90,7 @@
                 name =
                         inputRoutingEnabledAndIsDesktop()
                                 ? context.getString(R.string.media_transfer_headphone_name)
-                                : context.getString(R.string.media_transfer_wired_usb_device_name);
+                                : context.getString(R.string.media_transfer_wired_headphone_name);
                 break;
             case TYPE_USB_DEVICE:
             case TYPE_USB_HEADSET:
@@ -98,7 +98,7 @@
                 name =
                         inputRoutingEnabledAndIsDesktop()
                                 ? context.getString(R.string.media_transfer_usb_speaker_name)
-                                : context.getString(R.string.media_transfer_wired_usb_device_name);
+                                : context.getString(R.string.media_transfer_wired_headphone_name);
                 break;
             case TYPE_DOCK:
                 name = context.getString(R.string.media_transfer_dock_speaker_device_name);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
index 23cfc01..da5f428 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
@@ -106,12 +106,12 @@
         when(mInfo.getName()).thenReturn(deviceName);
 
         assertThat(mPhoneMediaDevice.getName())
-                .isEqualTo(mContext.getString(R.string.media_transfer_wired_usb_device_name));
+                .isEqualTo(mContext.getString(R.string.media_transfer_wired_headphone_name));
 
         when(mInfo.getType()).thenReturn(TYPE_USB_DEVICE);
 
         assertThat(mPhoneMediaDevice.getName())
-                .isEqualTo(mContext.getString(R.string.media_transfer_wired_usb_device_name));
+                .isEqualTo(mContext.getString(R.string.media_transfer_wired_headphone_name));
 
         when(mInfo.getType()).thenReturn(TYPE_BUILTIN_SPEAKER);
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index ba59ce8..0ae4da5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -545,6 +545,10 @@
                 reportDeviceConfigAccess(prefix);
                 return result;
             }
+            case Settings.CALL_METHOD_LIST_NAMESPACES_CONFIG -> {
+                Bundle result = packageNamespacesForCallResult(getAllConfigFlagNamespaces());
+                return result;
+            }
             case Settings.CALL_METHOD_REGISTER_MONITOR_CALLBACK_CONFIG -> {
                 RemoteCallback callback = args.getParcelable(
                         Settings.CALL_METHOD_MONITOR_CALLBACK_KEY);
@@ -1337,6 +1341,23 @@
     }
 
     @NonNull
+    private HashSet<String> getAllConfigFlagNamespaces() {
+        Set<String> flagNames = getAllConfigFlags(null).keySet();
+        HashSet<String> namespaces = new HashSet();
+        for (String name : flagNames) {
+            int slashIndex = name.indexOf("/");
+            boolean validSlashIndex = slashIndex != -1
+                        && slashIndex != 0
+                        && slashIndex != name.length();
+            if (validSlashIndex) {
+                String namespace = name.substring(0, slashIndex);
+                namespaces.add(namespace);
+            }
+        }
+        return namespaces;
+    }
+
+    @NonNull
     private HashMap<String, String> getAllConfigFlags(@Nullable String prefix) {
         if (DEBUG) {
             Slog.v(LOG_TAG, "getAllConfigFlags() for " + prefix);
@@ -2561,6 +2582,12 @@
         return result;
     }
 
+    private Bundle packageNamespacesForCallResult(@NonNull HashSet<String> namespaces) {
+        Bundle result = new Bundle();
+        result.putSerializable(Settings.NameValueTable.VALUE, namespaces);
+        return result;
+    }
+
     private void setMonitorCallback(RemoteCallback callback) {
         if (callback == null) {
             return;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
index 956c129..2028d288 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -25,6 +25,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.view.MotionEvent;
 import android.view.accessibility.AccessibilityManager;
 
@@ -33,6 +35,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.testing.FakeMetricsLogger;
+import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -201,6 +204,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING)
     public void testTrackpadGesture() {
         assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
         when(mFalsingDataProvider.isFromTrackpad()).thenReturn(true);
@@ -208,6 +212,14 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING)
+    public void testTrackpadGesture_touchScreenSource_false() {
+        assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
+        when(mFalsingDataProvider.isTouchScreenSource()).thenReturn(false);
+        assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
+    }
+
+    @Test
     public void testAddAndRemoveFalsingBeliefListener() {
         verify(mHistoryTracker, never()).addBeliefListener(any());
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index df4b048..5a4799c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -312,6 +312,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING)
     public void test_IsFromTrackpad() {
         MotionEvent motionEventOrigin = appendTrackpadDownEvent(0, 0);
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
index c18deb1..fac9312 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
@@ -14,22 +14,6 @@
  * limitations under the License.
  */
 
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
 package com.android.systemui.keyguard.domain.interactor
 
 import android.os.PowerManager
@@ -47,7 +31,6 @@
 import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
 import com.android.systemui.communal.domain.interactor.setCommunalAvailable
 import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.communal.shared.model.CommunalTransitionKeys
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -129,7 +112,7 @@
             transitionRepository.sendTransitionSteps(
                 from = KeyguardState.LOCKSCREEN,
                 to = KeyguardState.DOZING,
-                testScope
+                testScope,
             )
             kosmos.fakeKeyguardRepository.setBiometricUnlockState(BiometricUnlockMode.NONE)
             reset(transitionRepository)
@@ -145,10 +128,7 @@
 
             // Under default conditions, we should transition to LOCKSCREEN when waking up.
             assertThat(transitionRepository)
-                .startedTransition(
-                    from = KeyguardState.DOZING,
-                    to = KeyguardState.LOCKSCREEN,
-                )
+                .startedTransition(from = KeyguardState.DOZING, to = KeyguardState.LOCKSCREEN)
         }
 
     @Test
@@ -166,10 +146,7 @@
             // If dreaming is possible and communal is available, then we should transition to
             // GLANCEABLE_HUB when waking up due to power button press.
             assertThat(transitionRepository)
-                .startedTransition(
-                    from = KeyguardState.DOZING,
-                    to = KeyguardState.GLANCEABLE_HUB,
-                )
+                .startedTransition(from = KeyguardState.DOZING, to = KeyguardState.GLANCEABLE_HUB)
         }
 
     @Test
@@ -186,8 +163,7 @@
 
             // If dreaming is possible and communal is available, then we should transition to
             // GLANCEABLE_HUB when waking up due to power button press.
-            verify(kosmos.fakeCommunalSceneRepository)
-                .changeScene(CommunalScenes.Communal, CommunalTransitionKeys.Immediately)
+            verify(kosmos.fakeCommunalSceneRepository).snapToScene(CommunalScenes.Communal)
         }
 
     @Test
@@ -204,10 +180,7 @@
             // If dreaming is NOT possible but communal is available, then we should transition to
             // LOCKSCREEN when waking up due to power button press.
             assertThat(transitionRepository)
-                .startedTransition(
-                    from = KeyguardState.DOZING,
-                    to = KeyguardState.LOCKSCREEN,
-                )
+                .startedTransition(from = KeyguardState.DOZING, to = KeyguardState.LOCKSCREEN)
         }
 
     @Test
@@ -224,10 +197,7 @@
             // If dreaming is possible but communal is NOT available, then we should transition to
             // LOCKSCREEN when waking up due to power button press.
             assertThat(transitionRepository)
-                .startedTransition(
-                    from = KeyguardState.DOZING,
-                    to = KeyguardState.LOCKSCREEN,
-                )
+                .startedTransition(from = KeyguardState.DOZING, to = KeyguardState.LOCKSCREEN)
         }
 
     @Test
@@ -245,10 +215,7 @@
 
             // Under default conditions, we should transition to LOCKSCREEN when waking up.
             assertThat(transitionRepository)
-                .startedTransition(
-                    from = KeyguardState.DOZING,
-                    to = KeyguardState.GLANCEABLE_HUB,
-                )
+                .startedTransition(from = KeyguardState.DOZING, to = KeyguardState.GLANCEABLE_HUB)
         }
 
     @Test
@@ -261,10 +228,7 @@
 
             // Waking with a SHOW_WHEN_LOCKED activity on top should transition to OCCLUDED.
             assertThat(transitionRepository)
-                .startedTransition(
-                    from = KeyguardState.DOZING,
-                    to = KeyguardState.OCCLUDED,
-                )
+                .startedTransition(from = KeyguardState.DOZING, to = KeyguardState.OCCLUDED)
         }
 
     @Test
@@ -282,10 +246,7 @@
 
             // Waking with a SHOW_WHEN_LOCKED activity on top should transition to OCCLUDED.
             assertThat(transitionRepository)
-                .startedTransition(
-                    from = KeyguardState.DOZING,
-                    to = KeyguardState.OCCLUDED,
-                )
+                .startedTransition(from = KeyguardState.DOZING, to = KeyguardState.OCCLUDED)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index 40fb769..614d51e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -39,6 +39,7 @@
 import android.app.IActivityManager;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
+import android.graphics.Rect;
 import android.platform.test.flag.junit.FlagsParameterization;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
@@ -53,6 +54,7 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.communal.domain.interactor.CommunalInteractor;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.EnableSceneContainer;
 import com.android.systemui.flags.SceneContainerFlagParameterizationKt;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
@@ -466,6 +468,32 @@
         assertThat(lp.preferredMinDisplayRefreshRate).isEqualTo(0);
     }
 
+    @Test
+    @EnableSceneContainer
+    public void configChanged_boundsUpdate() {
+        when(mNotificationShadeWindowView.getWidth()).thenReturn(1600);
+        when(mNotificationShadeWindowView.getHeight()).thenReturn(800);
+        when(mNotificationShadeWindowView.getVisibility()).thenReturn(View.INVISIBLE);
+        Configuration newConfig = new Configuration();
+        // swap width and height in new bounds to simulate auto-rotate
+        newConfig.windowConfiguration.setBounds(new Rect(0, 0, 800, 1600));
+        mNotificationShadeWindowController.onConfigChanged(newConfig);
+        verify(mWindowManager, atLeastOnce()).updateViewLayout(any(), any());
+    }
+
+    @Test
+    @EnableSceneContainer
+    public void configChanged_boundsDontUpdate() {
+        when(mNotificationShadeWindowView.getWidth()).thenReturn(1600);
+        when(mNotificationShadeWindowView.getHeight()).thenReturn(800);
+        when(mNotificationShadeWindowView.getVisibility()).thenReturn(View.INVISIBLE);
+        Configuration newConfig = new Configuration();
+        // same bounds as view's current bounds
+        newConfig.windowConfiguration.setBounds(new Rect(0, 0, 1600, 800));
+        mNotificationShadeWindowController.onConfigChanged(newConfig);
+        verify(mWindowManager, never()).updateViewLayout(any(), any());
+    }
+
     private void setKeyguardShowing() {
         mNotificationShadeWindowController.setKeyguardShowing(true);
         mNotificationShadeWindowController.setKeyguardGoingAway(false);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index 769976e..ae4b679d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -282,6 +282,8 @@
         return !mRecentKeyEvents.isEmpty();
     }
 
+    // Deprecated in favor of {@code isTouchScreenSource}, b/329221787
+    @Deprecated
     public boolean isFromTrackpad() {
         if (Flags.nonTouchscreenDevicesBypassFalsing()) {
             return false;
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index 6e01393..ee6223f 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -146,7 +146,7 @@
                 screenTimeout =
                     systemSettings.getInt(
                         Settings.System.SCREEN_OFF_TIMEOUT,
-                        DEFAULT_SCREEN_TIMEOUT
+                        DEFAULT_SCREEN_TIMEOUT,
                     )
             }
             .launchIn(bgScope)
@@ -160,7 +160,7 @@
             combine(
                     communalSceneInteractor.currentScene,
                     // Emit a value on start so the combine starts.
-                    communalInteractor.userActivity.emitOnStart()
+                    communalInteractor.userActivity.emitOnStart(),
                 ) { scene, _ ->
                     // Only timeout if we're on the hub is open.
                     scene == CommunalScenes.Communal
@@ -219,7 +219,7 @@
     }
 
     private suspend fun determineSceneAfterTransition(
-        lastStartedTransition: TransitionStep,
+        lastStartedTransition: TransitionStep
     ): Pair<SceneKey, TransitionKey>? {
         val to = lastStartedTransition.to
         val from = lastStartedTransition.from
@@ -251,9 +251,8 @@
                 Pair(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
             }
             from == KeyguardState.DOZING && to == KeyguardState.GLANCEABLE_HUB -> {
-                // Make sure the communal hub is showing (immediately, not fading in) when
-                // transitioning from dozing to hub.
-                Pair(CommunalScenes.Communal, CommunalTransitionKeys.Immediately)
+                // Make sure the communal hub is showing when transitioning from dozing to hub.
+                Pair(CommunalScenes.Communal, CommunalTransitionKeys.SimpleFade)
             }
             else -> null
         }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt
index 11fb233..78156db 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalTransitionKeys.kt
@@ -30,6 +30,4 @@
     val ToEditMode = TransitionKey("ToEditMode")
     /** Transition to the glanceable hub after exiting edit mode */
     val FromEditMode = TransitionKey("FromEditMode")
-    /** Immediately transitions without any delay */
-    val Immediately = TransitionKey("Immediately")
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index 80a0cee..b0820a7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
 import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.communal.shared.model.CommunalTransitionKeys
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -95,10 +94,7 @@
         scope.launch {
             powerInteractor.isAwake
                 .filterRelevantKeyguardStateAnd { isAwake -> isAwake }
-                .sample(
-                    keyguardInteractor.biometricUnlockState,
-                    ::Pair,
-                )
+                .sample(keyguardInteractor.biometricUnlockState, ::Pair)
                 .collect {
                     (
                         _,
@@ -203,21 +199,21 @@
                             if (!SceneContainerFlag.isEnabled) {
                                 startTransitionTo(
                                     KeyguardState.GONE,
-                                    ownerReason = "waking from dozing"
+                                    ownerReason = "waking from dozing",
                                 )
                             }
                         } else if (primaryBouncerShowing) {
                             if (!SceneContainerFlag.isEnabled) {
                                 startTransitionTo(
                                     KeyguardState.PRIMARY_BOUNCER,
-                                    ownerReason = "waking from dozing"
+                                    ownerReason = "waking from dozing",
                                 )
                             }
                         } else if (isIdleOnCommunal && !communalSceneKtfRefactor()) {
                             if (!SceneContainerFlag.isEnabled) {
                                 startTransitionTo(
                                     KeyguardState.GLANCEABLE_HUB,
-                                    ownerReason = "waking from dozing"
+                                    ownerReason = "waking from dozing",
                                 )
                             }
                         } else if (isCommunalAvailable && dreamManager.canStartDreaming(true)) {
@@ -227,7 +223,7 @@
                         } else {
                             startTransitionTo(
                                 KeyguardState.LOCKSCREEN,
-                                ownerReason = "waking from dozing"
+                                ownerReason = "waking from dozing",
                             )
                         }
                     }
@@ -237,11 +233,9 @@
 
     private suspend fun transitionToGlanceableHub() {
         if (communalSceneKtfRefactor()) {
-            communalSceneInteractor.changeScene(
+            communalSceneInteractor.snapToScene(
                 newScene = CommunalScenes.Communal,
                 loggingReason = "from dozing to hub",
-                // Immediately show the hub when transitioning from dozing to hub.
-                transitionKey = CommunalTransitionKeys.Immediately,
             )
         } else {
             startTransitionTo(KeyguardState.GLANCEABLE_HUB)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
index 199caa1..7759298 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
@@ -162,10 +162,9 @@
                 .filterRelevantKeyguardStateAnd { isAsleep -> isAsleep }
                 .collect {
                     if (communalSceneKtfRefactor()) {
-                        communalSceneInteractor.changeScene(
+                        communalSceneInteractor.snapToScene(
                             newScene = CommunalScenes.Blank,
                             loggingReason = "hub to dozing",
-                            transitionKey = CommunalTransitionKeys.Immediately,
                             keyguardState = KeyguardState.DOZING,
                         )
                     } else {
@@ -210,12 +209,12 @@
                             // ends, to avoid transitioning to OCCLUDED erroneously when exiting
                             // the dream.
                             .debounce(100.milliseconds),
-                        ::Pair
+                        ::Pair,
                     )
                     .sampleFilter(
                         // When launching activities from widgets on the hub, we have a
                         // custom occlusion animation.
-                        communalSceneInteractor.isLaunchingWidget,
+                        communalSceneInteractor.isLaunchingWidget
                     ) { launchingWidget ->
                         !launchingWidget
                     }
@@ -253,7 +252,7 @@
                         noneOf(
                             // When launching activities from widgets on the hub, we wait to change
                             // scenes until the activity launch is complete.
-                            communalSceneInteractor.isLaunchingWidget,
+                            communalSceneInteractor.isLaunchingWidget
                         ),
                     )
                     .filterRelevantKeyguardStateAnd { isKeyguardGoingAway -> isKeyguardGoingAway }
@@ -270,7 +269,7 @@
                                 newScene = CommunalScenes.Blank,
                                 loggingReason = "hub to gone",
                                 transitionKey = CommunalTransitionKeys.SimpleFade,
-                                keyguardState = KeyguardState.GONE
+                                keyguardState = KeyguardState.GONE,
                             )
                         }
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
index aa6c08e..45aad82 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
@@ -140,6 +140,7 @@
                     }
                 },
                 onLongClick = { tile.onLongClick(expandable) },
+                accessibilityUiState = uiState.accessibilityUiState,
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 3f3ad13..4f47536 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -28,6 +28,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.PixelFormat;
+import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
 import android.os.Build;
@@ -987,6 +988,19 @@
 
     @Override
     public void onConfigChanged(Configuration newConfig) {
+        // If the shade window is not visible, the bounds will not update until it becomes visible.
+        // Touches that should invoke shade expansion but are not within those incorrect bounds
+        // (because the shape of the shade window remains portrait after flipping to landscape) will
+        // be dropped, causing the shade expansion to fail silently. Since the shade doesn't open,
+        // it doesn't become visible, and the bounds will never update. Therefore, we must detect
+        // the incorrect bounds here and force the update so that touches are routed correctly.
+        if (SceneContainerFlag.isEnabled() && mWindowRootView.getVisibility() == View.INVISIBLE) {
+            Rect bounds = newConfig.windowConfiguration.getBounds();
+            if (mWindowRootView.getWidth() != bounds.width()) {
+                mLogger.logConfigChangeWidthAdjust(mWindowRootView.getWidth(), bounds.width());
+                updateRootViewBounds(bounds);
+            }
+        }
         final boolean newScreenRotationAllowed = mKeyguardStateController
                 .isKeyguardScreenRotationAllowed();
 
@@ -996,6 +1010,16 @@
         }
     }
 
+    private void updateRootViewBounds(Rect bounds) {
+        int originalMlpWidth = mLp.width;
+        int originalMlpHeight = mLp.height;
+        mLp.width = bounds.width();
+        mLp.height = bounds.height();
+        mWindowManager.updateViewLayout(mWindowRootView, mLp);
+        mLp.width = originalMlpWidth;
+        mLp.height = originalMlpHeight;
+    }
+
     /**
      * When keyguard will be dismissed but didn't start animation yet.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
index e7a397b..1693e62 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
@@ -31,18 +31,13 @@
     ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) {
 
     fun logNewState(state: Any) {
-        buffer.log(
-            TAG,
-            DEBUG,
-            { str1 = state.toString() },
-            { "Applying new state: $str1" }
-        )
+        buffer.log(TAG, DEBUG, { str1 = state.toString() }, { "Applying new state: $str1" })
     }
 
     private inline fun log(
         logLevel: LogLevel,
         initializer: LogMessage.() -> Unit,
-        noinline printer: LogMessage.() -> String
+        noinline printer: LogMessage.() -> String,
     ) {
         buffer.log(TAG, logLevel, initializer, printer)
     }
@@ -52,7 +47,8 @@
             TAG,
             DEBUG,
             { bool1 = visible },
-            { "Updating visibility, should be visible : $bool1" })
+            { "Updating visibility, should be visible : $bool1" },
+        )
     }
 
     fun logIsExpanded(
@@ -65,7 +61,7 @@
         headsUpNotificationShowing: Boolean,
         scrimsVisibilityNotTransparent: Boolean,
         backgroundBlurRadius: Boolean,
-        launchingActivityFromNotification: Boolean
+        launchingActivityFromNotification: Boolean,
     ) {
         buffer.log(
             TAG,
@@ -82,11 +78,13 @@
                 long2 = if (backgroundBlurRadius) 1 else 0
                 double1 = if (launchingActivityFromNotification) 1.0 else 0.0
             },
-            { "Setting isExpanded to $str1: forceWindowCollapsed $bool1, " +
+            {
+                "Setting isExpanded to $str1: forceWindowCollapsed $bool1, " +
                     "isKeyguardShowingAndNotOccluded $bool2, panelVisible $bool3, " +
                     "keyguardFadingAway $bool4, bouncerShowing $int1," +
                     "headsUpNotificationShowing $int2, scrimsVisibilityNotTransparent $long1," +
-                    "backgroundBlurRadius $long2, launchingActivityFromNotification $double1"}
+                    "backgroundBlurRadius $long2, launchingActivityFromNotification $double1"
+            },
         )
     }
 
@@ -95,7 +93,7 @@
             TAG,
             DEBUG,
             { bool1 = visible },
-            { "Updating shade, should be visible and focusable: $bool1" }
+            { "Updating shade, should be visible and focusable: $bool1" },
         )
     }
 
@@ -104,7 +102,19 @@
             TAG,
             DEBUG,
             { bool1 = focusable },
-            { "Updating shade, should be focusable : $bool1" }
+            { "Updating shade, should be focusable : $bool1" },
+        )
+    }
+
+    fun logConfigChangeWidthAdjust(originalWidth: Int, newWidth: Int) {
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                int1 = originalWidth
+                int2 = newWidth
+            },
+            { "Config changed. SceneWindowRootView width updating from $int1 to $int2." },
         )
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
index 103449b..ee8ce17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.verify;
 
 import android.app.UiModeManager;
+import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.graphics.drawable.GradientDrawable;
 import android.platform.test.annotations.EnableFlags;
@@ -78,6 +79,12 @@
         mNightMode = mUiModeManager.getNightMode();
         mUiModeManager.setNightMode(MODE_NIGHT_YES);
 
+        // Programmatically update the resource's configuration to night mode to reduce flakiness
+        Configuration nightConfig = new Configuration(mContext.getResources().getConfiguration());
+        nightConfig.uiMode = Configuration.UI_MODE_NIGHT_YES;
+        mContext.getResources().updateConfiguration(nightConfig,
+                mContext.getResources().getDisplayMetrics(), null);
+
         mSpyContext = spy(mContext);
         doNothing().when(mSpyContext).startActivity(any());
 
@@ -101,6 +108,8 @@
 
     @Test
     public void insetsOnDarkTheme_menuOnLeft_matchInsets() {
+        // In dark theme, the inset is not 0 to avoid weird spacing issue between the menu and
+        // the edge of the screen.
         mMenuView.onConfigurationChanged(/* newConfig= */ null);
         final InstantInsetLayerDrawable insetLayerDrawable =
                 (InstantInsetLayerDrawable) mMenuView.getBackground();
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
index 4cb2ce1..5d251bd 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -195,23 +195,25 @@
         try {
             performGlobalInitialization();
 
+            /*
+             * If the class has @DisabledOnRavenwood, then we'll delegate to
+             * ClassSkippingTestRunner, which simply skips it.
+             *
+             * We need to do it before instantiating TestClass for b/367694651.
+             */
+            if (isOnRavenwood() && !RavenwoodAwareTestRunnerHook.shouldRunClassOnRavenwood(
+                    testClass)) {
+                mRealRunner = new ClassSkippingTestRunner(testClass);
+                mDescription = mRealRunner.getDescription();
+                return;
+            }
+
             mTestClass = new TestClass(testClass);
 
             Log.v(TAG, "RavenwoodAwareTestRunner starting for " + testClass.getCanonicalName());
 
             onRunnerInitializing();
 
-            /*
-             * If the class has @DisabledOnRavenwood, then we'll delegate to
-             * ClassSkippingTestRunner, which simply skips it.
-             */
-            if (isOnRavenwood() && !RavenwoodAwareTestRunnerHook.shouldRunClassOnRavenwood(
-                    mTestClass.getJavaClass())) {
-                mRealRunner = new ClassSkippingTestRunner(mTestClass);
-                mDescription = mRealRunner.getDescription();
-                return;
-            }
-
             // Find the real runner.
             final Class<? extends Runner> realRunnerClass;
             final InnerRunner innerRunnerAnnotation = mTestClass.getAnnotation(InnerRunner.class);
@@ -444,14 +446,11 @@
      * filter.
      */
     private static class ClassSkippingTestRunner extends Runner implements Filterable {
-        private final TestClass mTestClass;
         private final Description mDescription;
         private boolean mFilteredOut;
 
-        ClassSkippingTestRunner(TestClass testClass) {
-            mTestClass = testClass;
-            mDescription = Description.createTestDescription(
-                    testClass.getJavaClass(), testClass.getJavaClass().getSimpleName());
+        ClassSkippingTestRunner(Class<?> testClass) {
+            mDescription = Description.createTestDescription(testClass, testClass.getSimpleName());
             mFilteredOut = false;
         }
 
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerCallbackTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerCallbackTest.java
index 6d8fb98..09ed12d 100644
--- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerCallbackTest.java
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerCallbackTest.java
@@ -17,12 +17,14 @@
 
 import static org.junit.Assume.assumeTrue;
 
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.NoRavenizer;
 import android.platform.test.ravenwood.RavenwoodAwareTestRunner;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import org.junit.AfterClass;
+import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
@@ -353,4 +355,34 @@
         public void test2() {
         }
     }
+
+    /**
+     * The test class is unloadable, but has a @DisabledOnRavenwood.
+     */
+    @RunWith(AndroidJUnit4.class)
+    @DisabledOnRavenwood
+    // CHECKSTYLE:OFF
+    @Expected("""
+    testRunStarted: classes
+    testSuiteStarted: classes
+    testSuiteStarted: ClassUnloadbleTest(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassUnloadbleTest)
+    testIgnored: ClassUnloadbleTest(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassUnloadbleTest)
+    testSuiteFinished: ClassUnloadbleTest(com.android.ravenwoodtest.runnercallbacktests.RavenwoodRunnerCallbackTest$ClassUnloadbleTest)
+    testSuiteFinished: classes
+    testRunFinished: 0,0,0,1
+    """)
+    // CHECKSTYLE:ON
+    public static class ClassUnloadbleTest {
+        static {
+            Assert.fail("Class unloadable!");
+        }
+
+        @Test
+        public void test1() {
+        }
+
+        @Test
+        public void test2() {
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 68d0ad2..a459ea9 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -173,6 +173,15 @@
                     "include-filter": "com.android.server.wm.BackgroundActivityStart*"
                 }
             ]
+        },
+        {
+            "name": "CtsOsTestCases",
+            "file_patterns": ["StorageManagerService\\.java"],
+            "options": [
+                {
+                    "include-filter": "android.os.storage.cts.StorageStatsManagerTest"
+                }
+            ]
         }
    ]
 }
diff --git a/services/core/java/com/android/server/cpu/CpuMonitorService.java b/services/core/java/com/android/server/cpu/CpuMonitorService.java
index 88ff7e4..2cadbc58 100644
--- a/services/core/java/com/android/server/cpu/CpuMonitorService.java
+++ b/services/core/java/com/android/server/cpu/CpuMonitorService.java
@@ -216,7 +216,7 @@
 
     @Override
     public void onBootPhase(int phase) {
-        if (phase != PHASE_BOOT_COMPLETED) {
+        if (phase != PHASE_BOOT_COMPLETED || mHandler == null) {
             return;
         }
         Slogf.i(TAG, "Stopping periodic cpuset reading on boot complete");
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index 4b2c12a..63bd9ab 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -389,7 +389,7 @@
             // Reload gnss config for no SIM case
             mGnssConfiguration.reloadGpsProperties();
         }
-        if (Flags.enableNiSuplMessageInjectionByCarrierConfig()) {
+        if (Flags.enableNiSuplMessageInjectionByCarrierConfigBugfix()) {
             updateNiSuplMessageListenerRegistration(
                     mGnssConfiguration.isNiSuplMessageInjectionEnabled());
         }
@@ -538,7 +538,7 @@
         intentFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
         mContext.registerReceiver(mIntentReceiver, intentFilter, null, mHandler);
 
-        if (!Flags.enableNiSuplMessageInjectionByCarrierConfig()) {
+        if (!Flags.enableNiSuplMessageInjectionByCarrierConfigBugfix()) {
             updateNiSuplMessageListenerRegistration(
                     mGnssConfiguration.isNiSuplMessageInjectionEnabled());
         }
@@ -1672,7 +1672,7 @@
         if (dumpAll) {
             mNetworkTimeHelper.dump(pw);
             pw.println("mSupportsPsds=" + mSupportsPsds);
-            if (Flags.enableNiSuplMessageInjectionByCarrierConfig()) {
+            if (Flags.enableNiSuplMessageInjectionByCarrierConfigBugfix()) {
                 pw.println("mNiSuplMessageListenerRegistered="
                         + mNiSuplMessageListenerRegistered);
             }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperData.java b/services/core/java/com/android/server/wallpaper/WallpaperData.java
index a698429..15f86e9 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperData.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperData.java
@@ -78,7 +78,7 @@
     /**
      * The component name of the currently set live wallpaper.
      */
-    ComponentName wallpaperComponent;
+    private ComponentName mWallpaperComponent;
 
     // TODO(b/347235611) Remove this field
     /**
@@ -195,7 +195,7 @@
      */
     WallpaperData(WallpaperData source) {
         this.userId = source.userId;
-        this.wallpaperComponent = source.wallpaperComponent;
+        this.mWallpaperComponent = source.mWallpaperComponent;
         this.mWhich = source.mWhich;
         this.wallpaperId = source.wallpaperId;
         this.cropHint.set(source.cropHint);
@@ -230,6 +230,14 @@
         return result;
     }
 
+    ComponentName getComponent() {
+        return mWallpaperComponent;
+    }
+
+    void setComponent(ComponentName componentName) {
+        this.mWallpaperComponent = componentName;
+    }
+
     @Override
     public String toString() {
         StringBuilder out = new StringBuilder(defaultString(this));
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
index b15facb..e3e83b3 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -189,13 +189,13 @@
 
                         String comp = parser.getAttributeValue(null, "component");
                         if (removeNextWallpaperComponent()) {
-                            wallpaperToParse.wallpaperComponent = comp != null
+                            wallpaperToParse.setComponent(comp != null
                                     ? ComponentName.unflattenFromString(comp)
-                                    : null;
-                            if (wallpaperToParse.wallpaperComponent == null
-                                    || "android".equals(wallpaperToParse.wallpaperComponent
+                                    : null);
+                            if (wallpaperToParse.getComponent() == null
+                                    || "android".equals(wallpaperToParse.getComponent()
                                     .getPackageName())) {
-                                wallpaperToParse.wallpaperComponent = mImageWallpaper;
+                                wallpaperToParse.setComponent(mImageWallpaper);
                             }
                         } else {
                             wallpaperToParse.nextWallpaperComponent = comp != null
@@ -219,7 +219,7 @@
                             Slog.v(TAG, "primaryColors:" + wallpaper.primaryColors);
                             Slog.v(TAG, "mName:" + wallpaper.name);
                             if (removeNextWallpaperComponent()) {
-                                Slog.v(TAG, "mWallpaperComponent:" + wallpaper.wallpaperComponent);
+                                Slog.v(TAG, "mWallpaperComponent:" + wallpaper.getComponent());
                             } else {
                                 Slog.v(TAG, "mNextWallpaperComponent:"
                                         + wallpaper.nextWallpaperComponent);
@@ -340,7 +340,7 @@
                 getAttributeInt(parser, "totalCropTop", 0),
                 getAttributeInt(parser, "totalCropRight", 0),
                 getAttributeInt(parser, "totalCropBottom", 0));
-        ComponentName componentName = removeNextWallpaperComponent() ? wallpaper.wallpaperComponent
+        ComponentName componentName = removeNextWallpaperComponent() ? wallpaper.getComponent()
                 : wallpaper.nextWallpaperComponent;
         if (multiCrop() && mImageWallpaper.equals(componentName)) {
             wallpaper.mCropHints = new SparseArray<>();
@@ -480,7 +480,7 @@
         out.startTag(null, tag);
         out.attributeInt(null, "id", wallpaper.wallpaperId);
 
-        if (multiCrop() && mImageWallpaper.equals(wallpaper.wallpaperComponent)) {
+        if (multiCrop() && mImageWallpaper.equals(wallpaper.getComponent())) {
             if (wallpaper.mCropHints == null) {
                 Slog.e(TAG, "cropHints should not be null when saved");
                 wallpaper.mCropHints = new SparseArray<>();
@@ -580,10 +580,10 @@
         }
 
         out.attribute(null, "name", wallpaper.name);
-        if (wallpaper.wallpaperComponent != null
-                && !wallpaper.wallpaperComponent.equals(mImageWallpaper)) {
+        if (wallpaper.getComponent() != null
+                && !wallpaper.getComponent().equals(mImageWallpaper)) {
             out.attribute(null, "component",
-                    wallpaper.wallpaperComponent.flattenToShortString());
+                    wallpaper.getComponent().flattenToShortString());
         }
 
         if (wallpaper.allowBackup) {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 6cc37dd..4754ffb 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -276,7 +276,7 @@
             final boolean isMigration = moved && lockWallpaperChanged;
             final boolean isRestore = moved && !isMigration;
             final boolean isAppliedToLock = (wallpaper.mWhich & FLAG_LOCK) != 0;
-            final boolean needsUpdate = wallpaper.wallpaperComponent == null
+            final boolean needsUpdate = wallpaper.getComponent() == null
                     || event != CLOSE_WRITE // includes the MOVED_TO case
                     || wallpaper.imageWallpaperPending;
 
@@ -527,7 +527,7 @@
      * @return true unless the wallpaper changed during the color computation
      */
     private boolean extractColors(WallpaperData wallpaper) {
-        if (offloadColorExtraction()) return !mImageWallpaper.equals(wallpaper.wallpaperComponent);
+        if (offloadColorExtraction()) return !mImageWallpaper.equals(wallpaper.getComponent());
         String cropFile = null;
         boolean defaultImageWallpaper = false;
         int wallpaperId;
@@ -550,8 +550,8 @@
 
         synchronized (mLock) {
             // Not having a wallpaperComponent means it's a lock screen wallpaper.
-            final boolean imageWallpaper = mImageWallpaper.equals(wallpaper.wallpaperComponent)
-                    || wallpaper.wallpaperComponent == null;
+            final boolean imageWallpaper = mImageWallpaper.equals(wallpaper.getComponent())
+                    || wallpaper.getComponent() == null;
             if (imageWallpaper && wallpaper.getCropFile().exists()) {
                 cropFile = wallpaper.getCropFile().getAbsolutePath();
             } else if (imageWallpaper && !wallpaper.cropExists() && !wallpaper.sourceExists()) {
@@ -824,13 +824,13 @@
                 return;
             }
             TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG);
-            t.traceBegin("WPMS.connectLocked-" + wallpaper.wallpaperComponent);
+            t.traceBegin("WPMS.connectLocked-" + wallpaper.getComponent());
             if (DEBUG) Slog.v(TAG, "Adding window token: " + mToken);
             mWindowManagerInternal.addWindowToken(mToken, TYPE_WALLPAPER, mDisplayId,
                     null /* options */);
             mWindowManagerInternal.setWallpaperShowWhenLocked(
                     mToken, (wallpaper.mWhich & FLAG_LOCK) != 0);
-            if (multiCrop() && mImageWallpaper.equals(wallpaper.wallpaperComponent)) {
+            if (multiCrop() && mImageWallpaper.equals(wallpaper.getComponent())) {
                 mWindowManagerInternal.setWallpaperCropHints(mToken,
                         mWallpaperCropper.getRelativeCropHints(wallpaper));
             } else {
@@ -906,7 +906,7 @@
                 }
 
                 if (!mWallpaper.wallpaperUpdating && mWallpaper.userId == mCurrentUserId) {
-                    Slog.w(TAG, "Wallpaper reconnect timed out for " + mWallpaper.wallpaperComponent
+                    Slog.w(TAG, "Wallpaper reconnect timed out for " + mWallpaper.getComponent()
                             + ", reverting to built-in wallpaper!");
                     clearWallpaperLocked(mWallpaper.mWhich, mWallpaper.userId, false, null);
                 }
@@ -1035,9 +1035,9 @@
         public void onServiceDisconnected(ComponentName name) {
             synchronized (mLock) {
                 Slog.w(TAG, "Wallpaper service gone: " + name);
-                if (!Objects.equals(name, mWallpaper.wallpaperComponent)) {
+                if (!Objects.equals(name, mWallpaper.getComponent())) {
                     Slog.e(TAG, "Does not match expected wallpaper component "
-                            + mWallpaper.wallpaperComponent);
+                            + mWallpaper.getComponent());
                 }
                 mService = null;
                 forEachDisplayConnector(connector -> connector.mEngine = null);
@@ -1065,7 +1065,7 @@
             fgHandler.postDelayed(mResetRunnable, WALLPAPER_RECONNECT_TIMEOUT_MS);
             if (DEBUG_LIVE) {
                 Slog.i(TAG,
-                        "Started wallpaper reconnect timeout for " + mWallpaper.wallpaperComponent);
+                        "Started wallpaper reconnect timeout for " + mWallpaper.getComponent());
             }
         }
 
@@ -1081,7 +1081,7 @@
                     return;
                 }
 
-                final ComponentName wpService = mWallpaper.wallpaperComponent;
+                final ComponentName wpService = mWallpaper.getComponent();
                 // The broadcast of package update could be delayed after service disconnected. Try
                 // to re-bind the service for 10 seconds.
                 mWallpaper.mBindSource = BindSource.CONNECTION_TRY_TO_REBIND;
@@ -1110,7 +1110,7 @@
                 // The wallpaper disappeared.  If this isn't a system-default one, track
                 // crashes and fall back to default if it continues to misbehave.
                 if (this == mWallpaper.connection) {
-                    final ComponentName wpService = mWallpaper.wallpaperComponent;
+                    final ComponentName wpService = mWallpaper.getComponent();
                     if (!mWallpaper.wallpaperUpdating
                             && mWallpaper.userId == mCurrentUserId
                             && !Objects.equals(mDefaultWallpaperComponent, wpService)
@@ -1188,7 +1188,7 @@
             synchronized (mLock) {
                 // Do not broadcast changes on ImageWallpaper since it's handled
                 // internally by this class.
-                boolean isImageWallpaper = mImageWallpaper.equals(mWallpaper.wallpaperComponent);
+                boolean isImageWallpaper = mImageWallpaper.equals(mWallpaper.getComponent());
                 if (isImageWallpaper && (!offloadColorExtraction() || primaryColors == null)) {
                     return;
                 }
@@ -1303,7 +1303,7 @@
                 if (mNewWallpaper.mWhich == FLAG_SYSTEM) {
                     // New wp is system only, so old system+lock is now lock only
                     final boolean originalIsStatic = mImageWallpaper.equals(
-                            mOriginalSystem.wallpaperComponent);
+                            mOriginalSystem.getComponent());
                     if (originalIsStatic) {
                         // Static wp: image file rename has already been tried via
                         // migrateStaticSystemToLockWallpaperLocked() and added to the lock wp map
@@ -1314,8 +1314,7 @@
                             if (DEBUG) {
                                 Slog.v(TAG, "static system+lock to system success");
                             }
-                            lockWp.wallpaperComponent =
-                                    mOriginalSystem.wallpaperComponent;
+                            lockWp.setComponent(mOriginalSystem.getComponent());
                             lockWp.connection = mOriginalSystem.connection;
                             lockWp.connection.mWallpaper = lockWp;
                             mOriginalSystem.mWhich = FLAG_LOCK;
@@ -1376,7 +1375,7 @@
                     return;
                 }
                 for (WallpaperData wallpaper: getWallpapers()) {
-                    final ComponentName wpService = wallpaper.wallpaperComponent;
+                    final ComponentName wpService = wallpaper.getComponent();
                     if (wpService != null && wpService.getPackageName().equals(packageName)) {
                         if (DEBUG_LIVE) {
                             Slog.i(TAG, "Wallpaper " + wpService + " update has finished");
@@ -1402,8 +1401,8 @@
                     return;
                 }
                 for (WallpaperData wallpaper: getWallpapers()) {
-                    if (wallpaper.wallpaperComponent != null
-                            && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
+                    if (wallpaper.getComponent() != null
+                            && wallpaper.getComponent().getPackageName().equals(packageName)) {
                         doPackagesChangedLocked(true, wallpaper);
                     }
                 }
@@ -1417,10 +1416,10 @@
                     return;
                 }
                 for (WallpaperData wallpaper: getWallpapers()) {
-                    if (wallpaper.wallpaperComponent != null
-                            && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
+                    if (wallpaper.getComponent() != null
+                            && wallpaper.getComponent().getPackageName().equals(packageName)) {
                         if (DEBUG_LIVE) {
-                            Slog.i(TAG, "Wallpaper service " + wallpaper.wallpaperComponent
+                            Slog.i(TAG, "Wallpaper service " + wallpaper.getComponent()
                                     + " is updating");
                         }
                         wallpaper.wallpaperUpdating = true;
@@ -1462,15 +1461,15 @@
 
         boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) {
             boolean changed = false;
-            if (wallpaper.wallpaperComponent != null) {
-                int change = isPackageDisappearing(wallpaper.wallpaperComponent
+            if (wallpaper.getComponent() != null) {
+                int change = isPackageDisappearing(wallpaper.getComponent()
                         .getPackageName());
                 if (change == PACKAGE_PERMANENT_CHANGE
                         || change == PACKAGE_TEMPORARY_CHANGE) {
                     changed = true;
                     if (doit) {
                         Slog.w(TAG, "Wallpaper uninstalled, removing: "
-                                + wallpaper.wallpaperComponent);
+                                + wallpaper.getComponent());
                         clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, false, null);
                     }
                 }
@@ -1485,15 +1484,15 @@
                     }
                 }
             }
-            if (wallpaper.wallpaperComponent != null
-                    && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
+            if (wallpaper.getComponent() != null
+                    && isPackageModified(wallpaper.getComponent().getPackageName())) {
                 try {
-                    mContext.getPackageManager().getServiceInfo(wallpaper.wallpaperComponent,
+                    mContext.getPackageManager().getServiceInfo(wallpaper.getComponent(),
                             PackageManager.MATCH_DIRECT_BOOT_AWARE
                                     | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
                 } catch (NameNotFoundException e) {
                     Slog.w(TAG, "Wallpaper component gone, removing: "
-                            + wallpaper.wallpaperComponent);
+                            + wallpaper.getComponent());
                     clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, false, null);
                 }
             }
@@ -1636,8 +1635,8 @@
         // sure we have something to render
         boolean isImageComponent;
         if (removeNextWallpaperComponent()) {
-            isImageComponent = wallpaper.wallpaperComponent == null
-                    || mImageWallpaper.equals(wallpaper.wallpaperComponent);
+            isImageComponent = wallpaper.getComponent() == null
+                    || mImageWallpaper.equals(wallpaper.getComponent());
         } else {
             isImageComponent = mImageWallpaper.equals(wallpaper.nextWallpaperComponent);
         }
@@ -1892,10 +1891,10 @@
 
             final ComponentName cname;
             if (removeNextWallpaperComponent()) {
-                cname = wallpaper.wallpaperComponent;
+                cname = wallpaper.getComponent();
             } else {
-                cname = (wallpaper.wallpaperComponent != null)
-                        ? wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
+                cname = (wallpaper.getComponent() != null)
+                        ? wallpaper.getComponent() : wallpaper.nextWallpaperComponent;
             }
             if (!bindWallpaperComponentLocked(cname, true, false, wallpaper, reply)) {
                 // We failed to bind the desired wallpaper, but that might
@@ -1927,7 +1926,7 @@
             // We might end up persisting the current wallpaper data
             // while locked, so pretend like the component was actually
             // bound into place
-            wallpaper.wallpaperComponent = wallpaper.nextWallpaperComponent;
+            wallpaper.setComponent(wallpaper.nextWallpaperComponent);
         }
         final WallpaperData fallback = new WallpaperData(wallpaper.userId, wallpaper.mWhich);
 
@@ -2004,7 +2003,7 @@
 
             // lock only case: set the system wallpaper component to both screens
             if (which == FLAG_LOCK) {
-                component = wallpaper.wallpaperComponent;
+                component = wallpaper.getComponent();
                 finalWhich = FLAG_LOCK | FLAG_SYSTEM;
             } else {
                 component = null;
@@ -2310,7 +2309,7 @@
             checkPermission(READ_WALLPAPER_INTERNAL);
             WallpaperData wallpaper = (which == FLAG_LOCK) ? mLockWallpaperMap.get(userId)
                     : mWallpaperMap.get(userId);
-            if (wallpaper == null || !mImageWallpaper.equals(wallpaper.wallpaperComponent)) {
+            if (wallpaper == null || !mImageWallpaper.equals(wallpaper.getComponent())) {
                 return null;
             }
             SparseArray<Rect> relativeSuggestedCrops =
@@ -2760,7 +2759,7 @@
             WallpaperData wallpaperData = (which == FLAG_LOCK ? mLockWallpaperMap : mWallpaperMap)
                     .get(mCurrentUserId);
             if (wallpaperData == null) return false;
-            return mImageWallpaper.equals(wallpaperData.wallpaperComponent);
+            return mImageWallpaper.equals(wallpaperData.getComponent());
         }
     }
 
@@ -2996,7 +2995,7 @@
             final WallpaperData originalSystemWallpaper = mWallpaperMap.get(userId);
             final boolean systemIsStatic =
                     originalSystemWallpaper != null && mImageWallpaper.equals(
-                            originalSystemWallpaper.wallpaperComponent);
+                            originalSystemWallpaper.getComponent());
             final boolean systemIsBoth = mLockWallpaperMap.get(userId) == null;
 
             /* If we're setting system but not lock, and lock is currently sharing the system
@@ -3190,7 +3189,7 @@
                 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
             }
             final boolean systemIsStatic = mImageWallpaper.equals(
-                    originalSystemWallpaper.wallpaperComponent);
+                    originalSystemWallpaper.getComponent());
             final boolean systemIsBoth = mLockWallpaperMap.get(userId) == null;
 
             if (which == FLAG_SYSTEM && systemIsBoth && systemIsStatic) {
@@ -3212,7 +3211,7 @@
                         liveSync = new WallpaperDestinationChangeHandler(
                         newWallpaper);
                 boolean same = changingToSame(name, newWallpaper.connection,
-                        newWallpaper.wallpaperComponent);
+                        newWallpaper.getComponent());
 
                 /*
                  * If we have a shared system+lock wallpaper, and we reapply the same wallpaper
@@ -3243,7 +3242,7 @@
                         }
                     }
                     boolean lockBitmapCleared = false;
-                    if (!mImageWallpaper.equals(newWallpaper.wallpaperComponent)) {
+                    if (!mImageWallpaper.equals(newWallpaper.getComponent())) {
                         clearWallpaperBitmaps(newWallpaper);
                         lockBitmapCleared = newWallpaper.mWhich == FLAG_LOCK;
                     }
@@ -3324,7 +3323,7 @@
         }
         // Has the component changed?
         if (!force && changingToSame(componentName, wallpaper.connection,
-                wallpaper.wallpaperComponent)) {
+                wallpaper.getComponent())) {
             try {
                 if (DEBUG_LIVE) {
                     Slog.v(TAG, "Changing to the same component, ignoring");
@@ -3461,7 +3460,7 @@
                 return false;
             }
             maybeDetachLastWallpapers(wallpaper);
-            wallpaper.wallpaperComponent = componentName;
+            wallpaper.setComponent(componentName);
             wallpaper.connection = newConn;
             newConn.mReply = reply;
             updateCurrentWallpapers(wallpaper);
@@ -3586,7 +3585,7 @@
     }
 
     private void clearWallpaperComponentLocked(WallpaperData wallpaper) {
-        wallpaper.wallpaperComponent = null;
+        wallpaper.setComponent(null);
         detachWallpaperLocked(wallpaper);
     }
 
@@ -3831,7 +3830,7 @@
             wallpaper.wallpaperId = makeWallpaperIdLocked();    // always bump id at restore
             wallpaper.allowBackup = true;   // by definition if it was restored
             ComponentName componentName =
-                    removeNextWallpaperComponent() ? wallpaper.wallpaperComponent
+                    removeNextWallpaperComponent() ? wallpaper.getComponent()
                             : wallpaper.nextWallpaperComponent;
             if (componentName != null && !componentName.equals(mImageWallpaper)) {
                 wallpaper.mBindSource = BindSource.RESTORE_SETTINGS_LIVE_SUCCESS;
@@ -3907,7 +3906,7 @@
         if (multiCrop()) pw.print("  mCropHints="); pw.println(wallpaper.mCropHints);
         pw.print("  mName=");  pw.println(wallpaper.name);
         pw.print("  mAllowBackup="); pw.println(wallpaper.allowBackup);
-        pw.print("  mWallpaperComponent="); pw.println(wallpaper.wallpaperComponent);
+        pw.print("  mWallpaperComponent="); pw.println(wallpaper.getComponent());
         pw.print("  mWallpaperDimAmount="); pw.println(wallpaper.mWallpaperDimAmount);
         pw.print("  isColorExtracted="); pw.println(wallpaper.mIsColorExtractedFromDim);
         pw.println("  mUidToDimAmount:");
diff --git a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
index cc6904f..156d8a0 100644
--- a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
+++ b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
@@ -103,7 +103,7 @@
         final TaskDisplayArea displayArea = task.getDisplayArea();
         final Rect screenBounds = displayArea.getBounds();
         final Size idealSize = calculateIdealSize(screenBounds, DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
-        if (!DesktopModeFlags.DYNAMIC_INITIAL_BOUNDS.isEnabled(activity.mWmService.mContext)) {
+        if (!DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isEnabled()) {
             return centerInScreen(idealSize, screenBounds);
         }
         if (activity.mAppCompatController.getAppCompatAspectRatioOverrides()
diff --git a/services/core/java/com/android/server/wm/DesktopModeHelper.java b/services/core/java/com/android/server/wm/DesktopModeHelper.java
index 61fbb96..da76317 100644
--- a/services/core/java/com/android/server/wm/DesktopModeHelper.java
+++ b/services/core/java/com/android/server/wm/DesktopModeHelper.java
@@ -35,8 +35,8 @@
             "persist.wm.debug.desktop_mode_enforce_device_restrictions", true);
 
     /** Whether desktop mode is enabled. */
-    static boolean isDesktopModeEnabled(@NonNull Context context) {
-        return DesktopModeFlags.DESKTOP_WINDOWING_MODE.isEnabled(context);
+    static boolean isDesktopModeEnabled() {
+        return DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODE.isEnabled();
     }
 
     /**
@@ -60,7 +60,7 @@
      * Return {@code true} if desktop mode can be entered on the current device.
      */
     static boolean canEnterDesktopMode(@NonNull Context context) {
-        return isDesktopModeEnabled(context)
+        return isDesktopModeEnabled()
                 && (!shouldEnforceDeviceRestrictions() || isDesktopModeSupported(context));
     }
 }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 9d46529..7c3f0f2 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -35,6 +35,7 @@
 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.window.TaskFragmentAnimationParams.DEFAULT_ANIMATION_BACKGROUND_COLOR;
+import static android.window.flags.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ANIM;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
@@ -115,7 +116,6 @@
 import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 import com.android.server.wm.utils.AlwaysTruePredicate;
-import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -457,7 +457,7 @@
         source.setFrame(provider.getArbitraryRectangle())
                 .updateSideHint(getBounds())
                 .setBoundingRects(provider.getBoundingRects());
-        if (Flags.enableCaptionCompatInsetForceConsumption()) {
+        if (ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION.isEnabled()) {
             source.setFlags(provider.getFlags());
         }
         mLocalInsetsSources.put(id, source);
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 8c4448e..155e73c 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -1808,9 +1808,30 @@
     ATRACE_CALL();
     JNIEnv* env = jniEnv();
 
-    for (int32_t iconId = static_cast<int32_t>(PointerIconStyle::TYPE_CONTEXT_MENU);
-         iconId <= static_cast<int32_t>(PointerIconStyle::TYPE_HANDWRITING); ++iconId) {
-        const PointerIconStyle pointerIconStyle = static_cast<PointerIconStyle>(iconId);
+    constexpr static std::array ADDITIONAL_STYLES{PointerIconStyle::TYPE_CONTEXT_MENU,
+                                                  PointerIconStyle::TYPE_HAND,
+                                                  PointerIconStyle::TYPE_HELP,
+                                                  PointerIconStyle::TYPE_WAIT,
+                                                  PointerIconStyle::TYPE_CELL,
+                                                  PointerIconStyle::TYPE_CROSSHAIR,
+                                                  PointerIconStyle::TYPE_TEXT,
+                                                  PointerIconStyle::TYPE_VERTICAL_TEXT,
+                                                  PointerIconStyle::TYPE_ALIAS,
+                                                  PointerIconStyle::TYPE_COPY,
+                                                  PointerIconStyle::TYPE_NO_DROP,
+                                                  PointerIconStyle::TYPE_ALL_SCROLL,
+                                                  PointerIconStyle::TYPE_HORIZONTAL_DOUBLE_ARROW,
+                                                  PointerIconStyle::TYPE_VERTICAL_DOUBLE_ARROW,
+                                                  PointerIconStyle::TYPE_TOP_RIGHT_DOUBLE_ARROW,
+                                                  PointerIconStyle::TYPE_TOP_LEFT_DOUBLE_ARROW,
+                                                  PointerIconStyle::TYPE_ZOOM_IN,
+                                                  PointerIconStyle::TYPE_ZOOM_OUT,
+                                                  PointerIconStyle::TYPE_GRAB,
+                                                  PointerIconStyle::TYPE_GRABBING,
+                                                  PointerIconStyle::TYPE_HANDWRITING,
+                                                  PointerIconStyle::TYPE_SPOT_HOVER};
+
+    for (const auto pointerIconStyle : ADDITIONAL_STYLES) {
         PointerIcon pointerIcon = loadPointerIcon(env, displayId, pointerIconStyle);
         (*outResources)[pointerIconStyle] = toSpriteIcon(pointerIcon);
         if (!pointerIcon.bitmapFrames.empty()) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
index 8b65337..32135f1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
@@ -22,9 +22,10 @@
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.never;
@@ -36,6 +37,7 @@
 import android.media.projection.MediaProjectionInfo;
 import android.media.projection.MediaProjectionManager;
 import android.os.Process;
+import android.os.RemoteException;
 import android.platform.test.annotations.RequiresFlagsDisabled;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
@@ -137,9 +139,17 @@
 
         mSensitiveContentProtectionManagerService.mNotificationListener =
                 spy(mSensitiveContentProtectionManagerService.mNotificationListener);
-        doCallRealMethod()
-                .when(mSensitiveContentProtectionManagerService.mNotificationListener)
-                .onListenerConnected();
+
+        // Unexpected NLS interactions when registered cause test flakes. For purposes of this test,
+        // the test will control any NLS calls.
+        try {
+            doNothing().when(mSensitiveContentProtectionManagerService.mNotificationListener)
+                    .registerAsSystemService(any(), any(), anyInt());
+            doNothing().when(mSensitiveContentProtectionManagerService.mNotificationListener)
+                    .unregisterAsSystemService();
+        } catch (RemoteException e) {
+            // Intra-process call, should never happen.
+        }
 
         // Setup RankingMap and two possilbe rankings
         when(mSensitiveRanking.hasSensitiveContent()).thenReturn(true);
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
index 15ae463..0b762df 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
@@ -290,7 +290,7 @@
 
         final WallpaperData fallbackData = mService.mFallbackWallpaper;
         assertEquals("Fallback wallpaper component should be ImageWallpaper.",
-                sImageWallpaperComponentName, fallbackData.wallpaperComponent);
+                sImageWallpaperComponentName, fallbackData.getComponent());
 
         verifyLastWallpaperData(USER_SYSTEM, sDefaultWallpaperComponent);
         verifyDisplayData();
@@ -580,7 +580,7 @@
         final WallpaperData lastData = mService.mLastWallpaper;
         assertNotNull("Last wallpaper must not be null", lastData);
         assertEquals("Last wallpaper component must be equals.", expectedComponent,
-                lastData.wallpaperComponent);
+                lastData.getComponent());
         assertEquals("The user id in last wallpaper should be the last switched user",
                 lastUserId, lastData.userId);
         assertNotNull("Must exist user data connection on last wallpaper data",
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 41223db..2ef0573 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -5038,7 +5038,7 @@
          * {@code true} - Enable NI SUPL message injection.
          */
         @FlaggedApi(android.location.flags.Flags
-                .FLAG_ENABLE_NI_SUPL_MESSAGE_INJECTION_BY_CARRIER_CONFIG)
+                .FLAG_ENABLE_NI_SUPL_MESSAGE_INJECTION_BY_CARRIER_CONFIG_BUGFIX)
         public static final String KEY_ENABLE_NI_SUPL_MESSAGE_INJECTION_BOOL =
                 KEY_PREFIX + "enable_ni_supl_message_injection_bool";
 
@@ -5059,7 +5059,7 @@
             defaults.putInt(KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
                     SUPL_EMERGENCY_MODE_TYPE_CP_ONLY);
             defaults.putStringArray(KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY, null);
-            if (android.location.flags.Flags.enableNiSuplMessageInjectionByCarrierConfig()) {
+            if (android.location.flags.Flags.enableNiSuplMessageInjectionByCarrierConfigBugfix()) {
                 defaults.putBoolean(KEY_ENABLE_NI_SUPL_MESSAGE_INJECTION_BOOL, false);
             }
             return defaults;
diff --git a/tests/Tracing/Android.bp b/tests/Tracing/Android.bp
index 5a7f12f..90998e6 100644
--- a/tests/Tracing/Android.bp
+++ b/tests/Tracing/Android.bp
@@ -15,7 +15,7 @@
     },
     // Include some source files directly to be able to access package members
     srcs: ["src/**/*.java"],
-    libs: ["android.test.runner"],
+    libs: ["android.test.runner.stubs.system"],
     static_libs: [
         "junit",
         "androidx.test.rules",
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
index 290e7be..9467434 100644
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
@@ -22,6 +22,7 @@
 import com.google.android.lint.aidl.EnforcePermissionDetector
 import com.google.android.lint.aidl.PermissionAnnotationDetector
 import com.google.android.lint.aidl.SimpleManualPermissionEnforcementDetector
+import com.google.android.lint.aidl.SimpleRequiresNoPermissionDetector
 import com.google.auto.service.AutoService
 
 @AutoService(IssueRegistry::class)
@@ -34,6 +35,7 @@
             EnforcePermissionDetector.ISSUE_MISUSING_ENFORCE_PERMISSION,
             PermissionAnnotationDetector.ISSUE_MISSING_PERMISSION_ANNOTATION,
             SimpleManualPermissionEnforcementDetector.ISSUE_SIMPLE_MANUAL_PERMISSION_ENFORCEMENT,
+            SimpleRequiresNoPermissionDetector.ISSUE_SIMPLE_REQUIRES_NO_PERMISSION,
     )
 
     override val api: Int
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetector.kt
new file mode 100644
index 0000000..1a13c02
--- /dev/null
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetector.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.lint.aidl
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UastCallKind
+import org.jetbrains.uast.UBlockExpression
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UMethod
+import org.jetbrains.uast.visitor.AbstractUastVisitor
+
+/**
+ * Ensures all AIDL implementations hosted by system_server which don't call other methods are
+ * annotated with @RequiresNoPermission. AIDL Interfaces part of `exemptAidlInterfaces` are skipped
+ * during this search to ensure the detector targets only new AIDL Interfaces.
+ */
+class SimpleRequiresNoPermissionDetector : AidlImplementationDetector() {
+    override fun visitAidlMethod(
+        context: JavaContext,
+        node: UMethod,
+        interfaceName: String,
+        body: UBlockExpression
+    ) {
+        if (!isSystemServicePath(context)) return
+        if (context.evaluator.isAbstract(node)) return
+
+        val fullyQualifiedInterfaceName =
+            getContainingAidlInterfaceQualified(context, node) ?: return
+        if (exemptAidlInterfaces.contains(fullyQualifiedInterfaceName)) return
+
+        if (node.hasAnnotation(ANNOTATION_REQUIRES_NO_PERMISSION)) return
+
+        if (!isCallingMethod(node)) {
+            context.report(
+                ISSUE_SIMPLE_REQUIRES_NO_PERMISSION,
+                node,
+                context.getLocation(node),
+                """
+                    Method ${node.name} doesn't perform any permission checks, meaning it should \
+                    be annotated with @RequiresNoPermission.
+                """.trimMargin()
+            )
+        }
+    }
+
+    private fun isCallingMethod(node: UMethod): Boolean {
+        val uCallExpressionVisitor = UCallExpressionVisitor()
+        node.accept(uCallExpressionVisitor)
+
+        return uCallExpressionVisitor.isCallingMethod
+    }
+
+    /**
+     * Visits the body of a `UMethod` and determines if it encounters a `UCallExpression` which is
+     * a `UastCallKind.METHOD_CALL`. `isCallingMethod` will hold the result of the search procedure.
+     */
+    private class UCallExpressionVisitor : AbstractUastVisitor() {
+        var isCallingMethod = false
+
+        override fun visitElement(node: UElement): Boolean {
+            // Stop the search early when a method call has been found.
+            return isCallingMethod
+        }
+
+        override fun visitCallExpression(node: UCallExpression): Boolean {
+            if (node.kind != UastCallKind.METHOD_CALL) return false
+
+            isCallingMethod = true
+            return true
+        }
+    }
+
+    companion object {
+
+        private val EXPLANATION = """
+            Method implementations of AIDL Interfaces hosted by the `system_server` which do not
+            call any other methods should be annotated with @RequiresNoPermission. That is because
+            not calling any other methods implies that the method does not perform any permission
+            checking.
+
+            Please migrate to an @RequiresNoPermission annotation.
+        """.trimIndent()
+
+        @JvmField
+        val ISSUE_SIMPLE_REQUIRES_NO_PERMISSION = Issue.create(
+            id = "SimpleRequiresNoPermission",
+            briefDescription = "System Service APIs not calling other methods should use @RNP",
+            explanation = EXPLANATION,
+            category = Category.SECURITY,
+            priority = 5,
+            severity = Severity.ERROR,
+            implementation = Implementation(
+                SimpleRequiresNoPermissionDetector::class.java,
+                Scope.JAVA_FILE_SCOPE
+            ),
+        )
+    }
+}
diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/PermissionAnnotationDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/PermissionAnnotationDetectorTest.kt
index 92d0829..824be93 100644
--- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/PermissionAnnotationDetectorTest.kt
+++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/PermissionAnnotationDetectorTest.kt
@@ -17,7 +17,6 @@
 package com.google.android.lint.aidl
 
 import com.android.tools.lint.checks.infrastructure.LintDetectorTest
-import com.android.tools.lint.checks.infrastructure.TestFile
 import com.android.tools.lint.checks.infrastructure.TestLintTask
 import com.android.tools.lint.detector.api.Detector
 import com.android.tools.lint.detector.api.Issue
@@ -64,7 +63,7 @@
                     """
                         package com.android.server;
                         public class Bar extends IBar.Stub {
-                            public void testMethod() { }
+                            public void testMethod(int parameter1, int parameter2) { }
                         }
                     """
                 )
@@ -75,8 +74,8 @@
             .expect(
                 """
                 src/frameworks/base/services/java/com/android/server/Bar.java:3: Error: The method testMethod is not permission-annotated. [MissingPermissionAnnotation]
-                    public void testMethod() { }
-                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                    public void testMethod(int parameter1, int parameter2) { }
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                 1 errors, 0 warnings
                 """
             )
@@ -90,7 +89,7 @@
                     """
                         package com.android.server;
                         public class Bar extends IBar.Stub {
-                            public void testMethod() { }
+                            public void testMethod(int parameter1, int parameter2) { }
                         }
                     """
                 )
@@ -132,7 +131,7 @@
                     """
                         package com.android.server;
                         public abstract class Bar extends IBar.Stub {
-                            public abstract void testMethod();
+                            public abstract void testMethod(int parameter1, int parameter2);
                         }
                     """
                 )
@@ -177,50 +176,6 @@
             .expectClean()
     }
 
-    /* Stubs */
-
-    // A service with permission annotation on the method.
-    private val interfaceIFoo: TestFile = java(
-        """
-        public interface IFoo extends android.os.IInterface {
-         public static abstract class Stub extends android.os.Binder implements IFoo {
-          }
-          @Override
-          @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
-          public void testMethod();
-          @Override
-          @android.annotation.RequiresNoPermission
-          public void testMethodNoPermission();
-          @Override
-          @android.annotation.PermissionManuallyEnforced
-          public void testMethodManual();
-        }
-        """
-    ).indented()
-
-    // A service with no permission annotation.
-    private val interfaceIBar: TestFile = java(
-        """
-        public interface IBar extends android.os.IInterface {
-         public static abstract class Stub extends android.os.Binder implements IBar {
-          }
-          public void testMethod();
-        }
-        """
-    ).indented()
-
-    // A service whose AIDL Interface is exempted.
-    private val interfaceIExempted: TestFile = java(
-        """
-        package android.accessibilityservice;
-        public interface IBrailleDisplayConnection extends android.os.IInterface {
-         public static abstract class Stub extends android.os.Binder implements IBrailleDisplayConnection {
-          }
-          public void testMethod();
-        }
-        """
-    ).indented()
-
     private val stubs = arrayOf(interfaceIFoo, interfaceIBar, interfaceIExempted)
 
     private fun createVisitedPath(filename: String) =
diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetectorTest.kt
new file mode 100644
index 0000000..a33b48c
--- /dev/null
+++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetectorTest.kt
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.lint.aidl
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+class SimpleRequiresNoPermissionDetectorTest : LintDetectorTest() {
+    override fun getDetector(): Detector = SimpleRequiresNoPermissionDetector()
+    override fun getIssues(): List<Issue> = listOf(
+        SimpleRequiresNoPermissionDetector
+            .ISSUE_SIMPLE_REQUIRES_NO_PERMISSION
+    )
+
+    override fun lint(): TestLintTask = super.lint().allowMissingSdk()
+
+    fun testRequiresNoPermissionUsedCorrectly_shouldNotWarn() {
+        lint()
+            .files(
+                java(
+                    createVisitedPath("Foo.java"),
+                    """
+                        package com.android.server;
+                        public class Foo extends IFoo.Stub {
+                            private int memberInt;
+
+                            @Override
+                            @android.annotation.RequiresNoPermission
+                            public void testMethodNoPermission(int parameter1, int parameter2) {
+                                if (parameter1 < parameter2) {
+                                    memberInt = parameter1;
+                                } else {
+                                    memberInt = parameter2;
+                                }
+                            }
+                        }
+                    """
+                )
+                    .indented(),
+                *stubs
+            )
+            .run()
+            .expectClean()
+    }
+
+    fun testMissingRequiresNoPermission_shouldWarn() {
+        lint()
+            .files(
+                java(
+                    createVisitedPath("Bar.java"),
+                    """
+                        package com.android.server;
+                        public class Bar extends IBar.Stub {
+                            private int memberInt;
+
+                            @Override
+                            public void testMethod(int parameter1, int parameter2) {
+                                if (parameter1 < parameter2) {
+                                    memberInt = parameter1;
+                                } else {
+                                    memberInt = parameter2;
+                                }
+                            }
+                        }
+                    """
+                )
+                    .indented(),
+                *stubs
+            )
+            .run()
+            .expect(
+                """
+                src/frameworks/base/services/java/com/android/server/Bar.java:5: Error: Method testMethod doesn't perform any permission checks, meaning it should be annotated with @RequiresNoPermission. [SimpleRequiresNoPermission]
+                    @Override
+                    ^
+                1 errors, 0 warnings
+                """
+            )
+    }
+
+    fun testMethodOnlyPerformsConstructorCall_shouldWarn() {
+        lint()
+            .files(
+                java(
+                    createVisitedPath("Bar.java"),
+                    """
+                        package com.android.server;
+                        public class Bar extends IBar.Stub {
+                            private IntPair memberIntPair;
+
+                            @Override
+                            public void testMethod(int parameter1, int parameter2) {
+                                memberIntPair = new IntPair(parameter1, parameter2);
+                            }
+
+                            private static class IntPair {
+                                public int first;
+                                public int second;
+
+                                public IntPair(int first, int second) {
+                                    this.first = first;
+                                    this.second = second;
+                                }
+                            }
+                        }
+                    """
+                )
+                    .indented(),
+                *stubs
+            )
+            .run()
+            .expect(
+                """
+                src/frameworks/base/services/java/com/android/server/Bar.java:5: Error: Method testMethod doesn't perform any permission checks, meaning it should be annotated with @RequiresNoPermission. [SimpleRequiresNoPermission]
+                    @Override
+                    ^
+                1 errors, 0 warnings
+                """
+            )
+    }
+
+    fun testMissingRequiresNoPermissionInIgnoredDirectory_shouldNotWarn() {
+        lint()
+            .files(
+                java(
+                    ignoredPath,
+                    """
+                        package com.android.server;
+                        public class Bar extends IBar.Stub {
+                            @Override
+                            public void testMethod(int parameter1, int parameter2) {}
+                        }
+                    """
+                )
+                    .indented(),
+                *stubs
+            )
+            .run()
+            .expectClean()
+    }
+
+    fun testMissingRequiresNoPermissionAbstractMethod_shouldNotWarn() {
+        lint()
+            .files(
+                java(
+                    createVisitedPath("Bar.java"),
+                    """
+                        package com.android.server;
+                        public abstract class Bar extends IBar.Stub {
+                            private int memberInt;
+
+                            @Override
+                            public abstract void testMethodNoPermission(int parameter1, int parameter2);
+                        }
+                    """
+                )
+                    .indented(),
+                *stubs
+            )
+            .run()
+            .expectClean()
+    }
+
+    // If this test fails, consider the following steps:
+    //   1. Pick the first entry (interface) from `exemptAidlInterfaces`.
+    //   2. Change `interfaceIExempted` to use that interface.
+    //   3. Change this test's class to extend the interface's Stub.
+    fun testMissingRequiresNoPermissionAidlInterfaceExempted_shouldNotWarn() {
+        lint()
+            .files(
+                java(
+                    createVisitedPath("Bar.java"),
+                    """
+                        package com.android.server;
+                        public class Bar extends android.accessibilityservice.IBrailleDisplayConnection.Stub {
+                            public void testMethod(int parameter1, int parameter2) {}
+                        }
+                    """
+                )
+                    .indented(),
+                *stubs
+            )
+            .run()
+            .expectClean()
+    }
+
+    fun testMethodMakesAnotherMethodCall_shouldNotWarn() {
+        lint()
+            .files(
+                java(
+                    createVisitedPath("Bar.java"),
+                    """
+                        package com.android.server;
+                        public class Bar extends IBar.Stub {
+                            private int memberInt;
+
+                            @Override
+                            public void testMethod(int parameter1, int parameter2) {
+                                if (!hasPermission()) return;
+
+                                if (parameter1 < parameter2) {
+                                    memberInt = parameter1;
+                                } else {
+                                    memberInt = parameter2;
+                                }
+                            }
+
+                            private bool hasPermission() {
+                                // Perform a permission check.
+                                return true;
+                            }
+                        }
+                    """
+                )
+                    .indented(),
+                *stubs
+            )
+            .run()
+            .expectClean()
+    }
+
+    private val stubs = arrayOf(interfaceIFoo, interfaceIBar, interfaceIExempted)
+
+    private fun createVisitedPath(filename: String) =
+        "src/frameworks/base/services/java/com/android/server/$filename"
+
+    private val ignoredPath = "src/test/pkg/TestClass.java"
+}
diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt
index 2ec8fdd..18a8f18 100644
--- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt
+++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt
@@ -85,4 +85,46 @@
         }
     }
     """.trimIndent()
-)
\ No newline at end of file
+)
+
+// A service with permission annotation on the method.
+val interfaceIFoo: TestFile = java(
+    """
+        public interface IFoo extends android.os.IInterface {
+         public static abstract class Stub extends android.os.Binder implements IFoo {
+          }
+          @Override
+          @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
+          public void testMethod();
+          @Override
+          @android.annotation.RequiresNoPermission
+          public void testMethodNoPermission(int parameter1, int parameter2);
+          @Override
+          @android.annotation.PermissionManuallyEnforced
+          public void testMethodManual();
+        }
+        """
+).indented()
+
+// A service with no permission annotation.
+val interfaceIBar: TestFile = java(
+    """
+        public interface IBar extends android.os.IInterface {
+         public static abstract class Stub extends android.os.Binder implements IBar {
+          }
+          public void testMethod(int parameter1, int parameter2);
+        }
+        """
+).indented()
+
+// A service whose AIDL Interface is exempted.
+val interfaceIExempted: TestFile = java(
+    """
+        package android.accessibilityservice;
+        public interface IBrailleDisplayConnection extends android.os.IInterface {
+         public static abstract class Stub extends android.os.Binder implements IBrailleDisplayConnection {
+          }
+          public void testMethod();
+        }
+        """
+).indented()