Merge "Resolve some TODOs in appfunctions" into main
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 03eab7c..9c93c3a 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3434,6 +3434,23 @@
 
 package android.companion.virtual {
 
+  @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public final class ActivityPolicyExemption implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.content.ComponentName getComponentName();
+    method public int getDisplayId();
+    method @Nullable public String getPackageName();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.ActivityPolicyExemption> CREATOR;
+  }
+
+  public static final class ActivityPolicyExemption.Builder {
+    ctor public ActivityPolicyExemption.Builder();
+    method @NonNull public android.companion.virtual.ActivityPolicyExemption build();
+    method @NonNull public android.companion.virtual.ActivityPolicyExemption.Builder setComponentName(@NonNull android.content.ComponentName);
+    method @NonNull public android.companion.virtual.ActivityPolicyExemption.Builder setDisplayId(int);
+    method @NonNull public android.companion.virtual.ActivityPolicyExemption.Builder setPackageName(@NonNull String);
+  }
+
   public final class VirtualDevice implements android.os.Parcelable {
     method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public boolean hasCustomAudioInputSupport();
     method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public boolean hasCustomCameraSupport();
@@ -3467,9 +3484,7 @@
   public static class VirtualDeviceManager.VirtualDevice implements java.lang.AutoCloseable {
     method public void addActivityListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
     method @FlaggedApi("android.companion.virtual.flags.dynamic_policy") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull android.content.ComponentName);
-    method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull String);
-    method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull android.content.ComponentName, int);
-    method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull String, int);
+    method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void addActivityPolicyExemption(@NonNull android.companion.virtual.ActivityPolicyExemption);
     method public void addSoundEffectListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.SoundEffectListener);
     method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
     method @NonNull public android.content.Context createContext();
@@ -3494,9 +3509,7 @@
     method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull android.content.IntentFilter, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback);
     method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
     method @FlaggedApi("android.companion.virtual.flags.dynamic_policy") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull android.content.ComponentName);
-    method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull String);
-    method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull android.content.ComponentName, int);
-    method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull String, int);
+    method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void removeActivityPolicyExemption(@NonNull android.companion.virtual.ActivityPolicyExemption);
     method public void removeSoundEffectListener(@NonNull android.companion.virtual.VirtualDeviceManager.SoundEffectListener);
     method @FlaggedApi("android.companion.virtual.flags.dynamic_policy") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setDevicePolicy(int, int);
     method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setDevicePolicy(int, int, int);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 80764af..dbf9afd 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -112,6 +112,8 @@
 import android.permission.PermissionControllerManager;
 import android.permission.PermissionManager;
 import android.provider.Settings;
+import android.ravenwood.annotation.RavenwoodKeepPartialClass;
+import android.ravenwood.annotation.RavenwoodReplace;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -157,6 +159,7 @@
 import java.util.function.Function;
 
 /** @hide */
+@RavenwoodKeepPartialClass
 public class ApplicationPackageManager extends PackageManager {
     private static final String TAG = "ApplicationPackageManager";
     private static final boolean DEBUG_ICONS = false;
@@ -2163,6 +2166,7 @@
     }
 
     @UnsupportedAppUsage
+    @RavenwoodReplace(reason = "<cinit> crashes due to unsupported class PropertyInvalidatedCache")
     static void configurationChanged() {
         synchronized (sSync) {
             sIconCache.clear();
@@ -2170,6 +2174,10 @@
         }
     }
 
+    private static void configurationChanged$ravenwood() {
+        /* no-op */
+    }
+
     @UnsupportedAppUsage
     protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
         mContext = context;
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 2d5dad0..84a4eb4 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -41,6 +41,7 @@
 import android.os.Process;
 import android.os.Trace;
 import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.ravenwood.annotation.RavenwoodReplace;
 import android.ravenwood.annotation.RavenwoodThrow;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -1409,6 +1410,7 @@
         return newKey;
     }
 
+    @RavenwoodThrow(reason = "AppInfo update not supported")
     public void appendPendingAppInfoUpdate(@NonNull String[] oldSourceDirs,
             @NonNull ApplicationInfo appInfo) {
         synchronized (mLock) {
@@ -1427,6 +1429,7 @@
         }
     }
 
+    @RavenwoodReplace(reason = "AppInfo update not supported")
     public final void applyAllPendingAppInfoUpdates() {
         synchronized (mLock) {
             if (mPendingAppInfoUpdates != null) {
@@ -1439,6 +1442,10 @@
         }
     }
 
+    private void applyAllPendingAppInfoUpdates$ravenwood() {
+        /* no-op */
+    }
+
     public final boolean applyConfigurationToResources(@NonNull Configuration config,
             @Nullable CompatibilityInfo compat) {
         synchronized (mLock) {
diff --git a/core/java/android/companion/virtual/ActivityPolicyExemption.aidl b/core/java/android/companion/virtual/ActivityPolicyExemption.aidl
new file mode 100644
index 0000000..2f89da3
--- /dev/null
+++ b/core/java/android/companion/virtual/ActivityPolicyExemption.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 android.companion.virtual;
+
+parcelable ActivityPolicyExemption;
diff --git a/core/java/android/companion/virtual/ActivityPolicyExemption.java b/core/java/android/companion/virtual/ActivityPolicyExemption.java
new file mode 100644
index 0000000..c81bb43
--- /dev/null
+++ b/core/java/android/companion/virtual/ActivityPolicyExemption.java
@@ -0,0 +1,196 @@
+/*
+ * 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 android.companion.virtual;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.companion.virtualdevice.flags.Flags;
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.Display;
+
+import java.util.Objects;
+
+/**
+ * Specifies an exemption from the current default activity launch policy of a virtual device.
+ *
+ * <p>Note that changing the virtual device's activity launch policy will clear all current
+ * exemptions.</p>
+ *
+ * @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
+ * @see VirtualDeviceManager.VirtualDevice#setDevicePolicy
+ * @see VirtualDeviceManager.VirtualDevice#addActivityPolicyExemption(ActivityPolicyExemption)
+ * @see VirtualDeviceManager.VirtualDevice#removeActivityPolicyExemption(ActivityPolicyExemption)
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_ACTIVITY_CONTROL_API)
+@SystemApi
+public final class ActivityPolicyExemption implements Parcelable {
+
+    private final @Nullable ComponentName mComponentName;
+    private final @Nullable String mPackageName;
+    private final int mDisplayId;
+
+    private ActivityPolicyExemption(@Nullable ComponentName componentName,
+            @Nullable String packageName, int displayId) {
+        mComponentName = componentName;
+        mPackageName = packageName;
+        mDisplayId = displayId;
+    }
+
+    private ActivityPolicyExemption(@NonNull Parcel parcel) {
+        mComponentName = parcel.readTypedObject(ComponentName.CREATOR);
+        mPackageName = parcel.readString8();
+        mDisplayId = parcel.readInt();
+    }
+
+    /**
+     * Returns the exempt component name if this is a component level exemption, {@code null}
+     * otherwise.
+     *
+     * @see Builder#setComponentName(ComponentName)
+     */
+    public @Nullable ComponentName getComponentName() {
+        return mComponentName;
+    }
+
+    /**
+     * Returns the exempt package name if this is a package level exemption, {@code null} otherwise.
+     *
+     * @see Builder#setPackageName(String)
+     */
+    public @Nullable String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Returns the display ID relevant for this exemption if it is specific to a single display,
+     * {@link Display#INVALID_DISPLAY} otherwise.
+     *
+     * @see Builder#setDisplayId(int)
+     */
+    public int getDisplayId() {
+        return mDisplayId;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeTypedObject(mComponentName, flags);
+        dest.writeString8(mPackageName);
+        dest.writeInt(mDisplayId);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<ActivityPolicyExemption> CREATOR =
+            new Parcelable.Creator<>() {
+                public ActivityPolicyExemption createFromParcel(Parcel in) {
+                    return new ActivityPolicyExemption(in);
+                }
+
+                public ActivityPolicyExemption[] newArray(int size) {
+                    return new ActivityPolicyExemption[size];
+                }
+            };
+
+    /**
+     * Builder for {@link ActivityPolicyExemption}.
+     */
+    public static final class Builder {
+
+        private @Nullable ComponentName mComponentName;
+        private @Nullable String mPackageName;
+        private int mDisplayId = Display.INVALID_DISPLAY;
+
+        /**
+         * Specifies a component level exemption from the current default activity launch policy.
+         *
+         * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
+         * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
+         * then the specified component will be blocked from launching.
+         * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
+         * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then the
+         * specified component will be allowed to launch.</p>
+         *
+         * <p>Setting a component name will clear any previously set package name.</p>
+         */
+        public @NonNull Builder setComponentName(@NonNull ComponentName componentName) {
+            mComponentName = Objects.requireNonNull(componentName);
+            mPackageName = null;
+            return this;
+        }
+
+        /**
+         * Specifies a package level exemption from the current default activity launch policy.
+         *
+         * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
+         * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
+         * then all activities from the specified package will be blocked from launching.
+         * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
+         * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
+         * activities from the specified package will be allowed to launch.</p>
+         *
+         * <p>Package level exemptions are independent of component level exemptions created via
+         * {@link #setComponentName(ComponentName)}, i.e. removing a package exemption will not
+         * remove any existing component exemptions, even if the component belongs to that package.
+         * </p>
+         *
+         * <p>Setting a package name will clear any previously set component name.</p>
+         */
+        public @NonNull Builder setPackageName(@NonNull String packageName) {
+            mComponentName = null;
+            mPackageName = Objects.requireNonNull(packageName);
+            return this;
+        }
+
+        /**
+         * Makes this exemption specific to the display with the given ID. If unset, or set to
+         * {@link Display#INVALID_DISPLAY}, then the exemption is applied to all displays that
+         * belong to the virtual device.
+         *
+         * @param displayId  the ID of the display, for which to apply the exemption. The display
+         *   must belong to the virtual device.
+         */
+        public @NonNull Builder setDisplayId(int displayId) {
+            mDisplayId = displayId;
+            return this;
+        }
+
+        /**
+         * Builds the {@link ActivityPolicyExemption} instance.
+         *
+         * @throws IllegalArgumentException if neither the component name nor the package name are
+         *   set.
+         */
+        @NonNull
+        public ActivityPolicyExemption build() {
+            if ((mComponentName == null) == (mPackageName == null)) {
+                throw new IllegalArgumentException(
+                        "Either component name or package name must be set");
+            }
+            return new ActivityPolicyExemption(mComponentName, mPackageName, mDisplayId);
+        }
+    }
+}
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl
index 56d5a74..8916ce2 100644
--- a/core/java/android/companion/virtual/IVirtualDevice.aidl
+++ b/core/java/android/companion/virtual/IVirtualDevice.aidl
@@ -17,6 +17,7 @@
 package android.companion.virtual;
 
 import android.app.PendingIntent;
+import android.companion.virtual.ActivityPolicyExemption;
 import android.companion.virtual.IVirtualDeviceActivityListener;
 import android.companion.virtual.IVirtualDeviceIntentInterceptor;
 import android.companion.virtual.IVirtualDeviceSoundEffectListener;
@@ -103,25 +104,13 @@
      * Adds an exemption to the default activity launch policy.
      */
     @EnforcePermission("CREATE_VIRTUAL_DEVICE")
-    void addActivityPolicyExemption(in ComponentName exemption);
+    void addActivityPolicyExemption(in ActivityPolicyExemption exemption);
 
     /**
      * Removes an exemption to the default activity launch policy.
      */
     @EnforcePermission("CREATE_VIRTUAL_DEVICE")
-    void removeActivityPolicyExemption(in ComponentName exemption);
-
-    /**
-     * Adds a package level exemption to the default activity launch policy.
-     */
-    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
-    void addActivityPolicyPackageExemption(in String exemption);
-
-    /**
-     * Removes a package level exemption to the default activity launch policy.
-     */
-    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
-    void removeActivityPolicyPackageExemption(in String exemption);
+    void removeActivityPolicyExemption(in ActivityPolicyExemption exemption);
 
     /**
      * Specifies a policy for this virtual device on the given display.
@@ -130,30 +119,6 @@
     void setDevicePolicyForDisplay(int displayId, int policyType, int devicePolicy);
 
     /**
-     * Adds an exemption to the default activity launch policy on the given display.
-     */
-    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
-    void addActivityPolicyExemptionForDisplay(int displayId, in ComponentName exemption);
-
-    /**
-     * Removes an exemption to the default activity launch policy on the given display.
-     */
-    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
-    void removeActivityPolicyExemptionForDisplay(int displayId, in ComponentName exemption);
-
-    /**
-     * Adds a package level exemption to the default activity launch policy on the given display.
-     */
-    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
-    void addActivityPolicyPackageExemptionForDisplay(int displayId, in String exemption);
-
-    /**
-     * Removes a package level exemption to the default activity launch policy on the given display.
-     */
-    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
-    void removeActivityPolicyPackageExemptionForDisplay(int displayId, in String exemption);
-
-    /**
      * Notifies that an audio session being started.
      */
     @EnforcePermission("CREATE_VIRTUAL_DEVICE")
diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java
index e83f46a..b7bf2d1 100644
--- a/core/java/android/companion/virtual/VirtualDeviceInternal.java
+++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java
@@ -306,39 +306,22 @@
         }
     }
 
-    void addActivityPolicyExemption(@NonNull ComponentName componentName) {
+    void addActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
         try {
-            mVirtualDevice.addActivityPolicyExemption(componentName);
+            mVirtualDevice.addActivityPolicyExemption(exemption);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
-    void removeActivityPolicyExemption(@NonNull ComponentName componentName) {
+    void removeActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
         try {
-            mVirtualDevice.removeActivityPolicyExemption(componentName);
+            mVirtualDevice.removeActivityPolicyExemption(exemption);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
-    void addActivityPolicyPackageExemption(@NonNull String packageName) {
-        try {
-            mVirtualDevice.addActivityPolicyPackageExemption(packageName);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    void removeActivityPolicyPackageExemption(@NonNull String packageName) {
-        try {
-            mVirtualDevice.removeActivityPolicyPackageExemption(packageName);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-
     void setDevicePolicyForDisplay(int displayId,
             @VirtualDeviceParams.DynamicDisplayPolicyType int policyType,
             @VirtualDeviceParams.DevicePolicy int devicePolicy) {
@@ -358,40 +341,6 @@
         }
     }
 
-    void addActivityPolicyExemptionForDisplay(int displayId, @NonNull ComponentName componentName) {
-        try {
-            mVirtualDevice.addActivityPolicyExemptionForDisplay(displayId, componentName);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    void removeActivityPolicyExemptionForDisplay(int displayId,
-            @NonNull ComponentName componentName) {
-        try {
-            mVirtualDevice.removeActivityPolicyExemptionForDisplay(displayId, componentName);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    void addActivityPolicyPackageExemptionForDisplay(int displayId, @NonNull String packageName) {
-        try {
-            mVirtualDevice.addActivityPolicyPackageExemptionForDisplay(displayId, packageName);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    void removeActivityPolicyPackageExemptionForDisplay(int displayId,
-            @NonNull String packageName) {
-        try {
-            mVirtualDevice.removeActivityPolicyPackageExemptionForDisplay(displayId, packageName);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
     @NonNull
     VirtualDpad createVirtualDpad(@NonNull VirtualDpadConfig config) {
         try {
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 9e32cba..40aa6837 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -765,14 +765,15 @@
          * <p>Note that changing the activity launch policy will clear current set of exempt
          * components.</p>
          *
-         * @see #removeActivityPolicyExemption
+         * @see #removeActivityPolicyExemption(ComponentName)
          * @see #setDevicePolicy
          */
         @FlaggedApi(Flags.FLAG_DYNAMIC_POLICY)
         @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
         public void addActivityPolicyExemption(@NonNull ComponentName componentName) {
-            mVirtualDeviceInternal.addActivityPolicyExemption(
-                    Objects.requireNonNull(componentName));
+            addActivityPolicyExemption(new ActivityPolicyExemption.Builder()
+                    .setComponentName(componentName)
+                    .build());
         }
 
         /**
@@ -788,70 +789,54 @@
          * <p>Note that changing the activity launch policy will clear current set of exempt
          * components.</p>
          *
-         * @see #addActivityPolicyExemption
+         * @see #addActivityPolicyExemption(ComponentName)
          * @see #setDevicePolicy
          */
         @FlaggedApi(Flags.FLAG_DYNAMIC_POLICY)
         @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
         public void removeActivityPolicyExemption(@NonNull ComponentName componentName) {
-            mVirtualDeviceInternal.removeActivityPolicyExemption(
-                    Objects.requireNonNull(componentName));
+            removeActivityPolicyExemption(new ActivityPolicyExemption.Builder()
+                    .setComponentName(componentName)
+                    .build());
         }
 
         /**
-         * Specifies a package name to be exempt from the current activity launch policy.
+         * Specifies an exemption from the current activity launch policy.
          *
          * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
          * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
-         * then all activities from the specified package will be blocked from launching.
+         * then all exempt activities be blocked from launching.
          * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
          * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
-         * activities from the specified package will be allowed to launch.</p>
-         *
-         * <p>Package level exemptions are independent of component level exemptions added via
-         * {@link #addActivityPolicyExemption(String)}, i.e. removing a package exemption will not
-         * remove any existing component exemptions, even if the component belongs to that package.
-         * </p>
+         * exempt activities will be allowed to launch.</p>
          *
          * <p>Note that changing the activity launch policy will clear current set of exempt
          * packages.</p>
+         * <p>Any change to the exemptions will only be applied for new activity launches.</p>
          *
-         * @see #removeActivityPolicyExemption(String)
+         * @see #removeActivityPolicyExemption(ActivityPolicyExemption)
          * @see #setDevicePolicy
          */
         @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
         @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-        public void addActivityPolicyExemption(@NonNull String packageName) {
-            mVirtualDeviceInternal.addActivityPolicyPackageExemption(
-                    Objects.requireNonNull(packageName));
+        public void addActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
+            mVirtualDeviceInternal.addActivityPolicyExemption(Objects.requireNonNull(exemption));
         }
 
         /**
-         * Makes the specified package name adhere to the default activity launch policy.
-         *
-         * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
-         * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
-         * then all activities from the specified package will be allowed to launch.
-         * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
-         * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
-         * activities from the specified package will be blocked from launching.</p>
-         *
-         * <p>Package level exemptions are independent of component level exemptions added via
-         * {@link #addActivityPolicyExemption(String)}, i.e. removing a package exemption will not
-         * remove any existing component exemptions, even if the component belongs to that package.
-         * </p>
+         * Removes an exemption from the current activity launch policy.
          *
          * <p>Note that changing the activity launch policy will clear current set of exempt
          * packages.</p>
+         * <p>Any change to the exemptions will only be applied for new activity launches.</p>
          *
-         * @see #addActivityPolicyExemption(String)
+         * @see #addActivityPolicyExemption(ActivityPolicyExemption)
          * @see #setDevicePolicy
          */
         @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
         @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-        public void removeActivityPolicyExemption(@NonNull String packageName) {
-            mVirtualDeviceInternal.removeActivityPolicyPackageExemption(
-                    Objects.requireNonNull(packageName));
+        public void removeActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
+            mVirtualDeviceInternal.removeActivityPolicyExemption(Objects.requireNonNull(exemption));
         }
 
         /**
@@ -881,142 +866,6 @@
         }
 
         /**
-         * Specifies a component name to be exempt from the given display's activity launch policy.
-         *
-         * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
-         * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
-         * then the specified component will be blocked from launching.
-         * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
-         * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then the
-         * specified component will be allowed to launch.</p>
-         *
-         * <p>Note that changing the activity launch policy will clear current set of exempt
-         * components.</p>
-         * <p>Any change to the exemptions will only be applied for new activity launches.</p>
-         *
-         * @param componentName the component name to be exempt from the activity launch policy.
-         * @param displayId the ID of the display, for which to apply the exemption. The display
-         *   must belong to the virtual device.
-         * @throws IllegalArgumentException if the specified display does not belong to the virtual
-         *   device.
-         *
-         * @see #removeActivityPolicyExemption
-         * @see #setDevicePolicy
-         * @see Display#getDisplayId
-         */
-        @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
-        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-        public void addActivityPolicyExemption(
-                @NonNull ComponentName componentName, int displayId) {
-            mVirtualDeviceInternal.addActivityPolicyExemptionForDisplay(
-                    displayId, Objects.requireNonNull(componentName));
-        }
-
-        /**
-         * Makes the specified component name adhere to the given display's activity launch policy.
-         *
-         * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
-         * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
-         * then the specified component will be allowed to launch.
-         * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
-         * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then the
-         * specified component will be blocked from launching.</p>
-         *
-         * <p>Note that changing the activity launch policy will clear current set of exempt
-         * components.</p>
-         *
-         * @param componentName the component name to be removed from the exemption list.
-         * @param displayId the ID of the display, for which to apply the exemption. The display
-         *   must belong to the virtual device.
-         * @throws IllegalArgumentException if the specified display does not belong to the virtual
-         *   device.
-         *
-         * @see #addActivityPolicyExemption
-         * @see #setDevicePolicy
-         * @see Display#getDisplayId
-         */
-        @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
-        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-        public void removeActivityPolicyExemption(
-                @NonNull ComponentName componentName, int displayId) {
-            mVirtualDeviceInternal.removeActivityPolicyExemptionForDisplay(
-                    displayId, Objects.requireNonNull(componentName));
-        }
-
-        /**
-         * Specifies a package name to be exempt from the given display's activity launch policy.
-         *
-         * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
-         * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
-         * then all activities from the specified package will be blocked from launching.
-         * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
-         * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
-         * activities from the specified package will be allowed to launch.</p>
-         *
-         * <p>Note that changing the activity launch policy will clear current set of exempt
-         * packages.</p>
-         * <p>Any change to the exemptions will only be applied for new activity launches.</p>
-         *
-         * <p>Package level exemptions are independent of component level exemptions added via
-         * {@link #addActivityPolicyExemption(String, int)}, i.e. removing a package exemption will
-         * not remove any existing component exemptions, even if the component belongs to that
-         * package.</p>
-         *
-         * @param packageName the package name to be exempt from the activity launch policy. All
-         *   activities from that package will be exempt.
-         * @param displayId the ID of the display, for which to apply the exemption. The display
-         *   must belong to the virtual device.
-         * @throws IllegalArgumentException if the specified display does not belong to the virtual
-         *   device.
-         *
-         * @see #removeActivityPolicyExemption(String, int)
-         * @see #setDevicePolicy
-         * @see Display#getDisplayId
-         */
-        @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
-        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-        public void addActivityPolicyExemption(@NonNull String packageName, int displayId) {
-            mVirtualDeviceInternal.addActivityPolicyPackageExemptionForDisplay(
-                    displayId, Objects.requireNonNull(packageName));
-        }
-
-        /**
-         * Makes the specified package name adhere to the given display's activity launch policy.
-         *
-         * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
-         * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
-         * then all activities from the specified package will be allowed to launch.
-         * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
-         * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
-         * activities from the specified package will be blocked from launching.</p>
-         *
-         * <p>Note that changing the activity launch policy will clear current set of exempt
-         * packages.</p>
-         *
-         * <p>Package level exemptions are independent of component level exemptions added via
-         * {@link #addActivityPolicyExemption(String, int)}, i.e. removing a package exemption will
-         * not remove any existing component exemptions, even if the component belongs to that
-         * package.</p>
-         *
-         * @param packageName the package name to be removed from the exemption list. All activities
-         *   from that package stop being exempt from the activity launch policy.
-         * @param displayId the ID of the display, for which to apply the exemption. The display
-         *   must belong to the virtual device.
-         * @throws IllegalArgumentException if the specified display does not belong to the virtual
-         *   device.
-         *
-         * @see #addActivityPolicyExemption(String, int)
-         * @see #setDevicePolicy
-         * @see Display#getDisplayId
-         */
-        @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
-        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-        public void removeActivityPolicyExemption(@NonNull String packageName, int displayId) {
-            mVirtualDeviceInternal.removeActivityPolicyPackageExemptionForDisplay(
-                    displayId, Objects.requireNonNull(packageName));
-        }
-
-        /**
          * Creates a virtual dpad.
          *
          * @param config the configurations of the virtual dpad.
@@ -1401,7 +1250,7 @@
          *   activity to a different display.
          *
          * @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
-         * @see VirtualDevice#addActivityPolicyExemption(ComponentName)
+         * @see VirtualDevice#addActivityPolicyExemption(ActivityPolicyExemption)
          */
         @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
         default void onActivityLaunchBlocked(int displayId, @NonNull ComponentName componentName,
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index da4ecdd..9649cab 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -42,7 +42,7 @@
  * will be invoked on that thread.
  * <p>
  * Syncs can be cancelled at any time by the framework. For example a sync that was not
- * user-initiated and lasts longer than 30 minutes will be considered timed-out and cancelled.
+ * user-initiated and lasts longer than 10 minutes will be considered timed-out and cancelled.
  * Similarly the framework will attempt to determine whether or not an adapter is making progress
  * by monitoring its network activity over the course of a minute. If the network traffic over this
  * window is close enough to zero the sync will be cancelled. You can also request the sync be
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index f929c1f..d6620d1 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -28,6 +28,7 @@
 import android.os.Build.VERSION_CODES;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 import android.util.DisplayMetrics;
 import android.util.MergedConfiguration;
 import android.view.InsetsSourceControl;
@@ -42,6 +43,7 @@
  * 
  *  {@hide} 
  */
+@RavenwoodKeepWholeClass
 public class CompatibilityInfo implements Parcelable {
     /** default compatibility info object for compatible applications */
     @UnsupportedAppUsage
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 982224b..ef200c3 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -58,6 +58,7 @@
 import android.os.LocaleList;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Slog;
@@ -89,6 +90,7 @@
  * with {@link android.app.Activity#getResources}:</p>
  * <pre>Configuration config = getResources().getConfiguration();</pre>
  */
+@RavenwoodKeepWholeClass
 public final class Configuration implements Parcelable, Comparable<Configuration> {
     /** @hide */
     public static final Configuration EMPTY = new Configuration();
diff --git a/core/java/android/content/res/ConfigurationBoundResourceCache.java b/core/java/android/content/res/ConfigurationBoundResourceCache.java
index 5e10a57..9dc097a 100644
--- a/core/java/android/content/res/ConfigurationBoundResourceCache.java
+++ b/core/java/android/content/res/ConfigurationBoundResourceCache.java
@@ -18,6 +18,7 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.pm.ActivityInfo.Config;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 
 /**
  * A Cache class which can be used to cache resource objects that are easy to clone but more
@@ -25,6 +26,7 @@
  *
  * @hide For internal use only.
  */
+@RavenwoodKeepWholeClass
 public class ConfigurationBoundResourceCache<T> extends ThemedResourceCache<ConstantState<T>> {
 
     @UnsupportedAppUsage
diff --git a/core/java/android/content/res/ConstantState.java b/core/java/android/content/res/ConstantState.java
index 09d4a59..cedfe02 100644
--- a/core/java/android/content/res/ConstantState.java
+++ b/core/java/android/content/res/ConstantState.java
@@ -16,6 +16,7 @@
 package android.content.res;
 
 import android.content.pm.ActivityInfo.Config;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 
 /**
  * A cache class that can provide new instances of a particular resource which may change
@@ -29,6 +30,7 @@
  * changing configurations of each Animator in the set)
  * @hide
  */
+@RavenwoodKeepWholeClass
 abstract public class ConstantState<T> {
 
     /**
diff --git a/core/java/android/content/res/FontResourcesParser.java b/core/java/android/content/res/FontResourcesParser.java
index 24ae31e..8aef45b 100644
--- a/core/java/android/content/res/FontResourcesParser.java
+++ b/core/java/android/content/res/FontResourcesParser.java
@@ -18,6 +18,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Typeface;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Xml;
@@ -36,6 +37,7 @@
  * Parser for xml type font resources.
  * @hide
  */
+@RavenwoodKeepWholeClass
 public class FontResourcesParser {
     private static final String TAG = "FontResourcesParser";
 
diff --git a/core/java/android/content/res/FontScaleConverter.java b/core/java/android/content/res/FontScaleConverter.java
index f4312a9..b2c5afa 100644
--- a/core/java/android/content/res/FontScaleConverter.java
+++ b/core/java/android/content/res/FontScaleConverter.java
@@ -20,6 +20,7 @@
 import android.annotation.AnyThread;
 import android.annotation.FlaggedApi;
 import android.annotation.Nullable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 
 /**
  * A converter for non-linear font scaling. Converts font sizes given in "sp" dimensions to a
@@ -32,6 +33,7 @@
  * scale them slightly to preserve the visual hierarchy when compared to smaller fonts.
  */
 @FlaggedApi(Flags.FLAG_FONT_SCALE_CONVERTER_PUBLIC)
+@RavenwoodKeepWholeClass
 public interface FontScaleConverter {
     /**
      * Converts a dimension in "sp" to "dp".
diff --git a/core/java/android/content/res/FontScaleConverterFactory.java b/core/java/android/content/res/FontScaleConverterFactory.java
index c7237ea..9087a9a 100644
--- a/core/java/android/content/res/FontScaleConverterFactory.java
+++ b/core/java/android/content/res/FontScaleConverterFactory.java
@@ -19,6 +19,7 @@
 import android.annotation.AnyThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 import android.util.MathUtils;
 import android.util.SparseArray;
 
@@ -34,6 +35,7 @@
  *
  * @hide
  */
+@RavenwoodKeepWholeClass
 public class FontScaleConverterFactory {
     private static final float SCALE_KEY_MULTIPLIER = 100f;
 
diff --git a/core/java/android/content/res/FontScaleConverterImpl.java b/core/java/android/content/res/FontScaleConverterImpl.java
index 1968c4e..508507a 100644
--- a/core/java/android/content/res/FontScaleConverterImpl.java
+++ b/core/java/android/content/res/FontScaleConverterImpl.java
@@ -17,6 +17,7 @@
 package android.content.res;
 
 import android.annotation.NonNull;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 import android.util.MathUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -33,6 +34,7 @@
  */
 // Needs to be public so the Kotlin test can see it
 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+@RavenwoodKeepWholeClass
 public class FontScaleConverterImpl implements FontScaleConverter {
 
     /** @hide */
diff --git a/core/java/android/content/res/ThemedResourceCache.java b/core/java/android/content/res/ThemedResourceCache.java
index 690dfcf..c7fcc1a 100644
--- a/core/java/android/content/res/ThemedResourceCache.java
+++ b/core/java/android/content/res/ThemedResourceCache.java
@@ -22,6 +22,7 @@
 import android.content.pm.ActivityInfo.Config;
 import android.content.res.Resources.Theme;
 import android.content.res.Resources.ThemeKey;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 import android.util.ArrayMap;
 import android.util.LongSparseArray;
 
@@ -32,6 +33,7 @@
  *
  * @param <T> type of data to cache
  */
+@RavenwoodKeepWholeClass
 abstract class ThemedResourceCache<T> {
     public static final int UNDEFINED_GENERATION = -1;
     @UnsupportedAppUsage
diff --git a/core/java/android/view/DisplayAdjustments.java b/core/java/android/view/DisplayAdjustments.java
index bb50849..149d992 100644
--- a/core/java/android/view/DisplayAdjustments.java
+++ b/core/java/android/view/DisplayAdjustments.java
@@ -21,10 +21,12 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 
 import java.util.Objects;
 
 /** @hide */
+@RavenwoodKeepWholeClass
 public class DisplayAdjustments {
     public static final DisplayAdjustments DEFAULT_DISPLAY_ADJUSTMENTS = new DisplayAdjustments();
 
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 61ee13a..be744fd 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -228,6 +228,16 @@
 }
 
 flag {
+  name: "ensure_wallpaper_in_wear_transitions"
+  namespace: "windowing_frontend"
+  description: "Ensure that wallpaper window tokens are always present/available for collection in transitions on Wear"
+  bug: "355596979"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "custom_animations_behind_translucent"
   namespace: "windowing_frontend"
   description: "A change can use its own layer parameters to animate behind a translucent activity"
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 2bbaf9c..e86515f 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -164,6 +164,7 @@
         "org.apache.http.legacy",
     ],
     sdk_version: "core_platform",
+    resource_zips: [":FrameworksCoreTests_apks_as_resources"],
 }
 
 // Rules to copy all the test apks to the intermediate raw resource directory
@@ -237,6 +238,7 @@
     static_libs: [
         "core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
         "androidx.core_core",
+        "androidx.core_core-ktx",
         "androidx.annotation_annotation",
         "androidx.test.rules",
         "androidx.test.ext.junit",
@@ -255,8 +257,11 @@
         "src/android/content/pm/UserInfoTest.java",
         "src/android/database/CursorWindowTest.java",
         "src/android/os/**/*.java",
+        "src/android/content/res/*.java",
+        "src/android/content/res/*.kt",
         "src/android/telephony/PinResultTest.java",
         "src/android/util/**/*.java",
+        "src/android/view/DisplayAdjustmentsTests.java",
         "src/android/view/DisplayTest.java",
         "src/android/view/DisplayInfoTest.java",
         "src/com/android/internal/logging/**/*.java",
@@ -274,6 +279,10 @@
         ":FrameworksCoreTests-helpers",
         ":FrameworksCoreTestDoubles-sources",
     ],
+    exclude_srcs: [
+        "src/android/content/res/FontScaleConverterActivityTest.java",
+    ],
+    resource_apk: "FrameworksCoreTests-resonly",
     aidl: {
         generate_get_transaction_name: true,
         local_include_dirs: ["aidl"],
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index fc3c2f3..0dcb1ce 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1672,14 +1672,6 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="android.content.res.ResourceCacheActivity"
-                  android:exported="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
-            </intent-filter>
-        </activity>
-
         <activity
             android:name="android.print.test.PrintDocumentActivity"
             android:theme="@style/Theme" />
diff --git a/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java b/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java
index 6ffdee1..68882eb 100644
--- a/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java
+++ b/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java
@@ -16,80 +16,94 @@
 
 package android.content.res;
 
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+
+import android.content.Context;
 import android.platform.test.annotations.Presubmit;
-import android.test.ActivityInstrumentationTestCase2;
+import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.TypedValue;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.frameworks.coretests.R;
 
-import java.lang.reflect.InvocationTargetException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @Presubmit
-public class ConfigurationBoundResourceCacheTest
-        extends ActivityInstrumentationTestCase2<ResourceCacheActivity> {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ConfigurationBoundResourceCacheTest {
 
-    ConfigurationBoundResourceCache<Float> mCache;
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
 
-    public ConfigurationBoundResourceCacheTest() {
-        super(ResourceCacheActivity.class);
+    private ConfigurationBoundResourceCache<Float> mCache;
+    private Context mContext;
+
+    private void assertEquals(float expected, float actual) {
+        Assert.assertEquals(expected, actual, 0);
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
         mCache = new ConfigurationBoundResourceCache<>();
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
     }
 
-    @SmallTest
+    @Test
     public void testGetEmpty() {
-        final Resources res = getActivity().getResources();
+        final Resources res = mContext.getResources();
         assertNull(mCache.getInstance(-1, res, null));
     }
 
-    @SmallTest
+    @Test
     public void testSetGet() {
         mCache.put(1, null, new DummyFloatConstantState(5f),
                 ThemedResourceCache.UNDEFINED_GENERATION);
-        final Resources res = getActivity().getResources();
+        final Resources res = mContext.getResources();
         assertEquals(5f, mCache.getInstance(1, res, null));
         assertNotSame(5f, mCache.getInstance(1, res, null));
-        assertEquals(null, mCache.getInstance(1, res, getActivity().getTheme()));
+        assertNull(mCache.getInstance(1, res, mContext.getTheme()));
     }
 
-    @SmallTest
+    @Test
     public void testSetGetThemed() {
-        mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f),
+        mCache.put(1, mContext.getTheme(), new DummyFloatConstantState(5f),
                 ThemedResourceCache.UNDEFINED_GENERATION);
-        final Resources res = getActivity().getResources();
-        assertEquals(null, mCache.getInstance(1, res, null));
-        assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme()));
-        assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme()));
+        final Resources res = mContext.getResources();
+        assertNull(mCache.getInstance(1, res, null));
+        assertEquals(5f, mCache.getInstance(1, res, mContext.getTheme()));
+        assertNotSame(5f, mCache.getInstance(1, res, mContext.getTheme()));
     }
 
-    @SmallTest
+    @Test
     public void testMultiThreadPutGet() {
-        mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f),
+        mCache.put(1, mContext.getTheme(), new DummyFloatConstantState(5f),
                 ThemedResourceCache.UNDEFINED_GENERATION);
         mCache.put(1, null, new DummyFloatConstantState(10f),
                 ThemedResourceCache.UNDEFINED_GENERATION);
-        final Resources res = getActivity().getResources();
+        final Resources res = mContext.getResources();
         assertEquals(10f, mCache.getInstance(1, res, null));
         assertNotSame(10f, mCache.getInstance(1, res, null));
-        assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme()));
-        assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme()));
+        assertEquals(5f, mCache.getInstance(1, res, mContext.getTheme()));
+        assertNotSame(5f, mCache.getInstance(1, res, mContext.getTheme()));
     }
 
-    @SmallTest
-    public void testVoidConfigChange()
-            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    @Test
+    public void testVoidConfigChange() {
         TypedValue staticValue = new TypedValue();
         long key = 3L;
-        final Resources res = getActivity().getResources();
+        final Resources res = mContext.getResources();
         res.getValue(R.dimen.resource_cache_test_generic, staticValue, true);
         float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics());
-        mCache.put(key, getActivity().getTheme(),
+        mCache.put(key, mContext.getTheme(),
                 new DummyFloatConstantState(staticDim, staticValue.changingConfigurations),
                 ThemedResourceCache.UNDEFINED_GENERATION);
         final Configuration cfg = res.getConfiguration();
@@ -98,21 +112,20 @@
                 Configuration.ORIENTATION_PORTRAIT
                 : Configuration.ORIENTATION_LANDSCAPE;
         int changes = calcConfigChanges(res, newCnf);
-        assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme()));
+        assertEquals(staticDim, mCache.getInstance(key, res, mContext.getTheme()));
         mCache.onConfigurationChange(changes);
-        assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme()));
+        assertEquals(staticDim, mCache.getInstance(key, res, mContext.getTheme()));
     }
 
-    @SmallTest
-    public void testEffectiveConfigChange()
-            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    @Test
+    public void testEffectiveConfigChange() {
         TypedValue changingValue = new TypedValue();
         long key = 4L;
-        final Resources res = getActivity().getResources();
+        final Resources res = mContext.getResources();
         res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValue, true);
         float changingDim = TypedValue.complexToDimension(changingValue.data,
                 res.getDisplayMetrics());
-        mCache.put(key, getActivity().getTheme(),
+        mCache.put(key, mContext.getTheme(),
                 new DummyFloatConstantState(changingDim, changingValue.changingConfigurations),
                 ThemedResourceCache.UNDEFINED_GENERATION);
 
@@ -123,26 +136,25 @@
                 : Configuration.ORIENTATION_LANDSCAPE;
         int changes = calcConfigChanges(res, newCnf);
         assertEquals(changingDim,
-                mCache.getInstance(key, res, getActivity().getTheme()));
+                mCache.getInstance(key, res, mContext.getTheme()));
         mCache.onConfigurationChange(changes);
-        assertNull(mCache.get(key, getActivity().getTheme()));
+        assertNull(mCache.get(key, mContext.getTheme()));
     }
 
-    @SmallTest
-    public void testConfigChangeMultipleResources()
-            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    @Test
+    public void testConfigChangeMultipleResources() {
         TypedValue staticValue = new TypedValue();
         TypedValue changingValue = new TypedValue();
-        final Resources res = getActivity().getResources();
+        final Resources res = mContext.getResources();
         res.getValue(R.dimen.resource_cache_test_generic, staticValue, true);
         res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValue, true);
         float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics());
         float changingDim = TypedValue.complexToDimension(changingValue.data,
                 res.getDisplayMetrics());
-        mCache.put(R.dimen.resource_cache_test_generic, getActivity().getTheme(),
+        mCache.put(R.dimen.resource_cache_test_generic, mContext.getTheme(),
                 new DummyFloatConstantState(staticDim, staticValue.changingConfigurations),
                 ThemedResourceCache.UNDEFINED_GENERATION);
-        mCache.put(R.dimen.resource_cache_test_orientation_dependent, getActivity().getTheme(),
+        mCache.put(R.dimen.resource_cache_test_orientation_dependent, mContext.getTheme(),
                 new DummyFloatConstantState(changingDim, changingValue.changingConfigurations),
                 ThemedResourceCache.UNDEFINED_GENERATION);
         final Configuration cfg = res.getConfiguration();
@@ -152,25 +164,24 @@
                 : Configuration.ORIENTATION_LANDSCAPE;
         int changes = calcConfigChanges(res, newCnf);
         assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res,
-                getActivity().getTheme()));
+                mContext.getTheme()));
         assertEquals(changingDim,
                 mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
-                        getActivity().getTheme()));
+                        mContext.getTheme()));
         mCache.onConfigurationChange(changes);
         assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res,
-                getActivity().getTheme()));
+                mContext.getTheme()));
         assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
-                getActivity().getTheme()));
+                mContext.getTheme()));
     }
 
-    @SmallTest
-    public void testConfigChangeMultipleThemes()
-            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    @Test
+    public void testConfigChangeMultipleThemes() {
         TypedValue[] staticValues = new TypedValue[]{new TypedValue(), new TypedValue()};
         TypedValue[] changingValues = new TypedValue[]{new TypedValue(), new TypedValue()};
         float staticDim = 0;
         float changingDim = 0;
-        final Resources res = getActivity().getResources();
+        final Resources res = mContext.getResources();
         for (int i = 0; i < 2; i++) {
             res.getValue(R.dimen.resource_cache_test_generic, staticValues[i], true);
             staticDim = TypedValue
@@ -180,7 +191,7 @@
                     true);
             changingDim = TypedValue.complexToDimension(changingValues[i].data,
                     res.getDisplayMetrics());
-            final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
+            final Resources.Theme theme = i == 0 ? mContext.getTheme() : null;
             mCache.put(R.dimen.resource_cache_test_generic, theme,
                     new DummyFloatConstantState(staticDim, staticValues[i].changingConfigurations),
                     ThemedResourceCache.UNDEFINED_GENERATION);
@@ -196,7 +207,7 @@
                 : Configuration.ORIENTATION_LANDSCAPE;
         int changes = calcConfigChanges(res, newCnf);
         for (int i = 0; i < 2; i++) {
-            final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
+            final Resources.Theme theme = i == 0 ? mContext.getTheme() : null;
             assertEquals(staticDim,
                     mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme));
             assertEquals(changingDim,
@@ -205,7 +216,7 @@
         }
         mCache.onConfigurationChange(changes);
         for (int i = 0; i < 2; i++) {
-            final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
+            final Resources.Theme theme = i == 0 ? mContext.getTheme() : null;
             assertEquals(staticDim,
                     mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme));
             assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
diff --git a/core/tests/coretests/src/android/content/res/ConfigurationTest.java b/core/tests/coretests/src/android/content/res/ConfigurationTest.java
index 0d5cd72..83c7484 100644
--- a/core/tests/coretests/src/android/content/res/ConfigurationTest.java
+++ b/core/tests/coretests/src/android/content/res/ConfigurationTest.java
@@ -28,23 +28,27 @@
 import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
 import static android.view.Surface.ROTATION_90;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import android.content.Context;
 import android.os.LocaleList;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.AtomicFile;
 import android.util.proto.ProtoInputStream;
 import android.util.proto.ProtoOutputStream;
 
-import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.server.usage.IntervalStatsProto;
 
-import junit.framework.TestCase;
-
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -54,10 +58,14 @@
 /**
  * Build/install/run: bit FrameworksCoreTests:android.content.res.ConfigurationTest
  */
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
-public class ConfigurationTest extends TestCase {
+public class ConfigurationTest {
+
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
     @Test
     public void testUpdateFromPreservesRoundBit() {
         Configuration config = new Configuration();
@@ -82,7 +90,7 @@
 
     @Test
     public void testReadWriteProto() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
+        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
         final File testDir = new File(context.getFilesDir(), "ConfigurationTest");
         testDir.mkdirs();
         final File proto = new File(testDir, "configs");
diff --git a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
index 85f5d69..3fcd372 100644
--- a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
+++ b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
@@ -26,16 +26,17 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-import android.app.Instrumentation;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.ravenwood.RavenwoodRule;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.frameworks.coretests.R;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.xmlpull.v1.XmlPullParserException;
@@ -51,13 +52,14 @@
 @RunWith(AndroidJUnit4.class)
 public class FontResourcesParserTest {
 
-    private Instrumentation mInstrumentation;
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
     private Resources mResources;
 
     @Before
     public void setup() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mResources = mInstrumentation.getContext().getResources();
+        mResources = InstrumentationRegistry.getInstrumentation().getContext().getResources();
     }
 
     @Test
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
index c7d5825..c0a9bc2 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
@@ -20,6 +20,8 @@
 import android.platform.test.annotations.RequiresFlagsEnabled
 import android.platform.test.flag.junit.CheckFlagsRule
 import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.platform.test.flag.junit.RavenwoodFlagsValueProvider
+import android.platform.test.ravenwood.RavenwoodRule
 import android.util.SparseArray
 import androidx.core.util.forEach
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -27,15 +29,14 @@
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
+import kotlin.math.ceil
+import kotlin.math.floor
+import kotlin.random.Random.Default.nextFloat
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
-import kotlin.math.ceil
-import kotlin.math.floor
 import org.junit.Test
 import org.junit.runner.RunWith
-import java.lang.IllegalStateException
-import kotlin.random.Random.Default.nextFloat
 
 /**
  * Unit tests for FontScaleConverterFactory. Note that some similar tests are in
@@ -46,7 +47,15 @@
 class FontScaleConverterFactoryTest {
 
     @get:Rule
-    val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+    val ravenwoodRule: RavenwoodRule = RavenwoodRule.Builder().build()
+
+    @get:Rule
+    val checkFlagsRule: CheckFlagsRule =
+        if (RavenwoodRule.isOnRavenwood()) {
+            RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule()
+        } else {
+            DeviceFlagsValueProvider.createCheckFlagsRule()
+        }
 
     private var defaultLookupTables: SparseArray<FontScaleConverter>? = null
 
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
index 2c61442..0e5d926 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
@@ -17,8 +17,10 @@
 package android.content.res
 
 import android.platform.test.annotations.Presubmit
+import android.platform.test.ravenwood.RavenwoodRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -26,6 +28,9 @@
 @RunWith(AndroidJUnit4::class)
 class FontScaleConverterTest {
 
+    @get:Rule
+    val ravenwoodRule: RavenwoodRule = RavenwoodRule.Builder().build()
+
     @Test
     fun straightInterpolation() {
         val table = createTable(8f to 8f, 10f to 10f, 20f to 20f)
diff --git a/core/tests/coretests/src/android/content/res/ResourceCacheActivity.java b/core/tests/coretests/src/android/content/res/ResourceCacheActivity.java
deleted file mode 100644
index f37e549..0000000
--- a/core/tests/coretests/src/android/content/res/ResourceCacheActivity.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-* Copyright (C) 2014 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package android.content.res;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.os.Bundle;
-
-import java.lang.ref.WeakReference;
-
-public class ResourceCacheActivity extends Activity {
-    static WeakReference<ResourceCacheActivity> lastCreatedInstance;
-
-    @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        lastCreatedInstance = new WeakReference<ResourceCacheActivity>(this);
-    }
-
-    public static ResourceCacheActivity getLastCreatedInstance() {
-        return lastCreatedInstance == null ? null : lastCreatedInstance.get();
-    }
-}
diff --git a/core/tests/coretests/src/android/content/res/ResourcesDrawableTest.java b/core/tests/coretests/src/android/content/res/ResourcesDrawableTest.java
index ac69a0f..6a09848 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesDrawableTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesDrawableTest.java
@@ -24,22 +24,29 @@
 import android.graphics.drawable.ColorStateListDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LayerDrawable;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.ravenwood.RavenwoodRule;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.frameworks.coretests.R;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @Presubmit
 @SmallTest
+@DisabledOnRavenwood(blockedBy = Drawable.class)
 @RunWith(AndroidJUnit4.class)
 public class ResourcesDrawableTest {
 
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
     @Test
     public void testLoadColorAsDrawable() {
         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
diff --git a/core/tests/coretests/src/android/content/res/ResourcesLocaleTest.java b/core/tests/coretests/src/android/content/res/ResourcesLocaleTest.java
index 26e4349..fdfddc8 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesLocaleTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesLocaleTest.java
@@ -16,29 +16,52 @@
 
 package android.content.res;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import android.content.Context;
 import android.os.FileUtils;
 import android.os.LocaleList;
 import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
+import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.DisplayMetrics;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.frameworks.coretests.R;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.io.File;
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Locale;
 
 @Presubmit
-public class ResourcesLocaleTest extends AndroidTestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ResourcesLocaleTest {
+
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
+    private Context mContext;
+
+    @Before
+    public void setup() {
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+    }
 
     private String extractApkAndGetPath(int id) throws Exception {
-        final Resources resources = getContext().getResources();
+        final Resources resources = mContext.getResources();
         try (InputStream is = resources.openRawResource(id)) {
-            File path = new File(getContext().getFilesDir(), resources.getResourceEntryName(id));
+            File path = new File(mContext.getFilesDir(), resources.getResourceEntryName(id));
             FileUtils.copyToFileOrThrow(is, path);
             return path.getAbsolutePath();
         }
@@ -53,6 +76,15 @@
         return new Resources(assets, dm, new Configuration());
     }
 
+    private Resources createResourcesWithSelfApk() {
+        final AssetManager assets = new AssetManager();
+        assertTrue(assets.addAssetPath(mContext.getPackageResourcePath()) != 0);
+
+        final DisplayMetrics dm = new DisplayMetrics();
+        dm.setToDefaults();
+        return new Resources(assets, dm, new Configuration());
+    }
+
     private static void ensureNoLanguage(Resources resources, String language) {
         final String[] supportedLocales = resources.getAssets().getNonSystemLocales();
         for (String languageTag : supportedLocales) {
@@ -65,7 +97,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testEnglishIsAlwaysConsideredSupported() throws Exception {
         final Resources resources = createResourcesWithApk(R.raw.locales);
         ensureNoLanguage(resources, "en");
@@ -82,7 +114,7 @@
                 resources.getConfiguration().getLocales().get(0));
     }
 
-    @SmallTest
+    @Test
     public void testSelectFirstSupportedLanguage() throws Exception {
         final Resources resources = createResourcesWithApk(R.raw.locales);
         ensureNoLanguage(resources, "fr");
@@ -99,7 +131,7 @@
                 resources.getConfiguration().getLocales().get(0));
     }
 
-    @SmallTest
+    @Test
     public void testDeprecatedISOLanguageCode() {
         assertResGetString(Locale.US, R.string.locale_test_res_1, "Testing ID");
         assertResGetString(Locale.forLanguageTag("id"), R.string.locale_test_res_2, "Pengujian IN");
@@ -115,7 +147,8 @@
         LocaleList locales = new LocaleList(locale);
         final Configuration config = new Configuration();
         config.setLocales(locales);
-        Context newContext = getContext().createConfigurationContext(config);
-        assertEquals(expectedString, newContext.getResources().getString(resId));
+        final Resources resources = createResourcesWithSelfApk();
+        resources.updateConfiguration(config, null);
+        assertEquals(expectedString, resources.getString(resId));
     }
 }
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index ee1b658..3eefe04 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -16,27 +16,34 @@
 
 package android.content.res;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
 import android.annotation.NonNull;
 import android.app.ResourcesManager;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.LocaleList;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.Postsubmit;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.flag.junit.RavenwoodFlagsValueProvider;
+import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
 import android.view.Display;
 import android.view.DisplayAdjustments;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
-
-import junit.framework.TestCase;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -49,7 +56,7 @@
 
 @Postsubmit
 @RunWith(AndroidJUnit4.class)
-public class ResourcesManagerTest extends TestCase {
+public class ResourcesManagerTest {
     private static final int SECONDARY_DISPLAY_ID = 1;
     private static final String APP_ONE_RES_DIR = "app_one.apk";
     private static final String APP_ONE_RES_SPLIT_DIR = "app_one_split.apk";
@@ -57,14 +64,20 @@
     private static final String LIB_RES_DIR = "lib.apk";
     private static final String TEST_LIB = "com.android.frameworks.coretests.bdr_helper_app1";
 
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            RavenwoodRule.isOnRavenwood()
+                    ? RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule()
+                    : DeviceFlagsValueProvider.createCheckFlagsRule();
+
     private ResourcesManager mResourcesManager;
     private Map<Integer, DisplayMetrics> mDisplayMetricsMap;
-    private PackageManager mPackageManager;
 
     @Before
     public void setUp() throws Exception {
-        super.setUp();
-
         mDisplayMetricsMap = new HashMap<>();
 
         DisplayMetrics defaultDisplayMetrics = new DisplayMetrics();
@@ -110,12 +123,11 @@
                 return mDisplayMetricsMap.get(displayId);
             }
         };
-
-        mPackageManager = InstrumentationRegistry.getContext().getPackageManager();
     }
 
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+    private PackageManager getPackageManager() {
+        return InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+    }
 
     @Test
     @SmallTest
@@ -356,6 +368,7 @@
     @Test
     @SmallTest
     @RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
+    @DisabledOnRavenwood(blockedBy = PackageManager.class)
     public void testExistingResourcesAfterResourcePathsRegistration()
              throws PackageManager.NameNotFoundException {
         // Inject ResourcesManager instance from this test to the ResourcesManager class so that all
@@ -370,7 +383,7 @@
         assertNotNull(resources);
         ResourcesImpl oriResImpl = resources.getImpl();
 
-        ApplicationInfo appInfo = mPackageManager.getApplicationInfo(TEST_LIB, 0);
+        ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_LIB, 0);
         Resources.registerResourcePaths(TEST_LIB, appInfo);
 
         assertNotSame(oriResImpl, resources.getImpl());
@@ -390,6 +403,7 @@
     @Test
     @SmallTest
     @RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
+    @DisabledOnRavenwood(blockedBy = PackageManager.class)
     public void testNewResourcesAfterResourcePathsRegistration()
             throws PackageManager.NameNotFoundException {
         // Inject ResourcesManager instance from this test to the ResourcesManager class so that all
@@ -397,7 +411,7 @@
         ResourcesManager oriResourcesManager = ResourcesManager.getInstance();
         ResourcesManager.setInstance(mResourcesManager);
 
-        ApplicationInfo appInfo = mPackageManager.getApplicationInfo(TEST_LIB, 0);
+        ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_LIB, 0);
         Resources.registerResourcePaths(TEST_LIB, appInfo);
 
         // Create a Resources after register resources' paths for a package.
@@ -420,6 +434,7 @@
     @Test
     @SmallTest
     @RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
+    @DisabledOnRavenwood(blockedBy = PackageManager.class)
     public void testExistingResourcesCreatedByConstructorAfterResourcePathsRegistration()
             throws PackageManager.NameNotFoundException {
         // Inject ResourcesManager instance from this test to the ResourcesManager class so that all
@@ -437,7 +452,7 @@
 
         ResourcesImpl oriResImpl = resources.getImpl();
 
-        ApplicationInfo appInfo = mPackageManager.getApplicationInfo(TEST_LIB, 0);
+        ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_LIB, 0);
         Resources.registerResourcePaths(TEST_LIB, appInfo);
 
         assertNotSame(oriResImpl, resources.getImpl());
@@ -456,6 +471,7 @@
     @Test
     @SmallTest
     @RequiresFlagsEnabled(Flags.FLAG_REGISTER_RESOURCE_PATHS)
+    @DisabledOnRavenwood(blockedBy = PackageManager.class)
     public void testNewResourcesWithOutdatedImplAfterResourcePathsRegistration()
             throws PackageManager.NameNotFoundException {
         ResourcesManager oriResourcesManager = ResourcesManager.getInstance();
@@ -467,7 +483,7 @@
         assertNotNull(old_resources);
         ResourcesImpl oldImpl = old_resources.getImpl();
 
-        ApplicationInfo appInfo = mPackageManager.getApplicationInfo(TEST_LIB, 0);
+        ApplicationInfo appInfo = getPackageManager().getApplicationInfo(TEST_LIB, 0);
         Resources.registerResourcePaths(TEST_LIB, appInfo);
 
         // Create another resources with identical parameters.
diff --git a/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java b/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java
index afbf8db..b86029b 100644
--- a/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java
+++ b/core/tests/coretests/src/android/view/DisplayAdjustmentsTests.java
@@ -19,9 +19,11 @@
 import static org.junit.Assert.assertEquals;
 
 import android.content.res.Configuration;
+import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -34,6 +36,9 @@
 @RunWith(AndroidJUnit4.class)
 public class DisplayAdjustmentsTests {
 
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
+
     @Test
     public void testDefaultConstructor_hasEmptyConfiguration() {
         DisplayAdjustments emptyAdjustments = new DisplayAdjustments();
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
index 19b46e3..04aa04d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
@@ -63,7 +63,11 @@
                 if (categories.isEmpty()) {
                     ShortcutsUiState.Inactive
                 } else {
-                    val filteredCategories = filterCategoriesBySearchQuery(query, categories)
+                    /* temporarily hiding launcher shortcut categories until b/327141011
+                     * is completed. */
+                    val categoriesWithLauncherExcluded = excludeLauncherApp(categories)
+                    val filteredCategories =
+                        filterCategoriesBySearchQuery(query, categoriesWithLauncherExcluded)
                     ShortcutsUiState.Active(
                         searchQuery = query,
                         shortcutCategories = filteredCategories,
@@ -77,15 +81,27 @@
                 initialValue = ShortcutsUiState.Inactive
             )
 
+    private suspend fun excludeLauncherApp(
+        categories: List<ShortcutCategory>
+    ): List<ShortcutCategory> {
+        val launcherAppCategory =
+            categories.firstOrNull { it.type is CurrentApp && isLauncherApp(it.type.packageName) }
+        return if (launcherAppCategory != null) {
+            categories - launcherAppCategory
+        } else {
+            categories
+        }
+    }
+
     private suspend fun getDefaultSelectedCategory(
         categories: List<ShortcutCategory>
     ): ShortcutCategoryType? {
         val currentAppShortcuts =
-            categories.firstOrNull { it.type is CurrentApp && !isAppLauncher(it.type.packageName) }
+            categories.firstOrNull { it.type is CurrentApp && !isLauncherApp(it.type.packageName) }
         return currentAppShortcuts?.type ?: categories.firstOrNull()?.type
     }
 
-    private suspend fun isAppLauncher(packageName: String): Boolean {
+    private suspend fun isLauncherApp(packageName: String): Boolean {
         return withContext(backgroundDispatcher) {
             roleManager
                 .getRoleHoldersAsUser(RoleManager.ROLE_HOME, userTracker.userHandle)
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index 231179b..5cffdec 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -222,8 +222,16 @@
 android.content.res.AssetFileDescriptor
 android.content.res.AssetManager
 android.content.res.AssetManager$Builder
+android.content.res.ConfigurationBoundResourceCache
+android.content.res.Configuration
+android.content.res.CompatibilityInfo
+android.content.res.ConstantState
 android.content.res.DrawableCache
 android.content.res.Element
+android.content.res.FontResourcesParser
+android.content.res.FontScaleConverter
+android.content.res.FontScaleConverterImpl
+android.content.res.FontScaleConverterFactory
 android.content.res.Resources
 android.content.res.Resources$Theme
 android.content.res.ResourceId
@@ -231,6 +239,7 @@
 android.content.res.ResourcesKey
 android.content.res.StringBlock
 android.content.res.TagCounter
+android.content.res.ThemedResourceCache
 android.content.res.TypedArray
 android.content.res.Validator
 android.content.res.XmlBlock
@@ -275,6 +284,7 @@
 
 android.app.ActivityManager
 android.app.ActivityOptions
+android.app.ApplicationPackageManager
 android.app.BroadcastOptions
 android.app.ComponentOptions
 android.app.Instrumentation
@@ -288,6 +298,7 @@
 android.view.Display
 android.view.Display$HdrCapabilities
 android.view.Display$Mode
+android.view.DisplayAdjustments
 android.view.DisplayInfo
 android.view.inputmethod.InputBinding
 
diff --git a/ravenwood/texts/ravenwood-framework-policies.txt b/ravenwood/texts/ravenwood-framework-policies.txt
index 3062863..2d49128 100644
--- a/ravenwood/texts/ravenwood-framework-policies.txt
+++ b/ravenwood/texts/ravenwood-framework-policies.txt
@@ -69,20 +69,3 @@
 # Just enough to allow ResourcesManager to run
 class android.hardware.display.DisplayManagerGlobal keep
     method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore
-
-# These classes will be properly enabled in follow-up CLs
-
-class android.content.res.FontResourcesParser keepclass
-class android.content.res.FontResourcesParser.FamilyResourceEntry keepclass
-class android.content.res.FontResourcesParser.ProviderResourceEntry keepclass
-class android.content.res.FontResourcesParser.FontFamilyFilesResourceEntry keepclass
-class android.content.res.FontResourcesParser.FontFileResourceEntry keepclass
-class android.content.res.FontScaleConverter keepclass
-class android.content.res.FontScaleConverterImpl keepclass
-class android.content.res.FontScaleConverterFactory keepclass
-class android.content.res.ThemedResourceCache keepclass
-class android.content.res.ConfigurationBoundResourceCache keepclass
-class android.content.res.Configuration keepclass
-class android.content.res.CompatibilityInfo keepclass
-class android.content.res.ConstantState keepclass
-class android.view.DisplayAdjustments keepclass
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index f332ed9..4eb50a9 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -41,6 +41,7 @@
 import android.app.PendingIntent;
 import android.app.admin.DevicePolicyManager;
 import android.companion.AssociationInfo;
+import android.companion.virtual.ActivityPolicyExemption;
 import android.companion.virtual.IVirtualDevice;
 import android.companion.virtual.IVirtualDeviceActivityListener;
 import android.companion.virtual.IVirtualDeviceIntentInterceptor;
@@ -522,13 +523,37 @@
 
     @Override // Binder call
     @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    public void addActivityPolicyExemption(@NonNull ComponentName componentName) {
+    public void addActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
         super.addActivityPolicyExemption_enforcePermission();
+        final int displayId = exemption.getDisplayId();
+        if (exemption.getComponentName() == null || displayId != Display.INVALID_DISPLAY) {
+            if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+                return;
+            }
+        }
         synchronized (mVirtualDeviceLock) {
-            if (mActivityPolicyExemptions.add(componentName)) {
-                for (int i = 0; i < mVirtualDisplays.size(); i++) {
-                    mVirtualDisplays.valueAt(i).getWindowPolicyController()
-                            .addActivityPolicyExemption(componentName);
+            if (displayId != Display.INVALID_DISPLAY) {
+                checkDisplayOwnedByVirtualDeviceLocked(displayId);
+                if (exemption.getComponentName() != null) {
+                    mVirtualDisplays.get(displayId).getWindowPolicyController()
+                            .addActivityPolicyExemption(exemption.getComponentName());
+                } else if (exemption.getPackageName() != null) {
+                    mVirtualDisplays.get(displayId).getWindowPolicyController()
+                            .addActivityPolicyExemption(exemption.getPackageName());
+                }
+            } else {
+                if (exemption.getComponentName() != null
+                        && mActivityPolicyExemptions.add(exemption.getComponentName())) {
+                    for (int i = 0; i < mVirtualDisplays.size(); i++) {
+                        mVirtualDisplays.valueAt(i).getWindowPolicyController()
+                                .addActivityPolicyExemption(exemption.getComponentName());
+                    }
+                } else if (exemption.getPackageName() != null
+                        && mActivityPolicyPackageExemptions.add(exemption.getPackageName())) {
+                    for (int i = 0; i < mVirtualDisplays.size(); i++) {
+                        mVirtualDisplays.valueAt(i).getWindowPolicyController()
+                                .addActivityPolicyExemption(exemption.getPackageName());
+                    }
                 }
             }
         }
@@ -536,112 +561,42 @@
 
     @Override // Binder call
     @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    public void removeActivityPolicyExemption(@NonNull ComponentName componentName) {
+    public void removeActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
         super.removeActivityPolicyExemption_enforcePermission();
-        synchronized (mVirtualDeviceLock) {
-            if (mActivityPolicyExemptions.remove(componentName)) {
-                for (int i = 0; i < mVirtualDisplays.size(); i++) {
-                    mVirtualDisplays.valueAt(i).getWindowPolicyController()
-                            .removeActivityPolicyExemption(componentName);
-                }
+        final int displayId = exemption.getDisplayId();
+        if (exemption.getComponentName() == null || displayId != Display.INVALID_DISPLAY) {
+            if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+                return;
             }
         }
-    }
-
-    @Override // Binder call
-    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    public void addActivityPolicyPackageExemption(@NonNull String packageName) {
-        super.addActivityPolicyPackageExemption_enforcePermission();
-        if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
-            return;
-        }
         synchronized (mVirtualDeviceLock) {
-            if (mActivityPolicyPackageExemptions.add(packageName)) {
-                for (int i = 0; i < mVirtualDisplays.size(); i++) {
-                    mVirtualDisplays.valueAt(i).getWindowPolicyController()
-                            .addActivityPolicyExemption(packageName);
+            if (displayId != Display.INVALID_DISPLAY) {
+                checkDisplayOwnedByVirtualDeviceLocked(displayId);
+                if (exemption.getComponentName() != null) {
+                    mVirtualDisplays.get(displayId).getWindowPolicyController()
+                            .removeActivityPolicyExemption(exemption.getComponentName());
+                } else if (exemption.getPackageName() != null) {
+                    mVirtualDisplays.get(displayId).getWindowPolicyController()
+                            .removeActivityPolicyExemption(exemption.getPackageName());
+                }
+            } else {
+                if (exemption.getComponentName() != null
+                        && mActivityPolicyExemptions.remove(exemption.getComponentName())) {
+                    for (int i = 0; i < mVirtualDisplays.size(); i++) {
+                        mVirtualDisplays.valueAt(i).getWindowPolicyController()
+                                .removeActivityPolicyExemption(exemption.getComponentName());
+                    }
+                } else if (exemption.getPackageName() != null
+                        && mActivityPolicyPackageExemptions.remove(exemption.getPackageName())) {
+                    for (int i = 0; i < mVirtualDisplays.size(); i++) {
+                        mVirtualDisplays.valueAt(i).getWindowPolicyController()
+                                .removeActivityPolicyExemption(exemption.getPackageName());
+                    }
                 }
             }
         }
     }
 
-    @Override // Binder call
-    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    public void removeActivityPolicyPackageExemption(@NonNull String packageName) {
-        super.removeActivityPolicyPackageExemption_enforcePermission();
-        if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
-            return;
-        }
-        synchronized (mVirtualDeviceLock) {
-            if (mActivityPolicyPackageExemptions.remove(packageName)) {
-                for (int i = 0; i < mVirtualDisplays.size(); i++) {
-                    mVirtualDisplays.valueAt(i).getWindowPolicyController()
-                            .removeActivityPolicyExemption(packageName);
-                }
-            }
-        }
-    }
-
-    @Override // Binder call
-    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    public void addActivityPolicyExemptionForDisplay(
-            int displayId, @NonNull ComponentName componentName) {
-        super.addActivityPolicyExemptionForDisplay_enforcePermission();
-        if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
-            return;
-        }
-        synchronized (mVirtualDeviceLock) {
-            checkDisplayOwnedByVirtualDeviceLocked(displayId);
-            mVirtualDisplays.get(displayId).getWindowPolicyController()
-                    .addActivityPolicyExemption(componentName);
-        }
-    }
-
-    @Override // Binder call
-    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    public void removeActivityPolicyExemptionForDisplay(
-            int displayId, @NonNull ComponentName componentName) {
-        super.removeActivityPolicyExemptionForDisplay_enforcePermission();
-        if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
-            return;
-        }
-        synchronized (mVirtualDeviceLock) {
-            checkDisplayOwnedByVirtualDeviceLocked(displayId);
-            mVirtualDisplays.get(displayId).getWindowPolicyController()
-                    .removeActivityPolicyExemption(componentName);
-        }
-    }
-
-    @Override // Binder call
-    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    public void addActivityPolicyPackageExemptionForDisplay(
-            int displayId, @NonNull String packageName) {
-        super.addActivityPolicyPackageExemptionForDisplay_enforcePermission();
-        if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
-            return;
-        }
-        synchronized (mVirtualDeviceLock) {
-            checkDisplayOwnedByVirtualDeviceLocked(displayId);
-            mVirtualDisplays.get(displayId).getWindowPolicyController()
-                    .addActivityPolicyExemption(packageName);
-        }
-    }
-
-    @Override // Binder call
-    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
-    public void removeActivityPolicyPackageExemptionForDisplay(
-            int displayId, @NonNull String packageName) {
-        super.removeActivityPolicyPackageExemptionForDisplay_enforcePermission();
-        if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
-            return;
-        }
-        synchronized (mVirtualDeviceLock) {
-            checkDisplayOwnedByVirtualDeviceLocked(displayId);
-            mVirtualDisplays.get(displayId).getWindowPolicyController()
-                    .removeActivityPolicyExemption(packageName);
-        }
-    }
-
     private void sendPendingIntent(int displayId, PendingIntent pendingIntent)
             throws PendingIntent.CanceledException {
         final ActivityOptions options = ActivityOptions.makeBasic().setLaunchDisplayId(displayId);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 27024a7..a27360d 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -125,9 +125,9 @@
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.util.Preconditions;
+import com.android.server.crashrecovery.CrashRecoveryHelper;
 import com.android.server.EventLogTags;
 import com.android.server.LockGuard;
-import com.android.server.RescueParty;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
 import com.android.server.UiThread;
@@ -4031,7 +4031,7 @@
             }
         }
         if (mHandler == null || !mSystemReady) {
-            if (RescueParty.isRecoveryTriggeredReboot()) {
+            if (CrashRecoveryHelper.isRecoveryTriggeredReboot()) {
                 // If we're stuck in a really low-level reboot loop, and a
                 // rescue party is trying to prompt the user for a factory data
                 // reset, we must GET TO DA CHOPPA!
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 4b4e442..d209ea9 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -59,8 +59,8 @@
 import android.view.WindowManager;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.crashrecovery.CrashRecoveryHelper;
 import com.android.server.LocalServices;
-import com.android.server.RescueParty;
 import com.android.server.statusbar.StatusBarManagerInternal;
 
 import java.io.File;
@@ -339,7 +339,7 @@
                             com.android.internal.R.string.reboot_to_update_reboot));
             }
         } else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) {
-            if (RescueParty.isRecoveryTriggeredReboot()) {
+            if (CrashRecoveryHelper.isRecoveryTriggeredReboot()) {
                 // We're not actually doing a factory reset yet; we're rebooting
                 // to ask the user if they'd like to reset, so give them a less
                 // scary dialog message.
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index b768bb1..e76e94d 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1804,7 +1804,7 @@
                 // If on a rotation leash, the wallpaper token surface needs to be shown explicitly
                 // because shell only gets the leash and the wallpaper token surface is not allowed
                 // to be changed by non-transition logic until the transition is finished.
-                if (Flags.ensureWallpaperInTransitions() && wp.isVisibleRequested()
+                if (wp.mWmService.mFlags.mEnsureWallpaperInTransitions && wp.isVisibleRequested()
                         && wp.getFixedRotationLeash() != null) {
                     transaction.show(wp.mSurfaceControl);
                 }
@@ -2216,7 +2216,8 @@
             if (wallpaper != null) {
                 if (!wallpaper.isVisible() && wallpaper.isVisibleRequested()) {
                     wallpaper.commitVisibility(showWallpaper);
-                } else if (Flags.ensureWallpaperInTransitions() && wallpaper.isVisible()
+                } else if (wallpaper.mWmService.mFlags.mEnsureWallpaperInTransitions
+                        && wallpaper.isVisible()
                         && !showWallpaper && !wallpaper.getDisplayContent().isKeyguardLocked()
                         && !wallpaperIsOwnTarget(wallpaper)) {
                     wallpaper.setVisibleRequested(false);
@@ -2934,7 +2935,7 @@
                     // Use parent rotation because shell doesn't know the surface is rotated.
                     endRotation = parent.getWindowConfiguration().getRotation();
                 }
-            } else if (isWallpaper(target) && Flags.ensureWallpaperInTransitions()
+            } else if (isWallpaper(target) && target.mWmService.mFlags.mEnsureWallpaperInTransitions
                     && target.getRelativeDisplayRotation() != 0
                     && !target.mTransitionController.useShellTransitionsRotation()) {
                 // If the wallpaper is "fixed-rotated", shell is unaware of this, so use the
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index db95d96..4536f24 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -59,7 +59,6 @@
 import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.wallpaper.WallpaperCropper.WallpaperCropUtils;
-import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -759,7 +758,7 @@
 
     void collectTopWallpapers(Transition transition) {
         if (mFindResults.hasTopShowWhenLockedWallpaper()) {
-            if (Flags.ensureWallpaperInTransitions()) {
+            if (mService.mFlags.mEnsureWallpaperInTransitions) {
                 transition.collect(mFindResults.mTopWallpaper.mTopShowWhenLockedWallpaper.mToken);
             } else {
                 transition.collect(mFindResults.mTopWallpaper.mTopShowWhenLockedWallpaper);
@@ -767,7 +766,7 @@
 
         }
         if (mFindResults.hasTopHideWhenLockedWallpaper()) {
-            if (Flags.ensureWallpaperInTransitions()) {
+            if (mService.mFlags.mEnsureWallpaperInTransitions) {
                 transition.collect(mFindResults.mTopWallpaper.mTopHideWhenLockedWallpaper.mToken);
             } else {
                 transition.collect(mFindResults.mTopWallpaper.mTopHideWhenLockedWallpaper);
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 31156de..384d111 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -32,7 +32,6 @@
 import android.util.SparseArray;
 
 import com.android.internal.protolog.ProtoLog;
-import com.android.window.flags.Flags;
 
 import java.util.function.Consumer;
 
@@ -85,7 +84,7 @@
     public void prepareSurfaces() {
         super.prepareSurfaces();
 
-        if (Flags.ensureWallpaperInTransitions()) {
+        if (mWmService.mFlags.mEnsureWallpaperInTransitions) {
             // Similar to Task.prepareSurfaces, outside of transitions we need to apply visibility
             // changes directly. In transitions the transition player will take care of applying the
             // visibility change.
diff --git a/services/core/java/com/android/server/wm/WindowManagerFlags.java b/services/core/java/com/android/server/wm/WindowManagerFlags.java
index f3e6a18..7ef8d8d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerFlags.java
+++ b/services/core/java/com/android/server/wm/WindowManagerFlags.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wm;
 
+import android.app.AppGlobals;
+import android.content.pm.PackageManager;
+
 import com.android.window.flags.Flags;
 
 /**
@@ -53,5 +56,26 @@
     final boolean mRespectNonTopVisibleFixedOrientation =
             Flags.respectNonTopVisibleFixedOrientation();
 
+    final boolean mEnsureWallpaperInTransitions;
+
     /* End Available Flags */
+
+    WindowManagerFlags() {
+        boolean isWatch;
+        try {
+            isWatch = AppGlobals.getPackageManager().hasSystemFeature(
+                        PackageManager.FEATURE_WATCH, 0 /* version */);
+        } catch (Throwable e) {
+            isWatch = false;
+        }
+        /*
+         * Wallpaper enablement is separated on Wear vs Phone as the latter appears to still exhibit
+         * regressions when enabled (for example b/353870983). These don't exist on Wear likely
+         * due to differences in SysUI/transition implementations. Wear enablement is required for
+         * 25Q2 while phone doesn't have as pressing a constraint and will wait to resolve any
+         * outstanding issues prior to roll-out.
+         */
+        mEnsureWallpaperInTransitions = (isWatch && Flags.ensureWallpaperInWearTransitions())
+                || Flags.ensureWallpaperInTransitions();
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 24a2a62..b40cf56 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -67,9 +67,8 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 
-import com.android.internal.protolog.common.LogLevel;
 import com.android.internal.protolog.ProtoLog;
-import com.android.window.flags.Flags;
+import com.android.internal.protolog.common.LogLevel;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
@@ -413,7 +412,7 @@
             ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY: %s. %s",
                     mWin, new RuntimeException().fillInStackTrace());
             destroySurface(t);
-            if (Flags.ensureWallpaperInTransitions()) {
+            if (mService.mFlags.mEnsureWallpaperInTransitions) {
                 if (mWallpaperControllerLocked.isWallpaperTarget(mWin)) {
                     mWin.requestUpdateWallpaperIfNeeded();
                 }
@@ -464,7 +463,7 @@
 
         if (!w.isOnScreen()) {
             hide(t, "prepareSurfaceLocked");
-            if (!w.mIsWallpaper || !Flags.ensureWallpaperInTransitions()) {
+            if (!w.mIsWallpaper || !mService.mFlags.mEnsureWallpaperInTransitions) {
                 mWallpaperControllerLocked.hideWallpapers(w);
             }