Merge "Fix small issue where overflow expanded view wouldn't show" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index bd1d3e2..e184704 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -373,6 +373,11 @@
     name: "android.security.flags-aconfig-java-export",
     aconfig_declarations: "android.security.flags-aconfig",
     mode: "exported",
+    min_sdk_version: "30",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.wifi",
+    ],
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
diff --git a/core/api/current.txt b/core/api/current.txt
index 45f6a3f..a42a8de 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -24166,6 +24166,8 @@
     field public static final String KEY_OPERATING_RATE = "operating-rate";
     field public static final String KEY_OUTPUT_REORDER_DEPTH = "output-reorder-depth";
     field public static final String KEY_PCM_ENCODING = "pcm-encoding";
+    field @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public static final String KEY_PICTURE_PROFILE_ID = "picture-profile-id";
+    field @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public static final String KEY_PICTURE_PROFILE_INSTANCE = "picture-profile-instance";
     field public static final String KEY_PICTURE_TYPE = "picture-type";
     field public static final String KEY_PIXEL_ASPECT_RATIO_HEIGHT = "sar-height";
     field public static final String KEY_PIXEL_ASPECT_RATIO_WIDTH = "sar-width";
@@ -25613,6 +25615,7 @@
     method public void addOnSpatializerStateChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerStateChangedListener);
     method public boolean canBeSpatialized(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioFormat);
     method public int getImmersiveAudioLevel();
+    method @FlaggedApi("android.media.audio.spatializer_capabilities") @NonNull public java.util.List<java.lang.Integer> getSpatializedChannelMasks();
     method public boolean isAvailable();
     method public boolean isEnabled();
     method public boolean isHeadTrackerAvailable();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index e225bb4..d971f8b 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -16196,6 +16196,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallForwarding(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CallForwardingInfoCallback);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallWaitingStatus(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @FlaggedApi("com.android.internal.telephony.flags.carrier_id_from_carrier_identifier") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getCarrierIdFromCarrierIdentifier(@NonNull android.service.carrier.CarrierIdentifier);
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e766ae2..42fa9e7 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -14453,7 +14453,7 @@
      * </ul>
      * <p>
      * The following methods are supported for the parent instance but can only be called by the
-     * profile owner of a managed profile that was created during the device provisioning flow:
+     * profile owner on an <a href="#organization-owned">organization owned</a> managed profile:
      * <ul>
      * <li>{@link #getPasswordComplexity}</li>
      * <li>{@link #setCameraDisabled}</li>
@@ -14461,11 +14461,6 @@
      * <li>{@link #setAccountManagementDisabled(ComponentName, String, boolean)}</li>
      * <li>{@link #setPermittedInputMethods}</li>
      * <li>{@link #getPermittedInputMethods}</li>
-     * </ul>
-     *
-     * <p>The following methods can be called by the profile owner of a managed profile
-     * on an organization-owned device:
-     * <ul>
      * <li>{@link #wipeData}</li>
      * </ul>
      *
@@ -18177,4 +18172,4 @@
         }
         return HEADLESS_DEVICE_OWNER_MODE_UNSUPPORTED;
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 3d2d487..02eed1a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -7720,6 +7720,7 @@
     @IntDef(flag = true, prefix = { "EXTENDED_FLAG_" }, value = {
             EXTENDED_FLAG_FILTER_MISMATCH,
             EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN,
+            EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ExtendedFlags {}
@@ -7740,6 +7741,13 @@
      */
     public static final int EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN = 1 << 1;
 
+    /**
+     * This flag indicates this intent called {@link #collectExtraIntentKeys()}.
+     *
+     * @hide
+     */
+    public static final int EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED = 1 << 2;
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // toUri() and parseUri() options.
@@ -12328,7 +12336,8 @@
     }
 
     private void collectNestedIntentKeysRecur(Set<Intent> visited) {
-        if (mExtras != null && !mExtras.isParcelled() && !mExtras.isEmpty()) {
+        addExtendedFlags(EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED);
+        if (mExtras != null && !mExtras.isEmpty()) {
             for (String key : mExtras.keySet()) {
                 Object value = mExtras.get(key);
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 23f7629..d5b5258 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10999,6 +10999,25 @@
                 "emergency_gesture_ui_last_started_millis";
 
         /**
+         * Whether double tap the power button gesture is enabled.
+         *
+         * @hide
+         */
+        @Readable
+        public static final String DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED =
+                "double_tap_power_button_gesture_enabled";
+
+        /**
+         * Double tap power button gesture behavior.
+         * 0 = Camera launch
+         * 1 = Wallet launch
+         * @hide
+         */
+        @Readable
+        public static final String DOUBLE_TAP_POWER_BUTTON_GESTURE =
+                "double_tap_power_button_gesture";
+
+        /**
          * Whether the camera launch gesture to double tap the power button when the screen is off
          * should be disabled.
          *
diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig
index 6c92991..357aba3 100644
--- a/core/java/android/security/responsible_apis_flags.aconfig
+++ b/core/java/android/security/responsible_apis_flags.aconfig
@@ -96,6 +96,21 @@
 }
 
 flag {
+    name: "prevent_intent_redirect_throw_exception_if_nested_keys_not_collected"
+    namespace: "responsible_apis"
+    description: "Prevent intent redirect attacks by throwing exception if the intent does not collect nested keys"
+    bug: "361143368"
+}
+
+flag {
+    name: "prevent_intent_redirect_collect_nested_keys_on_server_if_not_collected"
+    namespace: "responsible_apis"
+    description: "Prevent intent redirect attacks by collecting nested keys on server if not yet collected"
+    bug: "361143368"
+    is_fixed_read_only: true
+}
+
+flag {
     name: "enable_intent_matching_flags"
     is_exported: true
     namespace: "permissions"
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 6af742f..2e0fe9e 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -256,6 +256,12 @@
     }
     optional Display display = 100;
 
+    message DoubleTapPowerButton {
+        optional SettingProto gesture_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto gesture = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+    optional DoubleTapPowerButton double_tap_power_button = 103;
+
     message Doze {
         option (android.msg_privacy).dest = DEST_EXPLICIT;
 
@@ -737,5 +743,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 103;
+    // Next tag = 104;
 }
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7f2c816..38ebda7 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2731,6 +2731,8 @@
     </string-array>
     <!-- The list of supported dream complications -->
     <integer-array name="config_supportedDreamComplications">
+        <!-- COMPLICATION_TYPE_TIME -->
+        <item>1</item>
     </integer-array>
 
     <!-- Are we allowed to dream while not plugged in? -->
diff --git a/core/xsd/permission.xsd b/core/xsd/permission.xsd
index 0ec8f7d..0a0ca7c 100644
--- a/core/xsd/permission.xsd
+++ b/core/xsd/permission.xsd
@@ -43,6 +43,7 @@
                 <xs:element name="disabled-until-used-preinstalled-carrier-app" type="disabled-until-used-preinstalled-carrier-app"/>
                 <xs:element name="privapp-permissions" type="privapp-permissions"/>
                 <xs:element name="oem-permissions" type="oem-permissions"/>
+                <xs:element name="signature-permissions" type="signature-permissions"/>
                 <xs:element name="hidden-api-whitelisted-app" type="hidden-api-whitelisted-app"/>
                 <xs:element name="allow-association" type="allow-association"/>
                 <xs:element name="bugreport-whitelisted" type="bugreport-whitelisted"/>
@@ -156,6 +157,21 @@
         </xs:sequence>
         <xs:attribute name="package" type="xs:string"/>
     </xs:complexType>
+    <xs:complexType name="signature-permissions">
+        <xs:sequence>
+            <xs:element name="permission" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:string"/>
+                </xs:complexType>
+            </xs:element>
+            <xs:element name="deny-permission" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:string"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+        <xs:attribute name="package" type="xs:string"/>
+    </xs:complexType>
     <xs:complexType name="hidden-api-whitelisted-app">
         <xs:attribute name="package" type="xs:string"/>
     </xs:complexType>
diff --git a/core/xsd/schema/current.txt b/core/xsd/schema/current.txt
index f3beea1..cdec6ab 100644
--- a/core/xsd/schema/current.txt
+++ b/core/xsd/schema/current.txt
@@ -183,6 +183,7 @@
     method public java.util.List<com.android.xml.permission.configfile.OemPermissions> getOemPermissions_optional();
     method public java.util.List<com.android.xml.permission.configfile.Permission> getPermission_optional();
     method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions> getPrivappPermissions_optional();
+    method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions> getSignaturePermissions_optional();
     method public java.util.List<com.android.xml.permission.configfile.SplitPermission> getSplitPermission_optional();
     method public java.util.List<com.android.xml.permission.configfile.SystemUserBlacklistedApp> getSystemUserBlacklistedApp_optional();
     method public java.util.List<com.android.xml.permission.configfile.SystemUserWhitelistedApp> getSystemUserWhitelistedApp_optional();
@@ -209,6 +210,26 @@
     method public void setName(String);
   }
 
+  public class SignaturePermissions {
+    ctor public SignaturePermissions();
+    method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions.DenyPermission> getDenyPermission();
+    method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions.Permission> getPermission();
+    method public String get_package();
+    method public void set_package(String);
+  }
+
+  public static class SignaturePermissions.DenyPermission {
+    ctor public SignaturePermissions.DenyPermission();
+    method public String getName();
+    method public void setName(String);
+  }
+
+  public static class SignaturePermissions.Permission {
+    ctor public SignaturePermissions.Permission();
+    method public String getName();
+    method public void setName(String);
+  }
+
   public class SplitPermission {
     ctor public SplitPermission();
     method public java.util.List<com.android.xml.permission.configfile.SplitPermission.Library> getLibrary();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 2945691..dc2025b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -898,7 +898,10 @@
             Bubble oldest = mOverflowBubbles.get(mOverflowBubbles.size() - 1);
             ProtoLog.d(WM_SHELL_BUBBLES, "overflow full, remove=%s", oldest.getKey());
             mStateChange.bubbleRemoved(oldest, Bubbles.DISMISS_OVERFLOW_MAX_REACHED);
-            mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED);
+            if (!mPositioner.isShowingInBubbleBar()) {
+                // Only logged for bubbles in stack view
+                mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED);
+            }
             mOverflowBubbles.remove(oldest);
             mStateChange.removedOverflowBubble = oldest;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index b6fa059..d57044a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -1417,7 +1417,6 @@
         mHandleMenu.show(
                 /* onToDesktopClickListener= */ () -> {
                     mOnToDesktopClickListener.accept(APP_HANDLE_MENU_BUTTON);
-                    mOnToDesktopClickListener.accept(APP_HANDLE_MENU_BUTTON);
                     return Unit.INSTANCE;
                 },
                 /* onToFullscreenClickListener= */ mOnToFullscreenClickListener,
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
index 176020f..6d12b00 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
@@ -49,6 +49,7 @@
         "wm-flicker-common-assertions",
         "launcher-helper-lib",
         "launcher-aosp-tapl",
+        "com_android_wm_shell_flags_lib",
     ],
 }
 
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index 6d396ea..9c71510 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
@@ -17,12 +17,16 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
 import android.tools.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.flicker.legacy.FlickerBuilder
 import android.tools.flicker.legacy.LegacyFlickerTest
 import android.tools.flicker.legacy.LegacyFlickerTestFactory
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.Flags
 import com.android.wm.shell.flicker.splitscreen.benchmark.DismissSplitScreenByGoHomeBenchmark
 import com.android.wm.shell.flicker.utils.ICommonAssertions
 import com.android.wm.shell.flicker.utils.appWindowBecomesInvisible
@@ -30,6 +34,7 @@
 import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesInvisible
 import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesInvisible
 import org.junit.FixMethodOrder
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
@@ -44,8 +49,13 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
 class DismissSplitScreenByGoHome(override val flicker: LegacyFlickerTest) :
     DismissSplitScreenByGoHomeBenchmark(flicker), ICommonAssertions {
+    @JvmField
+    @Rule
+    val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             defaultSetup(this)
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 08b0dd3..54a87ad 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -640,6 +640,9 @@
 
     boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af);
 
+    /* Returns a List<Integer> */
+    List getSpatializedChannelMasks();
+
     void registerSpatializerCallback(in ISpatializerCallback cb);
 
     void unregisterSpatializerCallback(in ISpatializerCallback cb);
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 4f94c3e..5038754 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -16,12 +16,12 @@
 
 package android.media;
 
-
 import static android.media.audio.Flags.FLAG_IAMF_DEFINITIONS_API;
+import static android.media.codec.Flags.FLAG_APV_SUPPORT;
 import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
 import static android.media.codec.Flags.FLAG_NUM_INPUT_SLOTS;
 import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
-import static android.media.codec.Flags.FLAG_APV_SUPPORT;
+import static android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES;
 
 import static com.android.media.codec.flags.Flags.FLAG_CODEC_IMPORTANCE;
 import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME;
@@ -1796,6 +1796,27 @@
     public static final String KEY_NUM_SLOTS = "num-slots";
 
     /**
+     * A key describing the picture profile ID to be applied to {@link MediaCodec}.
+     * <p>
+     * The associated value is a string.
+     * <p>
+     * @see {@link android.media.quality.PictureProfile}
+     * @see {@link android.media.quality.PictureProfile#getProfileId}
+     */
+    @FlaggedApi(FLAG_APPLY_PICTURE_PROFILES)
+    public static final String KEY_PICTURE_PROFILE_ID = "picture-profile-id";
+
+    /**
+     * A key describing the picture profile instance to be applied to {@link MediaCodec}.
+     * <p>
+     * The associated value is an instance of {@link android.media.quality.PictureProfile}.
+     * <p>
+     * @see {@link android.media.quality.PictureProfile}
+     */
+    @FlaggedApi(FLAG_APPLY_PICTURE_PROFILES)
+    public static final String KEY_PICTURE_PROFILE_INSTANCE = "picture-profile-instance";
+
+    /**
      * QpOffsetRect constitutes the metadata required for encoding a region of interest in an
      * image or a video frame. The region of interest is represented by a rectangle. The four
      * integer coordinates of the rectangle are stored in fields left, top, right, bottom.
diff --git a/media/java/android/media/Spatializer.java b/media/java/android/media/Spatializer.java
index 99fcaf2..95c4ad3 100644
--- a/media/java/android/media/Spatializer.java
+++ b/media/java/android/media/Spatializer.java
@@ -16,7 +16,10 @@
 
 package android.media;
 
+import static android.media.audio.Flags.FLAG_SPATIALIZER_CAPABILITIES;
+
 import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -35,6 +38,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
@@ -527,6 +531,28 @@
     }
 
     /**
+     * Returns a list of channel masks that represent the widest channel masks the spatializer
+     * is capable of rendering with individual channel positions.
+     * For instance a spatializer may only support virtual speaker positions for 5.1, it would
+     * therefore return {@link AudioFormat#CHANNEL_OUT_5POINT1}. But it would still return
+     * <code>true</code> when querying {@link #canBeSpatialized(AudioAttributes, AudioFormat)} it
+     * with a channel mask of {@link AudioFormat#CHANNEL_OUT_7POINT1POINT2}: the sound present
+     * in each channel would still be heard, but the sounds from the rear, side and top pairs would
+     * be mixed together, and be spatialized at the same location.
+     * @return a list of channel masks following the <code>CHANNEL_OUT_*</code> output channel
+     *     definitions found in {@link AudioFormat}.
+     */
+    @FlaggedApi(FLAG_SPATIALIZER_CAPABILITIES)
+    public @NonNull List<Integer> getSpatializedChannelMasks() {
+        try {
+            return mAm.getService().getSpatializedChannelMasks();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error querying getSpatializedChannelMasks", e);
+            return Collections.emptyList();
+        }
+    }
+
+    /**
      * Adds a listener to be notified of changes to the enabled state of the
      * {@code Spatializer}.
      * @param executor the {@code Executor} handling the callback
diff --git a/media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl b/media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl
new file mode 100644
index 0000000..550acba
--- /dev/null
+++ b/media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.analog;
+
+/**
+ * @hide
+ */
+interface IAnalogAttributeInterface {
+    int getVersion();
+    void setColorSystemCapability(in String[] list);
+    String[] getColorSystemCapability();
+}
diff --git a/media/java/android/media/tv/extension/event/IEventDownload.aidl b/media/java/android/media/tv/extension/event/IEventDownload.aidl
new file mode 100644
index 0000000..29c7553
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventDownload.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.media.tv.extension.event;
+
+import android.media.tv.extension.event.IEventDownloadListener;
+import android.os.Bundle;
+import android.os.IBinder;
+
+/**
+ * @hide
+ */
+interface IEventDownload {
+    // Create an event download session and return it as a Ibinder for DVB/DTMB
+    IBinder createSession(in Bundle eventDownloadParams, in IEventDownloadListener listener);
+}
diff --git a/media/java/android/media/tv/extension/event/IEventDownloadListener.aidl b/media/java/android/media/tv/extension/event/IEventDownloadListener.aidl
new file mode 100644
index 0000000..6d7d61f
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventDownloadListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.event;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IEventDownloadListener {
+    void onCompleted(in Bundle status);
+}
diff --git a/media/java/android/media/tv/extension/event/IEventDownloadSession.aidl b/media/java/android/media/tv/extension/event/IEventDownloadSession.aidl
new file mode 100644
index 0000000..fe7ee37
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventDownloadSession.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.media.tv.extension.event;
+
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IEventDownloadSession {
+    // Determine to execute barker channel or silent tune flow for related service type
+    int isBarkerOrSequentialDownloadByServiceType(in Bundle eventDownloadParams);
+    // Determine whether to start barker channel or silent tune flow.
+    int isBarkerOrSequentialDownloadByServiceRecord(in Bundle eventDownloadParams);
+    // Start event download.
+    void startTuningMultiplex(in Uri channelUri);
+    // Set active window channels.
+    void setActiveWindowChannelInfo(in Uri[] activeWinChannelInfos);
+    // Cancel barker channel or silent tune flow.
+    void cancel();
+    // Release barker channel or silent tune flow.
+    void release();
+}
diff --git a/media/java/android/media/tv/extension/event/IEventMonitor.aidl b/media/java/android/media/tv/extension/event/IEventMonitor.aidl
new file mode 100644
index 0000000..f6e7bd1
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventMonitor.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.media.tv.extension.event;
+
+import android.media.tv.extension.event.IEventMonitorListener;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IEventMonitor {
+    // Get present event information.
+    Bundle getPresentEventInfo(long channelDbId);
+    // Add present event information listener.
+    void addPresentEventInfoListener(in IEventMonitorListener listener);
+    // Remove present event information listener.
+    void removePresentEventInfoListener(in IEventMonitorListener listener);
+    // Get following event information.
+    Bundle getFollowingEventInfo(long channelDbId);
+    // Add following event information listener.
+    void addFollowingEventInfoListener(in IEventMonitorListener listener);
+    // Remove following event information listener.
+    void removeFollowingEventInfoListener(in IEventMonitorListener listener);
+    // Get SDT guidance information.
+    Bundle getSdtGuidanceInfo(long channelDbId);
+    // Set Event Background channel list info.
+    void setBgmTuneChannelInfo(in Uri[] tuneChannelInfos);
+}
diff --git a/media/java/android/media/tv/extension/event/IEventMonitorListener.aidl b/media/java/android/media/tv/extension/event/IEventMonitorListener.aidl
new file mode 100644
index 0000000..a00e542
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventMonitorListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.event;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IEventMonitorListener {
+    void onInfoChanged(long channelDbId, in Bundle eventinfo);
+}
diff --git a/media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl b/media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl
new file mode 100644
index 0000000..ff78aa4
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.IFavoriteNetworkListener;
+import android.os.Bundle;
+
+/**
+ * Country: Norway
+ * Broadcast Type: BROADCAST_TYPE_DVB_T
+ * (Operator: RiksTV)
+ *
+ * @hide
+ */
+interface IFavoriteNetwork {
+    // Get the favorite network information,If there are no conflicts, the array of Bundle is empty.
+    Bundle[] getFavoriteNetworks();
+    // Select and set one of two or more favorite networks detected by the service scan.
+    int setFavoriteNetwork(in Bundle favoriteNetworkSettings);
+    // Set the listener to be invoked when two or more favorite networks are detected.
+    int setListener(in IFavoriteNetworkListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl b/media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl
new file mode 100644
index 0000000..6994224
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IFavoriteNetworkListener {
+    void onDetectFavoriteNetwork(in Bundle detectFavoriteNetworks);
+}
diff --git a/media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl b/media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl
new file mode 100644
index 0000000..cdf6e23
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.media.tv.extension.scan;
+
+/**
+ * @hide
+ */
+interface IHDPlusInfo {
+    // Specifying a HDPlusInfo and start a network scan.
+    int setHDPlusInfo(String isBlindScanContinue, String isHDMode);
+}
diff --git a/media/java/android/media/tv/extension/scan/ILcnConflict.aidl b/media/java/android/media/tv/extension/scan/ILcnConflict.aidl
new file mode 100644
index 0000000..5dff39e
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ILcnConflict.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.ILcnConflictListener;
+import android.os.Bundle;
+
+/**
+ * Country: Italy, France
+ * Broadcast Type: BROADCAST_TYPE_DVB_T
+ *
+ * @hide
+ */
+interface ILcnConflict {
+    // Get the LCN conflict groups information, If there are no conflicts, the array of Bundle is empty.
+    Bundle[] getLcnConflictGroups();
+    // Resolve LCN conflicts caused by service scans.
+    int resolveLcnConflict(in Bundle[] lcnConflictSettings);
+    // Set the listener to be invoked the LCN conflict event.
+    int setListener(in ILcnConflictListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl b/media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl
new file mode 100644
index 0000000..6bbbeb8
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ILcnConflictListener {
+    void onDetectLcnConflict(in Bundle detectLcnConflicts);
+}
diff --git a/media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl b/media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl
new file mode 100644
index 0000000..f9a9d34
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.ILcnV2ChannelListListener;
+import android.os.Bundle;
+
+/**
+ * Country: (NorDig etc.)
+ * Broadcast Type: BROADCAST_TYPE_DVB_T, BROADCAST_TYPE_DVB_C
+ *
+ * @hide
+ */
+interface ILcnV2ChannelList {
+    // Get the LCN V2 channel list information. If there are no conflicts, the array of Bundle is empty.
+    Bundle[] getLcnV2ChannelLists();
+    // Select and set one of two or more LCN V2 channel list detected by the service scan.
+    int setLcnV2ChannelList(in Bundle lcnV2ChannelListSettings);
+    // Set the listener to be invoked when two or more LCN V2 channel list are detected.
+    int setListener(in ILcnV2ChannelListListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl b/media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl
new file mode 100644
index 0000000..cbdb83c
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ILcnV2ChannelListListener {
+    void onDetectLcnV2ChannelList(in Bundle detectLcnV2ChannelList);
+}
diff --git a/media/java/android/media/tv/extension/scan/IOperatorDetection.aidl b/media/java/android/media/tv/extension/scan/IOperatorDetection.aidl
new file mode 100644
index 0000000..770f866
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IOperatorDetection.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.IOperatorDetectionListener;
+import android.os.Bundle;
+
+/**
+ * Country: Any
+ * Broadcast Type: BROADCAST_TYPE_DVB_S
+ * (Operator: M7)
+ *
+ * @hide
+ */
+interface IOperatorDetection {
+    // Set the operator selected info for scanning.
+    int setOperatorDetection(in Bundle operatorSelected);
+    // Set the listener to be invoked when one or more operator detection has been detected by
+    // operator detection searches.
+    int setListener(in IOperatorDetectionListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl b/media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl
new file mode 100644
index 0000000..7dcd461
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+
+/**
+ * @hide
+ */
+oneway interface IOperatorDetectionListener {
+    void onDetectOperatorDetectionList(in Bundle[] detectOperatorDetectionList);
+}
diff --git a/media/java/android/media/tv/extension/scan/IRegionChannelList.aidl b/media/java/android/media/tv/extension/scan/IRegionChannelList.aidl
new file mode 100644
index 0000000..fe755f8
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IRegionChannelList.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.IRegionChannelListListener;
+
+/**
+ * @hide
+ */
+interface IRegionChannelList {
+    // Set the region channel list for scanning.
+    int setRegionChannelList(String regionChannelList);
+    // Set the listener to be invoked when one or more region channel list has been detected by
+    // region channel list searches.
+    int setListener(in IRegionChannelListListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl b/media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl
new file mode 100644
index 0000000..06b0eb5
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.scan;
+
+/**
+ * @hide
+ */
+oneway interface IRegionChannelListListener {
+    void onDetectRegionChannelList(in String[] detectRegionChannelList);
+}
diff --git a/media/java/android/media/tv/extension/scan/IScanInterface.aidl b/media/java/android/media/tv/extension/scan/IScanInterface.aidl
new file mode 100644
index 0000000..b44d1d2
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IScanInterface.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.IScanListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IScanInterface {
+    IBinder createSession(int broadcastType, String countryCode, String operator,
+        in IScanListener listener);
+    Bundle getParameters(int broadcastType, String countryCode, String operator,
+        in Bundle params);
+}
diff --git a/media/java/android/media/tv/extension/scan/IScanListener.aidl b/media/java/android/media/tv/extension/scan/IScanListener.aidl
new file mode 100644
index 0000000..2c4807f
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IScanListener.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IScanListener {
+    // notify events during scan.
+    void onEvent(in Bundle eventArgs);
+    // notify the scan progress.
+    void onScanProgress(String scanProgress, in Bundle scanProgressInfo);
+    // notify the scan completion.
+    void onScanCompleted(int scanResult);
+    // notify that the temporaily held channel list is stored.
+    void onStoreCompleted(int storeResult);
+}
diff --git a/media/java/android/media/tv/extension/scan/IScanSatSearch.aidl b/media/java/android/media/tv/extension/scan/IScanSatSearch.aidl
new file mode 100644
index 0000000..b8074fc
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IScanSatSearch.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+/**
+ * For satellite search function.
+ * @hide
+ */
+interface IScanSatSearch {
+    // Set currecnt LNB as customized LNB, default LNB is universal LNB
+    int setCustomizedLnb(String customizedLnb);
+}
diff --git a/media/java/android/media/tv/extension/scan/IScanSession.aidl b/media/java/android/media/tv/extension/scan/IScanSession.aidl
new file mode 100644
index 0000000..d42eca1
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IScanSession.aidl
@@ -0,0 +1,75 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IScanSession {
+    // Start a service scan.
+    int startScan(int broadcastType, String countryCode, String operator, in int[] frequency,
+        String scanType, String languageCode);
+    // Reset the scan information held in TIS.
+    int resetScan();
+    // Cancel scan.
+    int cancelScan();
+
+    // Get available interface for created ScanExtension interface.
+    String[] getAvailableExtensionInterfaceNames();
+    // Get extension interface for Scan.
+    IBinder getExtensionInterface(String name);
+
+    // Clear the results of the service scan from the service database.
+    int clearServiceList(in Bundle optionalClearParams);
+    // Store the results of the service scan from the service database.
+    int storeServiceList();
+    // Get a service information specified by the service information ID.
+    Bundle getServiceInfo(String serviceInfoId, in String[] keys);
+    // Get a service information ID list.
+    String[] getServiceInfoIdList();
+    // Get a list of service info by the filter.
+    Bundle getServiceInfoList(in Bundle filterInfo, in String[] keys);
+    // Update the service information.
+    int updateServiceInfo(in Bundle serviceInfo);
+    // Updates the service information for the specified service information ID in array list.
+    int updateServiceInfoByList(in Bundle[] serviceInfo);
+
+    /* DVBI specific functions */
+    // Get all of the serviceLists, parsed from Local TV storage, Broadcast, USB file discovery.
+    Bundle getServiceLists();
+    // Users choose one serviceList from the serviceLists, and install the services.
+    int setServiceList(int serviceListRecId);
+    // Get all of the packageData, parsed from the selected serviceList XML.
+    Bundle getPackageData();
+    // Choose the package using package id and install the corresponding services.
+    int setPackage(String packageId);
+    // Get all of the countryRegionData, parsed from the selected serviceList XML.
+    Bundle getCountryRegionData();
+    // Choose the countryRegion using countryRegion id, and install the corresponding services.
+    int setCountryRegion(String regionId);
+    // Get all of the regionData, parsed from the selected serviceList XML.
+    Bundle getRegionData();
+    // Choose the region using the regionData id, and install the corresponding services.
+    int setRegion(String regionId);
+
+    // Get unique session token for the scan.
+    String getSessionToken();
+    // Release scan resource, the register listener will be released.
+    int release();
+}
diff --git a/media/java/android/media/tv/extension/scan/ITargetRegion.aidl b/media/java/android/media/tv/extension/scan/ITargetRegion.aidl
new file mode 100644
index 0000000..417e122
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ITargetRegion.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.ITargetRegionListener;
+
+import android.os.Bundle;
+
+/**
+ * Country: U.K.
+ * Broadcast Type: BROADCAST_TYPE_DVB_T
+ *
+ * @hide
+ */
+interface ITargetRegion {
+    // Get the target regions information. If there are no conflicts, the array of Bundle is empty.
+    Bundle[] getTargetRegions();
+    // Select and set one of two or more target region detected by the service scan.
+    int setTargetRegion(in Bundle targetRegionSettings);
+    // Set the listener to be invoked when two or more regions are detected.
+    int setListener(in ITargetRegionListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl b/media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl
new file mode 100644
index 0000000..9d6aa8e
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ITargetRegionListener {
+    void onDetectTargetRegion(in Bundle detectTargetRegions);
+}
diff --git a/media/java/android/media/tv/extension/scan/ITkgsInfo.aidl b/media/java/android/media/tv/extension/scan/ITkgsInfo.aidl
new file mode 100644
index 0000000..f25952c
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ITkgsInfo.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.ITkgsInfoListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ITkgsInfo {
+     int setPrefServiceList(String prefServiceList);
+     int setTkgsInfoListener(in ITkgsInfoListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl b/media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl
new file mode 100644
index 0000000..e3dcf2d
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+/**
+ * @hide
+ */
+oneway interface ITkgsInfoListener {
+    void onServiceList(in String[] serviceList);
+    void onTableVersionUpdate(int tableVersion);
+    void onUserMessage(String strMessage);
+}
diff --git a/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl
new file mode 100644
index 0000000..bda60ed
--- /dev/null
+++ b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.media.tv.extension.scanbsu;
+
+import android.media.tv.extension.scanbsu.IScanBackgroundServiceUpdateListener;
+
+/**
+ * @hide
+ */
+interface IScanBackgroundServiceUpdate {
+    // Set the listener for background service update
+    // receives notifications for svl/tsl/nwl update during background service update.
+    void addBackgroundServiceUpdateListener(String clientToken,
+        in IScanBackgroundServiceUpdateListener listener);
+    // Remove the listener for background service update to stop receiving notifications
+    // for svl/tsl/nwl update during background service update.
+    void removeBackgroundServiceUpdateListener(in IScanBackgroundServiceUpdateListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl
new file mode 100644
index 0000000..d9bcbed
--- /dev/null
+++ b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.media.tv.extension.scanbsu;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IScanBackgroundServiceUpdateListener {
+    // On background service update add/delete/update svl records.
+    void onChannelListUpdate(String sessionToken, out Bundle[] updateInfos);
+    // On background service update add/delete/update nwl records.
+    void onNetworkListUpdate(String sessionToken, out Bundle[] updateInfos);
+    // On background service update add/delete/update tsl records.
+    void onTransportStreamingListUpdate(String sessionToken, out Bundle[] updateInfos);
+}
diff --git a/media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl b/media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl
new file mode 100644
index 0000000..57f3b4a
--- /dev/null
+++ b/media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.media.tv.extension.screenmode;
+
+/**
+ * @hide
+ */
+interface IScreenModeSettings {
+    // Set screen mode information using a JSON string.
+    void setScreenModeSettings(String sessionToken, String setting);
+    // Get the overscan index which TIS session is applied.
+    int getOverScanIndex(String sessionToken);
+    // Get status that TIS session is support overscan or not.
+    boolean getSupportApplyOverScan(String sessionToken);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl b/media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl
new file mode 100644
index 0000000..cb6aecc
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IChannelListTransfer {
+    // Parse XML file and import Channels information.
+    void importChannelList(in ParcelFileDescriptor pfd);
+    // Get Channels information for export and create XML file.
+    void exportChannelList(in ParcelFileDescriptor pfd);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceList.aidl b/media/java/android/media/tv/extension/servicedb/IServiceList.aidl
new file mode 100644
index 0000000..51daa80
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceList.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IServiceList {
+    // Get a list of the Service list IDs quivalent to COLUMN_CHANNEL_LIST_ID
+    // in the Channels table of TvProvider.
+    String[] getServiceListIds();
+    // Get the information associated with the Service list.
+    Bundle getServiceListInfo(String serviceListId, in String[] keys);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl
new file mode 100644
index 0000000..1b1577f
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl
@@ -0,0 +1,81 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.media.tv.extension.servicedb.IServiceListEditListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IServiceListEdit {
+    // Open in edit mode. Must call close() after edit is done.
+    int open(IServiceListEditListener listener);
+    // Method to close in edit mode.
+    int close();
+    // Method to commit changes made to service database.
+    int commit();
+    // Method to commit and close the changes.
+    int userEditCommit();
+
+    // Get a service/transportStream/Network/Satellite record information specified by
+    // serviceInfoId and keys from tvdb.
+    Bundle getServiceInfoFromDatabase(String serviceInfoId, in String[] keys);
+    // Get a list of all service records' information specified by serviceListId and keys from tvdb.
+    Bundle getServiceInfoListFromDatabase(String serviceListId, in String[] keys);
+    // Get a list of all service info IDs in the service list of serviceListId from tvdb.
+    String[] getServiceInfoIdsFromDatabase(String inServiceListId);
+    // Update a service information by the contents of serviceInfo;
+    int updateServiceInfoFromDatabase(in Bundle updateServiceInfo);
+    // Update all service information by the contents of serviceInfoList.
+    int updateServiceInfoByListFromDatabase(in Bundle[] updateServiceInfoList);
+    // Remove a service information of the serviceInfoId from the service list.
+    int removeServiceInfoFromDatabase(String serviceInfoId);
+    // Remove all service information of the serviceInfoId from the service list.
+    int removeServiceInfoByListFromDatabase(in String[] serviceInfoIdList);
+    // Get a list of the Service list IDs which is equivalent to COLUMN_CHANNEL_LIST_ID
+    // in Channels table from tv db.
+    String[] getServiceListChannelIds();
+    // Get the information associated with the Service list Channel id.
+    Bundle getServiceListInfoByChannelId(String serviceListChannelId, in String[] keys);
+
+    // Get a list of transportStream records' information specified by serviceListId and keys.
+    Bundle getTransportStreamInfoList(String serviceListId, in String[] keys);
+    // Get a list of transportStream records' information specified by serviceListId and keys
+    // from work db.
+    Bundle getTransportStreamInfoListForce(String serviceListId, in String[] keys);
+
+    // Get a list of network records' information specified by serviceListId and keys.
+    Bundle getNetworkInfoList(String serviceListId, in String[] keys);
+    // Get a list of satellite records' information specified by serviceListId and keys.
+    Bundle getSatelliteInfoList(String serviceListId, in String[] keys);
+
+    // Decompress whole bundle value of single service/transportStream/Network/Satellite record.
+    // RecordInfoBundle:a single record got from database by getServiceInfoFromDatabase()
+    String toRecordInfoByType(in Bundle recordInfoBundle, String recordType);
+    // Set channels(tv.db) modified result to middleware database(SVL/TSL/NWL/SATL).
+    int putRecordIdList(String serviceListId, in Bundle recordIdListBundle, int optType);
+
+    // Add predefined ServiceListInfo of Hotbird 13E in scan two satellite scene EU region
+    // following by commit().
+    String addPredefinedServiceListInfo(int broadcastType, String serviceListType,
+        String serviceListPrefix, String countryCode, int operatorId);
+    // Add predefined channels of Hotbird 13E in scan two satellite scene EU region.
+    int addPredefinedChannelList(String serviceListId, in Bundle[] predefinedListBundle);
+    // Add predefined satellite info of Hotbird 13E in scan two satellite scene EU region.
+    int addPredefinedSatInfo(String serviceListId, in Bundle predefinedSatInfoBundle);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl
new file mode 100644
index 0000000..e227eda
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+/**
+ * @hide
+ */
+oneway interface IServiceListEditListener {
+    void onCompleted(int requestId, int result);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl
new file mode 100644
index 0000000..c57e8f9
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+/**
+ * @hide
+ */
+oneway interface IServiceListExportListener {
+    void onExported(int exportResult);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl
new file mode 100644
index 0000000..fcde581
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IServiceListExportSession {
+    // Start export service list with reserved parameters.
+    int exportServiceList(in ParcelFileDescriptor pfd, in Bundle exportParams);
+    // Release export resources.
+    int release();
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl
new file mode 100644
index 0000000..abd8320
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+/**
+ * @hide
+ */
+interface IServiceListImportListener {
+    void onImported(int importResult);
+    void onPreloaded(int preloadResult);
+}
\ No newline at end of file
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl
new file mode 100644
index 0000000..1f1ae01
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IServiceListImportSession {
+    // Start import service list. Should call after preload and before release.
+    int importServiceList(in ParcelFileDescriptor pfd, in Bundle importParams);
+    // Preparing for import.
+    int preload(in ParcelFileDescriptor pfd);
+    // Release import resources.
+    int release();
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl
new file mode 100644
index 0000000..7c9c5c8
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+/**
+ * @hide
+ */
+oneway interface IServiceListSetChannelListListener {
+    void onCompleted(int setChannelListResult);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl
new file mode 100644
index 0000000..b0527b3
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IServiceListSetChannelListSession {
+    // Set channelList with channelinfo bundles, serviceListInfo, and operation type.
+    int setChannelList(in Bundle[] channelsInfo, in Bundle ServiceListInfoBundle, int optType);
+    // Release set channellist resources.
+    int release();
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl
new file mode 100644
index 0000000..91fb157
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.media.tv.extension.servicedb.IServiceListExportListener;
+import android.media.tv.extension.servicedb.IServiceListImportListener;
+import android.media.tv.extension.servicedb.IServiceListSetChannelListListener;
+import android.os.IBinder;
+
+/**
+ * @hide
+ */
+interface IServiceListTransferInterface {
+    IBinder createExportSession(in IServiceListExportListener listener);
+    IBinder createImportSession(in IServiceListImportListener listener);
+    IBinder createSetChannelListSession(in IServiceListSetChannelListListener listener);
+}
diff --git a/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl
new file mode 100644
index 0000000..a3725e4
--- /dev/null
+++ b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.teletext;
+
+import android.media.tv.extension.teletext.IDataServiceSignalInfoListener;
+import android.os.Bundle;
+
+
+/**
+ * @hide
+ */
+interface IDataServiceSignalInfo {
+     // Get Teletext data service signal information.
+     Bundle getDataServiceSignalInfo(String sessionToken);
+     // Add a listener that receives notifications of teletext running information.
+     void addDataServiceSignalInfoListener(String clientToken,
+        IDataServiceSignalInfoListener listener);
+     // Remove a listener that receives notifications of Teletext running information.
+     void removeDataServiceSignalInfoListener(String clientToken,
+        IDataServiceSignalInfoListener listener);
+}
diff --git a/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl
new file mode 100644
index 0000000..0e99bf5
--- /dev/null
+++ b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.teletext;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IDataServiceSignalInfoListener {
+    void onDataServiceSignalInfoChanged (String sessionToken, in Bundle changedSignalInfo);
+}
diff --git a/media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl b/media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl
new file mode 100644
index 0000000..c96ffc0
--- /dev/null
+++ b/media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.media.tv.extension.teletext;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ITeletextPageSubCode {
+    // Get Teletext page number
+    Bundle getTeletextPageNumber(String sessionToken);
+    // Set Teletext page number.
+    void setTeleltextPageNumber(String sessionToken, int pageNumber);
+    // Get Teletext sub page number.
+    Bundle getTeletextPageSubCode(String sessionToken);
+    // Set Teletext sub page number.
+    void setTeletextPageSubCode(String sessionToken, int pageSubCode);
+    // Get Teletext TopInfo.
+    Bundle getTeletextHasTopInfo(String sessionToken);
+    // Get Teletext TopBlockList.
+    Bundle getTeletextTopBlockList(String sessionToken);
+    // Get Teletext TopGroupList.
+    Bundle getTeletextTopGroupList(String sessionToken, int indexGroup);
+    // Get Teletext TopPageList.
+    Bundle getTeletextTopPageList(String sessionToken, int indexPage);
+}
diff --git a/media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl b/media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl
new file mode 100644
index 0000000..88e5084
--- /dev/null
+++ b/media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.media.tv.extension.tune;
+
+import android.media.tv.extension.tune.IChannelTunedListener;
+
+/*
+* @hide
+*/
+interface IChannelTunedInterface {
+    void addChannelTunedListener(in IChannelTunedListener listener);
+    void removeChannelTunedListener(in IChannelTunedListener listener);
+}
diff --git a/media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl b/media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl
new file mode 100644
index 0000000..4687546
--- /dev/null
+++ b/media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.tune;
+
+import android.os.Bundle;
+
+/*
+* @hide
+*/
+oneway interface IChannelTunedListener {
+    void onChannelTuned(String sessionToken, in Bundle channelTunedInfo);
+}
diff --git a/media/java/android/media/tv/extension/tune/IMuxTune.aidl b/media/java/android/media/tv/extension/tune/IMuxTune.aidl
new file mode 100644
index 0000000..4e9dbda
--- /dev/null
+++ b/media/java/android/media/tv/extension/tune/IMuxTune.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.tune;
+
+import android.media.tv.extension.tune.IMuxTuneSession;
+
+/**
+* @hide
+*/
+interface IMuxTune {
+    IMuxTuneSession createSession(int broadcastType, String clientToken);
+}
diff --git a/media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl b/media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl
new file mode 100644
index 0000000..5ad72b4
--- /dev/null
+++ b/media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.media.tv.extension.tune;
+
+import android.os.Bundle;
+
+/**
+* @hide
+*/
+interface IMuxTuneSession {
+    // Start mux tune with tune params.
+    void start(int broadcastType, int frequency, int brandwith, in Bundle muxTuneParams);
+    // Stop mux tune.
+    void stop();
+    // Release muxtune resources.
+    void release();
+    // Get the session token created by TIS to identify different sessions.
+    String getSessionToken();
+}
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 9ada14b..1019a10 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -60,14 +60,15 @@
     method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.List<java.lang.String> getActiveNfceeList();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.nfc.RoutingStatus getRoutingStatus();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.List<android.nfc.NfcRoutingTableEntry> getRoutingTable();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.T4tNdefNfcee getT4tNdefNfcee();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean hasUserEnabledNfc();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAutoChangeEnabled();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagPresent();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overwriteRoutingTable(int, int, int, int);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void pausePolling(int);
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int pausePolling(int);
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void resumePolling();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int resumePolling();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAutoChangeEnabled(boolean);
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void setControllerAlwaysOnMode(int);
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState();
@@ -83,6 +84,8 @@
     field public static final int HCE_ACTIVATE = 1; // 0x1
     field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
     field public static final int HCE_DEACTIVATE = 3; // 0x3
+    field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
+    field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
     field public static final int STATUS_OK = 0; // 0x0
     field public static final int STATUS_UNKNOWN_ERROR = 1; // 0x1
   }
@@ -120,6 +123,11 @@
 
   @FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry {
     method public int getNfceeId();
+    method public int getType();
+    field public static final int TYPE_AID = 0; // 0x0
+    field public static final int TYPE_PROTOCOL = 1; // 0x1
+    field public static final int TYPE_SYSTEM_CODE = 3; // 0x3
+    field public static final int TYPE_TECHNOLOGY = 2; // 0x2
   }
 
   @FlaggedApi("android.nfc.nfc_oem_extension") public final class OemLogItems implements android.os.Parcelable {
@@ -179,6 +187,47 @@
     field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_V = 3; // 0x3
   }
 
+  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfcee {
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int clearData();
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isOperationOngoing();
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isSupported();
+    method @Nullable @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public android.nfc.T4tNdefNfceeCcFileInfo readCcfile();
+    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public byte[] readData(@IntRange(from=0, to=65535) int);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int writeData(@IntRange(from=0, to=65535) int, @NonNull byte[]);
+    field public static final int CLEAR_DATA_FAILED_INTERNAL = 0; // 0x0
+    field public static final int CLEAR_DATA_SUCCESS = 1; // 0x1
+    field public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6; // 0xfffffffa
+    field public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7; // 0xfffffff9
+    field public static final int WRITE_DATA_ERROR_INTERNAL = -1; // 0xffffffff
+    field public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4; // 0xfffffffc
+    field public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5; // 0xfffffffb
+    field public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8; // 0xfffffff8
+    field public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3; // 0xfffffffd
+    field public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2; // 0xfffffffe
+    field public static final int WRITE_DATA_SUCCESS = 0; // 0x0
+  }
+
+  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfceeCcFileInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=15, to=32767) public int getCcFileLength();
+    method @IntRange(from=0xffffffff, to=65535) public int getFileId();
+    method @IntRange(from=15, to=65535) public int getMaxReadLength();
+    method @IntRange(from=5, to=32767) public int getMaxSize();
+    method @IntRange(from=13, to=65535) public int getMaxWriteLength();
+    method public int getReadAccess();
+    method public int getVersion();
+    method public int getWriteAccess();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.T4tNdefNfceeCcFileInfo> CREATOR;
+    field public static final int READ_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
+    field public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
+    field public static final int VERSION_2_0 = 32; // 0x20
+    field public static final int VERSION_3_0 = 48; // 0x30
+    field public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
+    field public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
+    field public static final int WRITE_ACCESS_NOT_GRANTED = 255; // 0xff
+  }
+
 }
 
 package android.nfc.cardemulation {
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index a08b55f..13e6734 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -31,6 +31,7 @@
 import android.nfc.INfcFCardEmulation;
 import android.nfc.INfcOemExtensionCallback;
 import android.nfc.INfcUnlockHandler;
+import android.nfc.IT4tNdefNfcee;
 import android.nfc.ITagRemovedCallback;
 import android.nfc.INfcDta;
 import android.nfc.INfcWlcStateListener;
@@ -52,8 +53,8 @@
     int getState();
     boolean disable(boolean saveState, in String pkg);
     boolean enable(in String pkg);
-    void pausePolling(int timeoutInMs);
-    void resumePolling();
+    int pausePolling(int timeoutInMs);
+    int resumePolling();
 
     void setForegroundDispatch(in PendingIntent intent,
             in IntentFilter[] filters, in TechListParcel techLists);
@@ -122,4 +123,5 @@
     void indicateDataMigration(boolean inProgress, String pkg);
     int commitRouting();
     boolean isTagIntentAllowed(in String pkg, in int Userid);
+    IT4tNdefNfcee getT4tNdefNfceeInterface();
 }
diff --git a/nfc/java/android/nfc/IT4tNdefNfcee.aidl b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
new file mode 100644
index 0000000..b4cda5b
--- /dev/null
+++ b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ *  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.nfc;
+
+import android.nfc.T4tNdefNfceeCcFileInfo;
+
+/**
+ * @hide
+ */
+interface IT4tNdefNfcee {
+    int writeData(in int fileId, in byte[] data);
+    byte[] readData(in int fileId);
+    int clearNdefData();
+    boolean isNdefOperationOngoing();
+    boolean isNdefNfceeEmulationSupported();
+    T4tNdefNfceeCcFileInfo readCcfile();
+}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 056844f..89ce423 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -589,6 +589,7 @@
     static INfcTag sTagService;
     static INfcCardEmulation sCardEmulationService;
     static INfcFCardEmulation sNfcFCardEmulationService;
+    static IT4tNdefNfcee sNdefNfceeService;
 
     /**
      * The NfcAdapter object for each application context.
@@ -827,7 +828,13 @@
                     throw new UnsupportedOperationException();
                 }
             }
-
+            try {
+                sNdefNfceeService = sService.getT4tNdefNfceeInterface();
+            } catch (RemoteException e) {
+                sNdefNfceeService = null;
+                Log.e(TAG, "could not retrieve NDEF NFCEE service");
+                throw new UnsupportedOperationException();
+            }
             sIsInitialized = true;
         }
         NfcAdapter adapter = sNfcAdapters.get(context);
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 9ed678f..ac7b8bb 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -173,6 +173,31 @@
     public @interface HostCardEmulationAction {}
 
     /**
+     * Status code returned when the polling state change request succeeded.
+     * @see #pausePolling()
+     * @see #resumePolling()
+     */
+    public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1;
+    /**
+     * Status code returned when the polling state change request is already in
+     * required state.
+     * @see #pausePolling()
+     * @see #resumePolling()
+     */
+    public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2;
+    /**
+     * Possible status codes for {@link #pausePolling()} and
+     * {@link #resumePolling()}.
+     * @hide
+     */
+    @IntDef(value = {
+            POLLING_STATE_CHANGE_SUCCEEDED,
+            POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PollingStateChangeStatusCode {}
+
+    /**
      * Status OK
      */
     public static final int STATUS_OK = 0;
@@ -467,6 +492,28 @@
     }
 
     /**
+     * Get an instance of {@link T4tNdefNfcee} object for performing T4T (Type-4 Tag)
+     * NDEF (NFC Data Exchange Format) NFCEE (NFC Execution Environment) operations.
+     * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
+     * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
+     * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     *
+     * This is a singleton object which shall be used by OEM extension module to do NDEF-NFCEE
+     * read/write operations.
+     *
+     * <p>Returns {@link T4tNdefNfcee}
+     * <p>Does not cause any RF activity and does not block.
+     * @return NFC Data Exchange Format (NDEF) NFC Execution Environment (NFCEE) object
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    public T4tNdefNfcee getT4tNdefNfcee() {
+        return T4tNdefNfcee.getInstance();
+    }
+
+    /**
      * Register an {@link Callback} to listen for NFC oem extension callbacks
      * Multiple clients can register and callbacks will be invoked asynchronously.
      *
@@ -653,24 +700,32 @@
 
     /**
      * Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
-     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely
-     * use {@link #resumePolling()} to resume the polling.
+     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely.
+     * Use {@link #resumePolling() to resume the polling.
      * @param timeoutInMs the pause polling duration in millisecond, ranging from 0 to 40000.
+     * @return status of the operation
+     * @throws IllegalArgumentException if timeoutInMs value is invalid
+     *         (0 < timeoutInMs < max).
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void pausePolling(@DurationMillisLong int timeoutInMs) {
-        NfcAdapter.callService(() -> NfcAdapter.sService.pausePolling(timeoutInMs));
+    public @PollingStateChangeStatusCode int pausePolling(@DurationMillisLong int timeoutInMs) {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sService.pausePolling(timeoutInMs),
+                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
     }
 
     /**
      * Resumes default NFC tag reader mode polling for the current device state if polling is
      * paused. Calling this while already in polling is a no-op.
+     * @return status of the operation
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void resumePolling() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.resumePolling());
+    public @PollingStateChangeStatusCode int resumePolling() {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sService.resumePolling(),
+                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
     }
 
     /**
diff --git a/nfc/java/android/nfc/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java
index 4e91377..c2cbbed 100644
--- a/nfc/java/android/nfc/NfcRoutingTableEntry.java
+++ b/nfc/java/android/nfc/NfcRoutingTableEntry.java
@@ -17,8 +17,12 @@
 
 
 import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Class to represent an entry of routing table. This class is abstract and extended by
  * {@link RoutingTableTechnologyEntry}, {@link RoutingTableProtocolEntry},
@@ -30,10 +34,42 @@
 @SystemApi
 public abstract class NfcRoutingTableEntry {
     private final int mNfceeId;
+    private final int mType;
+
+    /**
+     * AID routing table type.
+     */
+    public static final int TYPE_AID = 0;
+    /**
+     * Protocol routing table type.
+     */
+    public static final int TYPE_PROTOCOL = 1;
+    /**
+     * Technology routing table type.
+     */
+    public static final int TYPE_TECHNOLOGY = 2;
+    /**
+     * System Code routing table type.
+     */
+    public static final int TYPE_SYSTEM_CODE = 3;
+
+    /**
+     * Possible type of this routing table entry.
+     * @hide
+     */
+    @IntDef(prefix = "TYPE_", value = {
+            TYPE_AID,
+            TYPE_PROTOCOL,
+            TYPE_TECHNOLOGY,
+            TYPE_SYSTEM_CODE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RoutingTableType {}
 
     /** @hide */
-    protected NfcRoutingTableEntry(int nfceeId) {
+    protected NfcRoutingTableEntry(int nfceeId, @RoutingTableType int type) {
         mNfceeId = nfceeId;
+        mType = type;
     }
 
     /**
@@ -43,4 +79,13 @@
     public int getNfceeId() {
         return mNfceeId;
     }
+
+    /**
+     * Get the type of this entry.
+     * @return an integer defined in {@link RoutingTableType}
+     */
+    @RoutingTableType
+    public int getType() {
+        return mType;
+    }
 }
diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java
index 7634fe3..bf697d6 100644
--- a/nfc/java/android/nfc/RoutingTableAidEntry.java
+++ b/nfc/java/android/nfc/RoutingTableAidEntry.java
@@ -20,7 +20,7 @@
 import android.annotation.SystemApi;
 
 /**
- * Represents an AID entry in current routing table.
+ * Represents an Application ID (AID) entry in current routing table.
  * @hide
  */
 @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@@ -30,7 +30,7 @@
 
     /** @hide */
     public RoutingTableAidEntry(int nfceeId, String value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_AID);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
index 0c5be7d..536de4d 100644
--- a/nfc/java/android/nfc/RoutingTableProtocolEntry.java
+++ b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
@@ -97,7 +97,7 @@
 
     /** @hide */
     public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_PROTOCOL);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
index f87ad5f..f61892d 100644
--- a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
+++ b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
@@ -20,7 +20,9 @@
 import android.annotation.SystemApi;
 
 /**
- * Represents a system code entry in current routing table.
+ * Represents a system code entry in current routing table, where system codes are two-byte values
+ * used in NFC-F technology (a type of NFC communication) to identify specific
+ * device configurations.
  * @hide
  */
 @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@@ -30,7 +32,7 @@
 
     /** @hide */
     public RoutingTableSystemCodeEntry(int nfceeId, byte[] value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_SYSTEM_CODE);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
index f51a529..2dbc942 100644
--- a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
+++ b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
@@ -30,22 +30,27 @@
 @SystemApi
 public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry {
     /**
-     * Technology-A
+     * Technology-A.
+     * <p>Tech-A is mostly used for payment and ticketing applications. It supports various
+     * Tag platforms including Type 1, Type 2 and Type 4A tags. </p>
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_A = 0;
     /**
-     * Technology-B
+     * Technology-B which is based on ISO/IEC 14443-3 standard.
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_B = 1;
     /**
-     * Technology-F
+     * Technology-F.
+     * <p>Tech-F is a standard which supports Type 3 Tags and NFC-DEP protocol etc.</p>
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_F = 2;
     /**
-     * Technology-V
+     * Technology-V.
+     * <p>Tech-V is an NFC technology used for communication with passive tags that operate
+     * at a longer range than other NFC technologies. </p>
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_V = 3;
@@ -73,7 +78,7 @@
 
     /** @hide */
     public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_TECHNOLOGY);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/T4tNdefNfcee.java b/nfc/java/android/nfc/T4tNdefNfcee.java
new file mode 100644
index 0000000..06d02c5
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfcee.java
@@ -0,0 +1,258 @@
+/*
+ * 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.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.WorkerThread;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used for performing T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
+ * NFCEE (NFC Execution Environment) operations.
+ * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
+ * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
+ * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class T4tNdefNfcee {
+    private static final String TAG = "NdefNfcee";
+    static T4tNdefNfcee sNdefNfcee;
+
+    private T4tNdefNfcee() {
+    }
+
+    /**
+     * Helper to get an instance of this class.
+     *
+     * @return
+     * @hide
+     */
+    @NonNull
+    public static T4tNdefNfcee getInstance() {
+        if (sNdefNfcee == null) {
+            sNdefNfcee = new T4tNdefNfcee();
+        }
+        return sNdefNfcee;
+    }
+
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data is successful.
+     */
+    public static final int WRITE_DATA_SUCCESS = 0;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to unknown reasons.
+     */
+    public static final int WRITE_DATA_ERROR_INTERNAL = -1;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to ongoing rf activity.
+     */
+    public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to Nfc off.
+     */
+    public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to invalid file id.
+     */
+    public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to invalid length.
+     */
+    public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to core connection create failure.
+     */
+    public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to empty payload.
+     */
+    public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7;
+    /**
+     * Returns flag for {@link #writeData(int, byte[])}.
+     * It idicates write data fail due to invalid ndef format.
+     */
+    public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8;
+
+    /**
+     * Possible return values for {@link #writeData(int, byte[])}.
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "WRITE_DATA_" }, value = {
+        WRITE_DATA_SUCCESS,
+        WRITE_DATA_ERROR_INTERNAL,
+        WRITE_DATA_ERROR_RF_ACTIVATED,
+        WRITE_DATA_ERROR_NFC_NOT_ON,
+        WRITE_DATA_ERROR_INVALID_FILE_ID,
+        WRITE_DATA_ERROR_INVALID_LENGTH,
+        WRITE_DATA_ERROR_CONNECTION_FAILED,
+        WRITE_DATA_ERROR_EMPTY_PAYLOAD,
+        WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteDataStatus{}
+
+    /**
+     * This API performs writes of T4T data to NFCEE.
+     *
+     * <p>This is an I/O operation and will block until complete. It must
+     * not be called from the main application thread.</p>
+     *
+     * @param fileId File id (Refer NFC Forum Type 4 Tag Specification
+     *               Section 4.2 File Identifiers and Access Conditions
+     *               for more information) to which to write.
+     * @param data   This should be valid Ndef Message format.
+     *               Refer to Nfc forum NDEF specification NDEF Message section
+     * @return status of the operation.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public @WriteDataStatus int writeData(@IntRange(from = 0, to = 65535) int fileId,
+            @NonNull byte[] data) {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sNdefNfceeService.writeData(fileId, data), WRITE_DATA_ERROR_INTERNAL);
+    }
+
+    /**
+     * This API performs reading of T4T content of Nfcee.
+     *
+     * <p>This is an I/O operation and will block until complete. It must
+     * not be called from the main application thread.</p>
+     *
+     * @param fileId File Id (Refer
+     *               Section 4.2 File Identifiers and Access Conditions
+     *               for more information) from which to read.
+     * @return - Returns Ndef message if success
+     *           Refer to Nfc forum NDEF specification NDEF Message section
+     * @throws IllegalStateException if read fails because the fileId is invalid.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public byte[] readData(@IntRange(from = 0, to = 65535) int fileId) {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.readData(fileId), null);
+    }
+
+    /**
+     * Return flag for {@link #clearNdefData()}.
+     * It indicates clear data is successful.
+     */
+    public static final int CLEAR_DATA_SUCCESS = 1;
+     /**
+     * Return flag for {@link #clearNdefData()}.
+     * It indicates clear data failed due to internal error while processing the clear.
+     */
+    public static final int CLEAR_DATA_FAILED_INTERNAL = 0;
+
+    /**
+     * Possible return values for {@link #clearNdefData()}.
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "CLEAR_DATA_" }, value = {
+        CLEAR_DATA_SUCCESS,
+        CLEAR_DATA_FAILED_INTERNAL,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ClearDataStatus{}
+
+    /**
+     * This API will set all the T4T NDEF NFCEE data to zero.
+     *
+     * <p>This is an I/O operation and will block until complete. It must
+     * not be called from the main application thread.
+     *
+     * <p>This API can be called regardless of NDEF file lock state.
+     * </p>
+     * @return status of the operation
+     *
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public @ClearDataStatus int clearData() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.clearNdefData(), CLEAR_DATA_FAILED_INTERNAL);
+    }
+
+    /**
+     * Returns whether NDEF NFCEE operation is ongoing or not.
+     *
+     * @return true if NDEF NFCEE operation is ongoing, else false.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public boolean isOperationOngoing() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.isNdefOperationOngoing(), false);
+    }
+
+    /**
+     * This Api is to check the status of NDEF NFCEE emulation feature is
+     * supported or not.
+     *
+     * @return true if NDEF NFCEE emulation feature is supported, else false.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public boolean isSupported() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.isNdefNfceeEmulationSupported(), false);
+    }
+
+    /**
+     * This API performs reading of T4T NDEF NFCEE CC file content.
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+     *
+     * @return Returns CC file content if success or null if failed to read.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @Nullable
+    public T4tNdefNfceeCcFileInfo readCcfile() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.readCcfile(), null);
+    }
+}
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
new file mode 100644
index 0000000..f72f74e
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.nfc;
+
+parcelable T4tNdefNfceeCcFileInfo;
+
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
new file mode 100644
index 0000000..5fca052
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
@@ -0,0 +1,293 @@
+/*
+ * 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.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used to represence T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
+ * NFCEE (NFC Execution Environment) CC (Capability Container) File data.
+ * The CC file stores metadata about the T4T tag being emulated.
+ *
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class T4tNdefNfceeCcFileInfo implements Parcelable {
+    /**
+     * Indicates the size of this capability container (called “CC File”)<p>
+     */
+    private int mCcLength;
+    /**
+     * Indicates the mapping specification version<p>
+     */
+    private int mVersion;
+    /**
+     * Indicates the max data size by a single ReadBinary<p>
+     */
+    private int mMaxReadLength;
+    /**
+     * Indicates the max data size by a single UpdateBinary<p>
+     */
+    private int mMaxWriteLength;
+    /**
+     * Indicates the NDEF File Identifier<p>
+     */
+    private int mFileId;
+    /**
+     * Indicates the maximum Max NDEF file size<p>
+     */
+    private int mMaxSize;
+    /**
+     * Indicates the read access condition<p>
+     */
+    private int mReadAccess;
+    /**
+     * Indicates the write access condition<p>
+     */
+    private int mWriteAccess;
+
+    /**
+     * Constructor to be used by NFC service and internal classes.
+     * @hide
+     */
+    public T4tNdefNfceeCcFileInfo(int cclen, int version, int maxLe, int maxLc,
+                      int ndefFileId, int ndefMaxSize,
+                      int ndefReadAccess, int ndefWriteAccess) {
+        mCcLength = cclen;
+        mVersion = version;
+        mMaxWriteLength = maxLc;
+        mMaxReadLength = maxLe;
+        mFileId = ndefFileId;
+        mMaxSize = ndefMaxSize;
+        mReadAccess = ndefReadAccess;
+        mWriteAccess = ndefWriteAccess;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+
+        dest.writeInt(mCcLength);
+        dest.writeInt(mVersion);
+        dest.writeInt(mMaxWriteLength);
+        dest.writeInt(mMaxReadLength);
+        dest.writeInt(mFileId);
+        dest.writeInt(mMaxSize);
+        dest.writeInt(mReadAccess);
+        dest.writeInt(mWriteAccess);
+    }
+
+    /**
+     * Indicates the size of this capability container (called “CC File”).
+     *
+     * @return length of the CC file.
+     */
+    @IntRange(from = 0xf, to = 0x7fff)
+    public int getCcFileLength() {
+        return mCcLength;
+    }
+
+    /**
+     * T4T tag mapping version 2.0.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+     */
+    public static final int VERSION_2_0 = 0x20;
+    /**
+     * T4T tag mapping version 2.0.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+     */
+    public static final int VERSION_3_0 = 0x30;
+
+    /**
+     * Possible return values for {@link #getVersion()}.
+     * @hide
+     */
+    @IntDef(prefix = { "VERSION_" }, value = {
+            VERSION_2_0,
+            VERSION_3_0,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Version{}
+
+    /**
+     * Indicates the mapping version of the T4T tag supported.
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.5" for more details.
+     *
+     * @return version of the specification
+     */
+    @Version
+    public int getVersion() {
+        return mVersion;
+    }
+
+    /**
+     * Indicates the max data size that can be read by a single invocation of
+     * {@link T4tNdefNfcee#readData(int)}.
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLe.
+     * @return max size of read (in bytes).
+     */
+    @IntRange(from = 0xf, to = 0xffff)
+    public int getMaxReadLength() {
+        return mMaxReadLength;
+    }
+
+    /**
+     * Indicates the max data size that can be written by a single invocation of
+     * {@link T4tNdefNfcee#writeData(int, byte[])}
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLc.
+     * @return max size of write (in bytes).
+     */
+    @IntRange(from = 0xd, to = 0xffff)
+    public int getMaxWriteLength() {
+        return mMaxWriteLength;
+    }
+
+    /**
+     * Indicates the NDEF File Identifier. This is the identifier used in the last invocation of
+     * {@link T4tNdefNfcee#writeData(int, byte[])}
+     *
+     * @return FileId of the data stored or -1 if no data is present.
+     */
+    @IntRange(from = -1, to = 65535)
+    public int getFileId() {
+        return mFileId;
+    }
+
+    /**
+     * Indicates the maximum size of T4T NDEF data that can be written to the NFCEE.
+     *
+     * @return max size of the contents.
+     */
+    @IntRange(from = 0x5, to = 0x7fff)
+    public int getMaxSize() {
+        return mMaxSize;
+    }
+
+    /**
+     * T4T tag read access granted without any security.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0x0;
+    /**
+     * T4T tag read access granted with limited proprietary access only.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int READ_ACCESS_GRANTED_RESTRICTED = 0x80;
+
+    /**
+     * Possible return values for {@link #getVersion()}.
+     * @hide
+     */
+    @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
+            READ_ACCESS_GRANTED_RESTRICTED,
+            READ_ACCESS_GRANTED_UNRESTRICTED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ReadAccess {}
+
+    /**
+     * Indicates the read access condition.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     * @return read access restriction
+     */
+    @ReadAccess
+    public int getReadAccess() {
+        return mReadAccess;
+    }
+
+    /**
+     * T4T tag write access granted without any security.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0x0;
+    /**
+     * T4T tag write access granted with limited proprietary access only.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 0x80;
+    /**
+     * T4T tag write access not granted.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int WRITE_ACCESS_NOT_GRANTED = 0xFF;
+
+    /**
+     * Possible return values for {@link #getVersion()}.
+     * @hide
+     */
+    @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
+            WRITE_ACCESS_GRANTED_RESTRICTED,
+            WRITE_ACCESS_GRANTED_UNRESTRICTED,
+            WRITE_ACCESS_NOT_GRANTED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteAccess {}
+
+    /**
+     * Indicates the write access condition.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     * @return write access restriction
+     */
+    @WriteAccess
+    public int getWriteAccess() {
+        return mWriteAccess;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Parcelable.Creator<T4tNdefNfceeCcFileInfo> CREATOR =
+            new Parcelable.Creator<>() {
+                @Override
+                public T4tNdefNfceeCcFileInfo createFromParcel(Parcel in) {
+
+                    // NdefNfceeCcFileInfo fields
+                    int cclen = in.readInt();
+                    int version = in.readInt();
+                    int maxLe = in.readInt();
+                    int maxLc = in.readInt();
+                    int ndefFileId = in.readInt();
+                    int ndefMaxSize = in.readInt();
+                    int ndefReadAccess = in.readInt();
+                    int ndefWriteAccess = in.readInt();
+
+                    return new T4tNdefNfceeCcFileInfo(cclen, version, maxLe, maxLc,
+                            ndefFileId, ndefMaxSize,
+                            ndefReadAccess, ndefWriteAccess);
+                }
+
+                @Override
+                public T4tNdefNfceeCcFileInfo[] newArray(int size) {
+                    return new T4tNdefNfceeCcFileInfo[size];
+                }
+            };
+}
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
index fc48217..2ba93f1 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
@@ -456,7 +456,7 @@
      *
      * <p>This method could be called frequently if there is a severe problem on the device.
      */
-    public void onPackageFailure(@NonNull List<VersionedPackage> packages,
+    public void notifyPackageFailure(@NonNull List<VersionedPackage> packages,
             @FailureReasons int failureReason) {
         if (packages == null) {
             Slog.w(TAG, "Could not resolve a list of failing packages");
@@ -467,7 +467,7 @@
             if (Flags.recoverabilityDetection()) {
                 if (now >= mLastMitigation
                         && (now - mLastMitigation) < getMitigationWindowMs()) {
-                    Slog.i(TAG, "Skipping onPackageFailure mitigation");
+                    Slog.i(TAG, "Skipping notifyPackageFailure mitigation");
                     return;
                 }
             }
@@ -494,7 +494,7 @@
                             ObserverInternal observer = mAllObservers.valueAt(oIndex);
                             PackageHealthObserver registeredObserver = observer.registeredObserver;
                             if (registeredObserver != null
-                                    && observer.onPackageFailureLocked(
+                                    && observer.notifyPackageFailureLocked(
                                     versionedPackage.getPackageName())) {
                                 MonitoredPackage p = observer.getMonitoredPackage(
                                         versionedPackage.getPackageName());
@@ -693,7 +693,7 @@
         // Check if native watchdog reported a crash
         if ("1".equals(SystemProperties.get("sys.init.updatable_crashing"))) {
             // We rollback all available low impact rollbacks when crash is unattributable
-            onPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
+            notifyPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
             // we stop polling after an attempt to execute rollback, regardless of whether the
             // attempt succeeds or not
         } else {
@@ -731,6 +731,25 @@
     }
 
     /**
+     * The minimum value that can be returned by any observer.
+     * It represents that no mitigations were available.
+     */
+    public static final int LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT =
+            PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
+
+    /**
+     * The mitigation impact beyond which the user will start noticing the mitigations.
+     */
+    public static final int MEDIUM_USER_IMPACT_THRESHOLD =
+            PackageHealthObserverImpact.USER_IMPACT_LEVEL_20;
+
+    /**
+     * The mitigation impact beyond which the user impact is severely high.
+     */
+    public static final int HIGH_USER_IMPACT_THRESHOLD =
+            PackageHealthObserverImpact.USER_IMPACT_LEVEL_71;
+
+    /**
      * Possible severity values of the user impact of a
      * {@link PackageHealthObserver#onExecuteHealthCheckMitigation}.
      * @hide
@@ -773,6 +792,11 @@
         /**
          * Called when health check fails for the {@code versionedPackage}.
          *
+         * Note: if the returned user impact is higher than
+         * {@link #DEFAULT_HIGH_USER_IMPACT_THRESHOLD}, then
+         * {@link #onExecuteHealthCheckMitigation} would be called only in severe device conditions
+         * like boot-loop or network failure.
+         *
          * @param versionedPackage the package that is failing. This may be null if a native
          *                          service is crashing.
          * @param failureReason   the type of failure that is occurring.
@@ -780,8 +804,8 @@
          *                        (including this time).
          *
          *
-         * @return any one of {@link PackageHealthObserverImpact} to express the impact
-         * to the user on {@link #onExecuteHealthCheckMitigation}
+         * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
+         * the impact of mitigation on the user in {@link #onExecuteHealthCheckMitigation}
          */
         @PackageHealthObserverImpact int onHealthCheckFailed(
                 @Nullable VersionedPackage versionedPackage,
@@ -790,9 +814,8 @@
 
         /**
          * This would be called after {@link #onHealthCheckFailed}.
-         * This is called only if current observer returned least
-         * {@link PackageHealthObserverImpact} mitigation for failed health
-         * check.
+         * This is called only if current observer returned least impact mitigation for failed
+         * health check.
          *
          * @param versionedPackage the package that is failing. This may be null if a native
          *                          service is crashing.
@@ -811,6 +834,9 @@
          *
          * @param mitigationCount the number of times mitigation has been attempted for this
          *                        boot loop (including this time).
+         *
+         * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
+         * the impact of mitigation on the user in {@link #onExecuteBootLoopMitigation}
          */
         default @PackageHealthObserverImpact int onBootLoop(int mitigationCount) {
             return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
@@ -818,11 +844,13 @@
 
         /**
          * This would be called after {@link #onBootLoop}.
-         * This is called only if current observer returned least
-         * {@link PackageHealthObserverImpact} mitigation for fixing boot loop
+         * This is called only if current observer returned least impact mitigation for fixing
+         * boot loop.
          *
          * @param mitigationCount the number of times mitigation has been attempted for this
          *                        boot loop (including this time).
+         *
+         * @return {@code true} if action was executed successfully, {@code false} otherwise
          */
         default boolean onExecuteBootLoopMitigation(int mitigationCount) {
             return false;
@@ -916,7 +944,7 @@
      * effectively behave as if the explicit health check hasn't passed for {@code packageName}.
      *
      * <p> {@code packageName} can still be considered failed if reported by
-     * {@link #onPackageFailureLocked} before the package expires.
+     * {@link #notifyPackageFailureLocked} before the package expires.
      *
      * <p> Triggered by components outside the system server when they are fully functional after an
      * update.
@@ -1460,7 +1488,7 @@
          * @hide
          */
         @GuardedBy("sLock")
-        public boolean onPackageFailureLocked(String packageName) {
+        public boolean notifyPackageFailureLocked(String packageName) {
             if (getMonitoredPackage(packageName) == null && registeredObserver.isPersistent()
                     && registeredObserver.mayObservePackage(packageName)) {
                 putMonitoredPackage(sPackageWatchdog.newMonitoredPackage(
diff --git a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
index 129e47f..88fe36c 100644
--- a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
@@ -477,7 +477,7 @@
      *
      * <p>This method could be called frequently if there is a severe problem on the device.
      */
-    public void onPackageFailure(@NonNull List<VersionedPackage> packages,
+    public void notifyPackageFailure(@NonNull List<VersionedPackage> packages,
             @FailureReasons int failureReason) {
         if (packages == null) {
             Slog.w(TAG, "Could not resolve a list of failing packages");
@@ -488,7 +488,7 @@
             if (Flags.recoverabilityDetection()) {
                 if (now >= mLastMitigation
                         && (now - mLastMitigation) < getMitigationWindowMs()) {
-                    Slog.i(TAG, "Skipping onPackageFailure mitigation");
+                    Slog.i(TAG, "Skipping notifyPackageFailure mitigation");
                     return;
                 }
             }
@@ -515,7 +515,7 @@
                             ObserverInternal observer = mAllObservers.valueAt(oIndex);
                             PackageHealthObserver registeredObserver = observer.registeredObserver;
                             if (registeredObserver != null
-                                    && observer.onPackageFailureLocked(
+                                    && observer.notifyPackageFailureLocked(
                                     versionedPackage.getPackageName())) {
                                 MonitoredPackage p = observer.getMonitoredPackage(
                                         versionedPackage.getPackageName());
@@ -714,7 +714,7 @@
         // Check if native watchdog reported a crash
         if ("1".equals(SystemProperties.get("sys.init.updatable_crashing"))) {
             // We rollback all available low impact rollbacks when crash is unattributable
-            onPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
+            notifyPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
             // we stop polling after an attempt to execute rollback, regardless of whether the
             // attempt succeeds or not
         } else {
@@ -926,7 +926,7 @@
      * effectively behave as if the explicit health check hasn't passed for {@code packageName}.
      *
      * <p> {@code packageName} can still be considered failed if reported by
-     * {@link #onPackageFailureLocked} before the package expires.
+     * {@link #notifyPackageFailureLocked} before the package expires.
      *
      * <p> Triggered by components outside the system server when they are fully functional after an
      * update.
@@ -1253,7 +1253,7 @@
                         return;
                     }
                     final List<VersionedPackage> pkgList = Collections.singletonList(pkg);
-                    onPackageFailure(pkgList, FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
+                    notifyPackageFailure(pkgList, FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
                 });
     }
 
@@ -1467,7 +1467,7 @@
          * @hide
          */
         @GuardedBy("mLock")
-        public boolean onPackageFailureLocked(String packageName) {
+        public boolean notifyPackageFailureLocked(String packageName) {
             if (getMonitoredPackage(packageName) == null && registeredObserver.isPersistent()
                     && registeredObserver.mayObservePackage(packageName)) {
                 putMonitoredPackage(sPackageWatchdog.newMonitoredPackage(
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 2321097..b01b7c9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -390,6 +390,16 @@
     }
 
     /**
+     * Get the {@link MediaRoute2Info.Type} of the device.
+     */
+    public int getRouteType() {
+        if (mRouteInfo == null) {
+            return TYPE_UNKNOWN;
+        }
+        return mRouteInfo.getType();
+    }
+
+    /**
      * Checks if route's volume is fixed, if true, we should disable volume control for the device.
      *
      * @return route for this device is fixed.
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 927a1c59..1f291cd 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -107,6 +107,8 @@
         Settings.Secure.DISPLAY_WHITE_BALANCE_ENABLED,
         Settings.Secure.SYNC_PARENT_SOUNDS,
         Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
+        Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED,
+        Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
         Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
         Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
         // ACCESSIBILITY_QS_TARGETS needs to be restored after ENABLED_ACCESSIBILITY_SERVICES
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 6d73ee2..abd5b9a 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -160,6 +160,9 @@
         VALIDATORS.put(Secure.DISPLAY_WHITE_BALANCE_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.SYNC_PARENT_SOUNDS, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
+                new InclusiveIntegerRangeValidator(0, 1));
         VALIDATORS.put(Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.QS_TILES, TILE_LIST_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 600c36e..5ae11ba 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2124,6 +2124,15 @@
                 SecureSettingsProto.Display.SCREEN_RESOLUTION_MODE);
         p.end(displayToken);
 
+        final long doubleTapPowerButtonToken = p.start(SecureSettingsProto.DOUBLE_TAP_POWER_BUTTON);
+        dumpSetting(s, p,
+                Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED,
+                SecureSettingsProto.DoubleTapPowerButton.GESTURE_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
+                SecureSettingsProto.DoubleTapPowerButton.GESTURE);
+        p.end(doubleTapPowerButtonToken);
+
         final long dozeToken = p.start(SecureSettingsProto.DOZE);
         dumpSetting(s, p,
                 Settings.Secure.DOZE_ENABLED,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java b/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
index d835c5f..b0409c0 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
@@ -33,6 +33,15 @@
 final class WritableNamespaces {
     public static final Set<String> ALLOWLIST =
             new ArraySet<String>(Arrays.asList(
-                    "exo"
+                    "captive_portal_login",
+                    "connectivity",
+                    "exo",
+                    "nearby",
+                    "netd_native",
+                    "network_security",
+                    "on_device_personalization",
+                    "tethering",
+                    "tethering_u_or_later_native",
+                    "thread_network"
             ));
 }
diff --git a/packages/Shell/Android.bp b/packages/Shell/Android.bp
index 3350efc..5f81085 100644
--- a/packages/Shell/Android.bp
+++ b/packages/Shell/Android.bp
@@ -27,6 +27,7 @@
     ],
     flags_packages: [
         "android.security.flags-aconfig",
+        "android.permission.flags-aconfig",
     ],
     platform_apis: true,
     certificate: "platform",
@@ -51,5 +52,6 @@
     manifest: "AndroidManifest.xml",
     flags_packages: [
         "android.security.flags-aconfig",
+        "android.permission.flags-aconfig",
     ],
 }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index ac02af81..27e6bab 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -981,6 +981,14 @@
     <uses-permission android:name="android.permission.READ_SYSTEM_PREFERENCES" />
     <uses-permission android:name="android.permission.WRITE_SYSTEM_PREFERENCES" />
 
+    <!-- Permissions required for CTS test - ActivityManagerForegroundServiceTypeTest -->
+    <uses-permission android:name="android.permission.health.READ_HEART_RATE"
+        android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+    <uses-permission android:name="android.permission.health.READ_OXYGEN_SATURATION"
+        android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+    <uses-permission android:name="android.permission.health.READ_SKIN_TEMPERATURE"
+        android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+
     <application
         android:label="@string/app_label"
         android:theme="@android:style/Theme.DeviceDefault.DayNight"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
index 1f29255..544d201 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification.collection.coordinator;
 
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.Notification.FLAG_PROMOTED_ONGOING;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
@@ -24,12 +25,18 @@
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.Person;
 import android.content.Intent;
 import android.graphics.Color;
 import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -38,11 +45,14 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -136,6 +146,60 @@
         assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
     }
 
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void testIncludePromotedOngoingInSection_flagEnabled() {
+        // GIVEN the notification has FLAG_PROMOTED_ONGOING
+        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
+
+        // THEN the entry is in the fgs section
+        assertTrue(mFgsSection.isInSection(mEntryBuilder.build()));
+    }
+
+    @Test
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void testDiscludePromotedOngoingInSection_flagDisabled() {
+        // GIVEN the notification has FLAG_PROMOTED_ONGOING
+        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
+
+        // THEN the entry is NOT in the fgs section
+        assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void promoterSelectsPromotedOngoing_flagEnabled() {
+        ArgumentCaptor<NotifPromoter> captor = ArgumentCaptor.forClass(NotifPromoter.class);
+        verify(mNotifPipeline).addPromoter(captor.capture());
+        NotifPromoter promoter = captor.getValue();
+
+        // GIVEN the notification has FLAG_PROMOTED_ONGOING
+        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
+
+        // THEN the entry is promoted to top level
+        assertTrue(promoter.shouldPromoteToTopLevel(mEntryBuilder.build()));
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void promoterIgnoresNonPromotedOngoing_flagEnabled() {
+        ArgumentCaptor<NotifPromoter> captor = ArgumentCaptor.forClass(NotifPromoter.class);
+        verify(mNotifPipeline).addPromoter(captor.capture());
+        NotifPromoter promoter = captor.getValue();
+
+        // GIVEN the notification does not have FLAG_PROMOTED_ONGOING
+        mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, false);
+
+        // THEN the entry is NOT promoted to top level
+        assertFalse(promoter.shouldPromoteToTopLevel(mEntryBuilder.build()));
+    }
+
+    @Test
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+    public void noPromoterAdded_flagDisabled() {
+        verify(mNotifPipeline, never()).addPromoter(any());
+    }
+
     private Notification.CallStyle makeCallStyle() {
         final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
                 new Intent("action"), PendingIntent.FLAG_IMMUTABLE);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 7b91eae..38cfb9b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -25,6 +25,8 @@
 import com.android.systemui.biometrics.BiometricNotificationService
 import com.android.systemui.bouncer.domain.startable.BouncerStartable
 import com.android.systemui.clipboardoverlay.ClipboardListener
+import com.android.systemui.complication.ComplicationTypesUpdater
+import com.android.systemui.complication.DreamClockTimeComplication
 import com.android.systemui.controls.dagger.StartControlsStartableModule
 import com.android.systemui.dagger.qualifiers.PerUser
 import com.android.systemui.dreams.AssistantAttentionMonitor
@@ -337,4 +339,18 @@
     abstract fun bindDreamOverlayRegistrant(
         dreamOverlayRegistrant: DreamOverlayRegistrant
     ): CoreStartable
+
+    /** Inject into DreamClockTimeComplication.Registrant */
+    @Binds
+    @IntoMap
+    @ClassKey(DreamClockTimeComplication.Registrant::class)
+    abstract fun bindDreamClockTimeComplicationRegistrant(
+        registrant: DreamClockTimeComplication.Registrant
+    ): CoreStartable
+
+    /** Inject into ComplicationTypesUpdater. */
+    @Binds
+    @IntoMap
+    @ClassKey(ComplicationTypesUpdater::class)
+    abstract fun bindComplicationTypesUpdater(updater: ComplicationTypesUpdater): CoreStartable
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
index 47a0429..733b986 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
@@ -20,13 +20,21 @@
 
 import android.app.Notification;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
 import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt;
 
+import com.google.common.primitives.Booleans;
+
 import javax.inject.Inject;
 
 /**
@@ -44,12 +52,21 @@
 
     @Override
     public void attach(NotifPipeline pipeline) {
+        if (PromotedNotificationUi.isEnabled()) {
+            pipeline.addPromoter(mPromotedOngoingPromoter);
+        }
     }
 
     public NotifSectioner getSectioner() {
         return mNotifSectioner;
     }
 
+    private final NotifPromoter mPromotedOngoingPromoter = new NotifPromoter("PromotedOngoing") {
+        @Override
+        public boolean shouldPromoteToTopLevel(NotificationEntry child) {
+            return isPromotedOngoing(child);
+        }
+    };
 
     /**
      * Puts colorized foreground service and call notifications into its own section.
@@ -64,11 +81,30 @@
             }
             return false;
         }
+
+        private NotifComparator mPreferPromoted = new NotifComparator("PreferPromoted") {
+            @Override
+            public int compare(@NonNull ListEntry o1, @NonNull ListEntry o2) {
+                return -1 * Booleans.compare(
+                        isPromotedOngoing(o1.getRepresentativeEntry()),
+                        isPromotedOngoing(o2.getRepresentativeEntry()));
+            }
+        };
+
+        @Nullable
+        @Override
+        public NotifComparator getComparator() {
+            if (PromotedNotificationUi.isEnabled()) {
+                return mPreferPromoted;
+            } else {
+                return null;
+            }
+        }
     };
 
     /** Determines if the given notification is a colorized or call notification */
     public static boolean isRichOngoing(NotificationEntry entry) {
-        return isColorizedForegroundService(entry) || isCall(entry);
+        return isPromotedOngoing(entry) || isColorizedForegroundService(entry) || isCall(entry);
     }
 
     private static boolean isColorizedForegroundService(NotificationEntry entry) {
@@ -78,6 +114,11 @@
                 && entry.getImportance() > IMPORTANCE_MIN;
     }
 
+    private static boolean isPromotedOngoing(NotificationEntry entry) {
+        // NOTE: isPromotedOngoing already checks the android.app.ui_rich_ongoing flag.
+        return entry != null && entry.getSbn().getNotification().isPromotedOngoing();
+    }
+
     private static boolean isCall(NotificationEntry entry) {
         Notification notification = entry.getSbn().getNotification();
         return entry.getImportance() > IMPORTANCE_MIN
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index 2808056..a0b989b 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -55,16 +55,6 @@
 }
 
 flag {
-    name: "compute_window_changes_on_a11y_v2"
-    namespace: "accessibility"
-    description: "Computes accessibility window changes in accessibility instead of wm package."
-    bug: "322444245"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
     name: "deprecate_package_list_observer"
     namespace: "accessibility"
     description: "Stops using the deprecated PackageListObserver."
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 9a81aa6..5cbe0c4 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -433,22 +433,10 @@
             return Collections.emptyList();
         }
 
-        /**
-         * Callbacks from window manager when there's an accessibility change in windows.
-         *
-         * @param forceSend Send the windows for accessibility even if they haven't changed.
-         * @param topFocusedDisplayId The display Id which has the top focused window.
-         * @param topFocusedWindowToken The window token of top focused window.
-         * @param windows The windows for accessibility.
-         */
-        @Override
-        public void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
+        private void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
                 IBinder topFocusedWindowToken, @NonNull List<WindowInfo> windows) {
+            // TODO(b/322444245): no longer need to get a lock.
             synchronized (mLock) {
-                if (!Flags.computeWindowChangesOnA11yV2()) {
-                    // If the flag is enabled, it's already done in #createWindowInfoListLocked.
-                    updateWindowsByWindowAttributesLocked(windows);
-                }
                 if (DEBUG) {
                     Slogf.i(LOG_TAG, "mDisplayId=%d, topFocusedDisplayId=%d, currentUserId=%d, "
                                     + "visibleBgUsers=%s", mDisplayId, topFocusedDisplayId,
@@ -490,9 +478,7 @@
         }
 
         /**
-         * Called when the windows for accessibility changed. This is called if
-         * {@link com.android.server.accessibility.Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2} is
-         * true.
+         * Called when the windows for accessibility changed.
          *
          * @param forceSend             Send the windows for accessibility even if they haven't
          *                              changed.
@@ -655,16 +641,6 @@
             return true;
         }
 
-        private void updateWindowsByWindowAttributesLocked(List<WindowInfo> windows) {
-            for (int i = windows.size() - 1; i >= 0; i--) {
-                final WindowInfo windowInfo = windows.get(i);
-                final IBinder token = windowInfo.token;
-                final int windowId = findWindowIdLocked(
-                        mAccessibilityUserManager.getCurrentUserIdLocked(), token);
-                updateWindowWithWindowAttributes(windowInfo, mWindowAttributes.get(windowId));
-            }
-        }
-
         private void updateWindowWithWindowAttributes(@NonNull WindowInfo windowInfo,
                 @Nullable AccessibilityWindowAttributes attributes) {
             if (attributes == null) {
@@ -990,19 +966,6 @@
         private AccessibilityWindowInfo populateReportedWindowLocked(int userId,
                 WindowInfo window, SparseArray<AccessibilityWindowInfo> oldWindowsById) {
             final int windowId = findWindowIdLocked(userId, window.token);
-
-            // With the flag enabled, createWindowInfoListLocked() already removes invalid windows.
-            if (!Flags.computeWindowChangesOnA11yV2()) {
-                if (windowId < 0) {
-                    return null;
-                }
-
-                // Don't need to add the embedded hierarchy windows into the a11y windows list.
-                if (isEmbeddedHierarchyWindowsLocked(windowId)) {
-                    return null;
-                }
-            }
-
             final AccessibilityWindowInfo reportedWindow = AccessibilityWindowInfo.obtain();
 
             reportedWindow.setId(windowId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5c5361b..1a5d1f5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -131,6 +131,9 @@
 import static android.provider.Settings.Global.DEBUG_APP;
 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
 import static android.security.Flags.preventIntentRedirect;
+import static android.security.Flags.preventIntentRedirectCollectNestedKeysOnServerIfNotCollected;
+import static android.security.Flags.preventIntentRedirectShowToast;
+import static android.security.Flags.preventIntentRedirectThrowExceptionIfNestedKeysNotCollected;
 import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
 import static android.view.Display.INVALID_DISPLAY;
 
@@ -387,6 +390,7 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.view.autofill.AutofillManagerInternal;
+import android.widget.Toast;
 
 import com.android.internal.annotations.CompositeRWLock;
 import com.android.internal.annotations.GuardedBy;
@@ -437,6 +441,7 @@
 import com.android.server.SystemService;
 import com.android.server.SystemServiceManager;
 import com.android.server.ThreadPriorityBooster;
+import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.am.LowMemDetector.MemFactor;
 import com.android.server.appop.AppOpsService;
@@ -478,6 +483,7 @@
 
 import dalvik.annotation.optimization.NeverCompile;
 import dalvik.system.VMRuntime;
+
 import libcore.util.EmptyArray;
 
 import java.io.File;
@@ -19304,9 +19310,32 @@
      */
     public void addCreatorToken(@Nullable Intent intent, String creatorPackage) {
         if (!preventIntentRedirect()) return;
-
         if (intent == null) return;
 
+        if ((intent.getExtendedFlags() & Intent.EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED) == 0) {
+            Slog.wtf(TAG,
+                    "[IntentRedirect] The intent does not have its nested keys collected as a "
+                            + "preparation for creating intent creator tokens. Intent: "
+                            + intent + "; creatorPackage: " + creatorPackage);
+            if (preventIntentRedirectShowToast()) {
+                UiThread.getHandler().post(
+                        () -> Toast.makeText(mContext,
+                                "Nested keys not collected. go/report-bug-intentRedir to report a"
+                                        + " bug", Toast.LENGTH_LONG).show());
+            }
+            if (preventIntentRedirectThrowExceptionIfNestedKeysNotCollected()) {
+                // this flag will be internal only, not ramped to public.
+                throw new SecurityException(
+                        "The intent does not have its nested keys collected as a preparation for "
+                                + "creating intent creator tokens. Intent: "
+                                + intent + "; creatorPackage: " + creatorPackage);
+            }
+            if (preventIntentRedirectCollectNestedKeysOnServerIfNotCollected()) {
+                // this flag will be ramped to public.
+                intent.collectExtraIntentKeys();
+            }
+        }
+
         String targetPackage = intent.getComponent() != null
                 ? intent.getComponent().getPackageName()
                 : intent.getPackage();
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 415f78a..b7a5f3e 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -598,7 +598,7 @@
         }
 
         if (r != null) {
-            mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode(),
+            mPackageWatchdog.notifyPackageFailure(r.getPackageListWithVersionCode(),
                     PackageWatchdog.FAILURE_REASON_APP_CRASH);
 
             synchronized (mService) {
@@ -1142,7 +1142,7 @@
         }
         // Notify PackageWatchdog without the lock held
         if (packageList != null) {
-            mPackageWatchdog.onPackageFailure(packageList,
+            mPackageWatchdog.notifyPackageFailure(packageList,
                     PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
         }
     }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 2eb9f3c..d5bd057 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1262,6 +1262,17 @@
             mFrameworkStatsLogger = frameworkStatsLogger;
         }
 
+        private static float clampPowerMah(double powerMah, String consumer) {
+            float resultPowerMah = 0;
+            if (powerMah <= Float.MAX_VALUE && powerMah >= Float.MIN_VALUE) {
+                resultPowerMah = (float) powerMah;
+            } else {
+                // Handle overflow appropriately
+                Slog.wtfStack(TAG, consumer + " reported powerMah float overflow: " + powerMah);
+            }
+            return resultPowerMah;
+        }
+
         /**
          * Generates StatsEvents for the supplied battery usage stats and adds them to
          * the supplied list.
@@ -1282,7 +1293,8 @@
                     bus.getAggregateBatteryConsumer(
                             BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
 
-            final float totalDeviceConsumedPowerMah = (float) deviceConsumer.getConsumedPower();
+            final float totalDeviceConsumedPowerMah =
+                    clampPowerMah(deviceConsumer.getConsumedPower(), "AggregateBatteryConsumer");
 
             for (@BatteryConsumer.PowerComponentId int powerComponentId :
                     deviceConsumer.getPowerComponentIds()) {
@@ -1314,7 +1326,9 @@
             // Log single atom for BatteryUsageStats per uid/process_state/component/etc.
             for (UidBatteryConsumer uidConsumer : uidConsumers) {
                 final int uid = uidConsumer.getUid();
-                final float totalConsumedPowerMah = (float) uidConsumer.getConsumedPower();
+
+                final float totalConsumedPowerMah =
+                        clampPowerMah(uidConsumer.getConsumedPower(), "uidConsumer-" + uid);
 
                 for (@BatteryConsumer.PowerComponentId int powerComponentId :
                         uidConsumer.getPowerComponentIds()) {
@@ -1358,7 +1372,10 @@
             }
 
             final String powerComponentName = batteryConsumer.getPowerComponentName(componentId);
-            final float powerMah = (float) batteryConsumer.getConsumedPower(key);
+            final double consumedPowerMah = batteryConsumer.getConsumedPower(key);
+            float powerMah =
+                    clampPowerMah(
+                            consumedPowerMah, "uidConsumer-" + uid + "-" + powerComponentName);
             final long powerComponentDurationMillis = batteryConsumer.getUsageDurationMillis(key);
 
             if (powerMah == 0 && powerComponentDurationMillis == 0) {
diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
index ed41f2e..fa2e674 100644
--- a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
@@ -31,7 +31,6 @@
 import static android.app.AppOpsManager.OP_NONE;
 import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO;
-import static android.app.AppOpsManager.OP_TAKE_AUDIO_FOCUS;
 import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
 import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
 import static android.app.AppOpsManager.UID_STATE_NONEXISTENT;
@@ -177,8 +176,6 @@
             case OP_RECORD_AUDIO:
             case OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO:
                 return PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
-            case OP_TAKE_AUDIO_FOCUS:
-                return PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL;
             default:
                 return PROCESS_CAPABILITY_NONE;
         }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 40d5f86..5c2eb5c 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4954,6 +4954,15 @@
         }
 
         final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
+
+        final Set<Integer> a2dpDevices = AudioSystem.intersectionAudioDeviceTypes(
+                AudioSystem.DEVICE_OUT_ALL_A2DP_SET, deviceTypes);
+        if (!a2dpDevices.isEmpty()) {
+            int index = getStreamVolume(streamType,
+                    a2dpDevices.toArray(new Integer[0])[0].intValue());
+            mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index);
+        }
+
         final Set<Integer> absVolumeMultiModeCaseDevices =
                 AudioSystem.intersectionAudioDeviceTypes(
                         mAbsVolumeMultiModeCaseDevices, deviceTypes);
@@ -11425,6 +11434,10 @@
         return mSpatializerHelper.canBeSpatialized(attributes, format);
     }
 
+    public @NonNull List<Integer> getSpatializedChannelMasks() {
+        return mSpatializerHelper.getSpatializedChannelMasks();
+    }
+
     /** @see Spatializer.SpatializerInfoDispatcherStub */
     public void registerSpatializerCallback(
             @NonNull ISpatializerCallback cb) {
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 9265ff2..afa90d5 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -59,6 +59,8 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 import java.util.UUID;
@@ -1100,6 +1102,23 @@
         return able;
     }
 
+    synchronized @NonNull List<Integer> getSpatializedChannelMasks() {
+        if (!checkSpatializer("getSpatializedChannelMasks")) {
+            return Collections.emptyList();
+        }
+        try {
+            final int[] nativeMasks = new int[0]; // FIXME mSpat query goes here
+            for (int i = 0; i < nativeMasks.length; i++) {
+                nativeMasks[i] = AudioFormat.convertNativeChannelMaskToOutMask(nativeMasks[i]);
+            }
+            final List<Integer> masks = Arrays.stream(nativeMasks).boxed().toList();
+            return masks;
+        } catch (Exception e) { // just catch Exception in case nativeMasks is null
+            Log.e(TAG, "Error calling getSpatializedChannelMasks", e);
+            return Collections.emptyList();
+        }
+    }
+
     //------------------------------------------------------
     // head tracking
     final RemoteCallbackList<ISpatializerHeadTrackingModeCallback> mHeadTrackingModeCallbacks =
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 97a8854..b365ef7 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -434,21 +434,12 @@
 
         public boolean getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(int userId) {
             if (!mMandatoryBiometricsEnabled.containsKey(userId)) {
-                Slog.d(TAG, "update mb toggle for user " + userId);
                 updateMandatoryBiometricsForAllProfiles(userId);
             }
             if (!mMandatoryBiometricsRequirementsSatisfied.containsKey(userId)) {
-                Slog.d(TAG, "update mb reqs for user " + userId);
                 updateMandatoryBiometricsRequirementsForAllProfiles(userId);
             }
 
-            Slog.d(TAG, mMandatoryBiometricsEnabled.getOrDefault(userId,
-                    DEFAULT_MANDATORY_BIOMETRICS_STATUS)
-                    + " " + mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId,
-                    DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS)
-                    + " " + getEnabledForApps(userId)
-                    + " " + (mFingerprintEnrolledForUser.getOrDefault(userId, false /* default */)
-                    || mFaceEnrolledForUser.getOrDefault(userId, false /* default */)));
             return mMandatoryBiometricsEnabled.getOrDefault(userId,
                     DEFAULT_MANDATORY_BIOMETRICS_STATUS)
                     && mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId,
diff --git a/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java b/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java
index 8e72546..eef2b15 100644
--- a/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java
+++ b/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java
@@ -93,7 +93,8 @@
                     return;
                 }
                 final List<VersionedPackage> pkgList = Collections.singletonList(pkg);
-                PackageWatchdog.getInstance(mContext).onPackageFailure(pkgList,  PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
+                PackageWatchdog.getInstance(mContext).notifyPackageFailure(pkgList,
+                        PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
             });
     }
 
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 7cbacd6..4b7e74a 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -22,7 +22,6 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS;
 
@@ -1784,22 +1783,13 @@
                 mA11yWindowsPopulator.populateVisibleWindowsOnScreenLocked(
                         mDisplayId, visibleWindows);
 
-                if (!com.android.server.accessibility.Flags.computeWindowChangesOnA11yV2()) {
-                    windows = buildWindowInfoListLocked(visibleWindows, screenSize);
-                }
-
                 // Gets the top focused display Id and window token for supporting multi-display.
                 topFocusedDisplayId = mService.mRoot.getTopFocusedDisplayContent().getDisplayId();
                 topFocusedWindowToken = topFocusedWindowState.mClient.asBinder();
             }
 
-            if (com.android.server.accessibility.Flags.computeWindowChangesOnA11yV2()) {
-                mCallback.onAccessibilityWindowsChanged(forceSend, topFocusedDisplayId,
-                        topFocusedWindowToken, screenSize, visibleWindows);
-            } else {
-                mCallback.onWindowsForAccessibilityChanged(forceSend, topFocusedDisplayId,
-                        topFocusedWindowToken, windows);
-            }
+            mCallback.onAccessibilityWindowsChanged(forceSend, topFocusedDisplayId,
+                    topFocusedWindowToken, screenSize, visibleWindows);
 
             // Recycle the windows as we do not need them.
             for (final AccessibilityWindowsPopulator.AccessibilityWindow window : visibleWindows) {
@@ -1808,166 +1798,6 @@
             mInitialized = true;
         }
 
-        // Here are old code paths, called when computeWindowChangesOnA11yV2 flag is disabled.
-        // LINT.IfChange
-
-        /**
-         * From a list of windows, decides windows to be exposed to accessibility based on touchable
-         * region in the screen.
-         */
-        private List<WindowInfo> buildWindowInfoListLocked(List<AccessibilityWindow> visibleWindows,
-                Point screenSize) {
-            final List<WindowInfo> windows = new ArrayList<>();
-            final Set<IBinder> addedWindows = mTempBinderSet;
-            addedWindows.clear();
-
-            boolean focusedWindowAdded = false;
-
-            final int visibleWindowCount = visibleWindows.size();
-
-            Region unaccountedSpace = mTempRegion;
-            unaccountedSpace.set(0, 0, screenSize.x, screenSize.y);
-
-            // Iterate until we figure out what is touchable for the entire screen.
-            for (int i = 0; i < visibleWindowCount; i++) {
-                final AccessibilityWindow a11yWindow = visibleWindows.get(i);
-                final Region regionInWindow = new Region();
-                a11yWindow.getTouchableRegionInWindow(regionInWindow);
-                if (windowMattersToAccessibility(a11yWindow, regionInWindow, unaccountedSpace)) {
-                    addPopulatedWindowInfo(a11yWindow, regionInWindow, windows, addedWindows);
-                    if (windowMattersToUnaccountedSpaceComputation(a11yWindow)) {
-                        updateUnaccountedSpace(a11yWindow, unaccountedSpace);
-                    }
-                    focusedWindowAdded |= a11yWindow.isFocused();
-                } else if (a11yWindow.isUntouchableNavigationBar()) {
-                    // If this widow is navigation bar without touchable region, accounting the
-                    // region of navigation bar inset because all touch events from this region
-                    // would be received by launcher, i.e. this region is a un-touchable one
-                    // for the application.
-                    unaccountedSpace.op(
-                            getSystemBarInsetsFrame(
-                                    mService.mWindowMap.get(a11yWindow.getWindowInfo().token)),
-                            unaccountedSpace,
-                            Region.Op.REVERSE_DIFFERENCE);
-                }
-
-                if (unaccountedSpace.isEmpty() && focusedWindowAdded) {
-                    break;
-                }
-            }
-
-            // Remove child/parent references to windows that were not added.
-            final int windowCount = windows.size();
-            for (int i = 0; i < windowCount; i++) {
-                WindowInfo window = windows.get(i);
-                if (!addedWindows.contains(window.parentToken)) {
-                    window.parentToken = null;
-                }
-                if (window.childTokens != null) {
-                    final int childTokenCount = window.childTokens.size();
-                    for (int j = childTokenCount - 1; j >= 0; j--) {
-                        if (!addedWindows.contains(window.childTokens.get(j))) {
-                            window.childTokens.remove(j);
-                        }
-                    }
-                    // Leave the child token list if empty.
-                }
-            }
-
-            addedWindows.clear();
-
-            return windows;
-        }
-
-        // Some windows should be excluded from unaccounted space computation, though they still
-        // should be reported
-        private boolean windowMattersToUnaccountedSpaceComputation(AccessibilityWindow a11yWindow) {
-            // Do not account space of trusted non-touchable windows, except the split-screen
-            // divider.
-            // If it's not trusted, touch events are not sent to the windows behind it.
-            if (!a11yWindow.isTouchable()
-                    && (a11yWindow.getType() != TYPE_DOCK_DIVIDER)
-                    && a11yWindow.isTrustedOverlay()) {
-                return false;
-            }
-
-            if (a11yWindow.getType() == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
-                return false;
-            }
-            return true;
-        }
-
-        private boolean windowMattersToAccessibility(AccessibilityWindow a11yWindow,
-                Region regionInScreen, Region unaccountedSpace) {
-            if (a11yWindow.isFocused()) {
-                return true;
-            }
-
-            // Ignore non-touchable windows, except the split-screen divider, which is
-            // occasionally non-touchable but still useful for identifying split-screen
-            // mode and the PIP menu.
-            if (!a11yWindow.isTouchable()
-                    && (a11yWindow.getType() != TYPE_DOCK_DIVIDER
-                    && !a11yWindow.isPIPMenu())) {
-                return false;
-            }
-
-            // If the window is completely covered by other windows - ignore.
-            if (unaccountedSpace.quickReject(regionInScreen)) {
-                return false;
-            }
-
-            // Add windows of certain types not covered by modal windows.
-            if (isReportedWindowType(a11yWindow.getType())) {
-                return true;
-            }
-
-            return false;
-        }
-
-        private void updateUnaccountedSpace(AccessibilityWindow a11yWindow,
-                Region unaccountedSpace) {
-            if (a11yWindow.getType()
-                    != WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
-                // Account for the space this window takes if the window
-                // is not an accessibility overlay which does not change
-                // the reported windows.
-                final Region touchableRegion = mTempRegion2;
-                a11yWindow.getTouchableRegionInScreen(touchableRegion);
-                unaccountedSpace.op(touchableRegion, unaccountedSpace,
-                        Region.Op.REVERSE_DIFFERENCE);
-            }
-        }
-
-        private static void addPopulatedWindowInfo(AccessibilityWindow a11yWindow,
-                Region regionInScreen, List<WindowInfo> out, Set<IBinder> tokenOut) {
-            final WindowInfo window = a11yWindow.getWindowInfo();
-            if (window.token == null) {
-                // The window was used in calculating visible windows but does not have an
-                // associated IWindow token, so exclude it from the list returned to accessibility.
-                return;
-            }
-            window.regionInScreen.set(regionInScreen);
-            window.layer = tokenOut.size();
-            out.add(window);
-            tokenOut.add(window.token);
-        }
-
-        private static boolean isReportedWindowType(int windowType) {
-            return (windowType != WindowManager.LayoutParams.TYPE_WALLPAPER
-                    && windowType != WindowManager.LayoutParams.TYPE_BOOT_PROGRESS
-                    && windowType != WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY
-                    && windowType != WindowManager.LayoutParams.TYPE_DRAG
-                    && windowType != WindowManager.LayoutParams.TYPE_INPUT_CONSUMER
-                    && windowType != WindowManager.LayoutParams.TYPE_POINTER
-                    && windowType != TYPE_MAGNIFICATION_OVERLAY
-                    && windowType != WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
-                    && windowType != WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY
-                    && windowType != WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
-        }
-
-        // LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java)
-
         private WindowState getTopFocusWindow() {
             return mService.mRoot.getTopFocusedDisplayContent().mCurrentFocus;
         }
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index fd2a909..7fc11e6 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -724,8 +724,7 @@
             }
 
             // Compute system bar insets frame if needed.
-            if (com.android.server.accessibility.Flags.computeWindowChangesOnA11yV2()
-                    && windowState != null && instance.isUntouchableNavigationBar()) {
+            if (windowState != null && instance.isUntouchableNavigationBar()) {
                 final InsetsSourceProvider provider =
                         windowState.getControllableInsetProvider();
                 if (provider != null) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index ce032b4..c77b1d9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -46,7 +46,6 @@
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost;
-import android.view.WindowInfo;
 import android.view.WindowManager.DisplayImePolicy;
 import android.view.inputmethod.ImeTracker;
 import android.window.ScreenCapture;
@@ -158,26 +157,8 @@
      * accessibility changed.
      */
     public interface WindowsForAccessibilityCallback {
-
         /**
-         * Called when the windows for accessibility changed. This is called if
-         * {@link com.android.server.accessibility.Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2} is
-         * false.
-         *
-         * @param forceSend Send the windows for accessibility even if they haven't changed.
-         * @param topFocusedDisplayId The display Id which has the top focused window.
-         * @param topFocusedWindowToken The window token of top focused window.
-         * @param windows The windows for accessibility.
-         */
-        void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
-                IBinder topFocusedWindowToken, @NonNull List<WindowInfo> windows);
-
-        /**
-         * Called when the windows for accessibility changed. This is called if
-         * {@link com.android.server.accessibility.Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2} is
-         * true.
-         * TODO(b/322444245): Remove screenSize parameter by getting it from
-         *  DisplayManager#getDisplay(int).getRealSize() on the a11y side.
+         * Called when the windows for accessibility changed.
          *
          * @param forceSend Send the windows for accessibility even if they haven't changed.
          * @param topFocusedDisplayId The display Id which has the top focused window.
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index 403930d..2ae31ad 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -18,20 +18,24 @@
 
 import static com.android.server.accessibility.AbstractAccessibilityServiceConnection.DISPLAY_TYPE_DEFAULT;
 import static com.android.server.accessibility.AccessibilityWindowManagerTest.DisplayIdMatcher.displayId;
+import static com.android.server.accessibility.AccessibilityWindowManagerTest.EventWindowIdMatcher.eventWindowId;
 import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowChangesMatcher.a11yWindowChanges;
-import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowIdMatcher.a11yWindowId;
+import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowIdMatcher.windowId;
 
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
@@ -42,14 +46,13 @@
 import static org.mockito.Mockito.when;
 
 import android.annotation.Nullable;
+import android.graphics.Point;
+import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.IBinder;
 import android.os.LocaleList;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.IWindow;
@@ -63,6 +66,7 @@
 
 import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
 import com.android.server.accessibility.test.MessageCapturingHandler;
+import com.android.server.wm.AccessibilityWindowsPopulator.AccessibilityWindow;
 import com.android.server.wm.WindowManagerInternal;
 import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback;
 
@@ -70,7 +74,6 @@
 import org.hamcrest.TypeSafeMatcher;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
@@ -81,17 +84,9 @@
 import java.util.Arrays;
 import java.util.List;
 
-// This test verifies deprecated codepath. Probably changing this file means
-// AccessibilityWindowManagerWithAccessibilityWindowTest also needs to be updated.
-// LINT.IfChange
-
 /**
- * Tests for the AccessibilityWindowManager with Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2
- * enabled.
- * TODO(b/322444245): Merge with AccessibilityWindowManagerWithAccessibilityWindowTest
- *  after completing the flag migration.
+ * Tests for the AccessibilityWindowManager.
  */
-@RequiresFlagsDisabled(Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2)
 public class AccessibilityWindowManagerTest {
     private static final String PACKAGE_NAME = "com.android.server.accessibility";
     private static final boolean FORCE_SEND = true;
@@ -122,9 +117,8 @@
 
     // List of window token, mapping from windowId -> window token.
     private final SparseArray<IWindow> mA11yWindowTokens = new SparseArray<>();
-    // List of window info lists, mapping from displayId -> window info lists.
-    private final SparseArray<ArrayList<WindowInfo>> mWindowInfos =
-            new SparseArray<>();
+    // List of window info lists, mapping from displayId -> a11y window lists.
+    private final SparseArray<ArrayList<AccessibilityWindow>> mWindows = new SparseArray<>();
     // List of callback, mapping from displayId -> callback.
     private final SparseArray<WindowsForAccessibilityCallback> mCallbackOfWindows =
             new SparseArray<>();
@@ -134,6 +128,13 @@
 
     private final MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
 
+    // This maps displayId -> next region offset.
+    // Touchable region must have un-occluded area so that it's exposed to a11y services.
+    // This offset can be used as left and top of new region so that top-left of each region are
+    // kept visible.
+    // It's expected to be incremented by some amount everytime the value is used.
+    private final SparseArray<Integer> mNextRegionOffsets = new SparseArray<>();
+
     @Mock private WindowManagerInternal mMockWindowManagerInternal;
     @Mock private AccessibilityWindowManager.AccessibilityEventSender mMockA11yEventSender;
     @Mock private AccessibilitySecurityPolicy mMockA11ySecurityPolicy;
@@ -144,9 +145,6 @@
     @Mock private IBinder mMockEmbeddedToken;
     @Mock private IBinder mMockInvalidToken;
 
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
     @Before
     public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
@@ -159,7 +157,7 @@
                 anyString(), anyInt(), anyInt(), anyInt())).thenReturn(PACKAGE_NAME);
 
         doAnswer((invocation) -> {
-            onWindowsForAccessibilityChanged(invocation.getArgument(0), false);
+            onAccessibilityWindowsChanged(invocation.getArgument(0), false);
             return null;
         }).when(mMockWindowManagerInternal).computeWindowsForAccessibility(anyInt());
 
@@ -173,7 +171,7 @@
         // as top focused display before each testing starts.
         startTrackingPerDisplay(Display.DEFAULT_DISPLAY);
 
-        // AccessibilityEventSender is invoked during onWindowsForAccessibilityChanged.
+        // AccessibilityEventSender is invoked during onAccessibilityWindowsChanged.
         // Resets it for mockito verify of further test case.
         Mockito.reset(mMockA11yEventSender);
 
@@ -237,19 +235,18 @@
     @Test
     public void onWindowsChanged_duringTouchInteractAndFocusChange_shouldChangeActiveWindow() {
         final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        WindowInfo focusedWindowInfo =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX);
+        final WindowInfo focusedWindowInfo =
+                mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
         assertEquals(activeWindowId, mA11yWindowManager.findWindowIdLocked(
                 USER_SYSTEM_ID, focusedWindowInfo.token));
 
         focusedWindowInfo.focused = false;
-        focusedWindowInfo =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX + 1);
-        focusedWindowInfo.focused = true;
+        mWindows.get(Display.DEFAULT_DISPLAY).get(
+                DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().focused = true;
 
         mA11yWindowManager.onTouchInteractionStart();
         setTopFocusedWindowAndDisplay(Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX + 1);
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
     }
@@ -273,7 +270,7 @@
         changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
                 DEFAULT_FOCUSED_INDEX + 1, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
 
-        onWindowsForAccessibilityChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
         // The active window should not be changed.
         assertEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
         // The top focused window should not be changed.
@@ -301,8 +298,8 @@
         changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
                 DEFAULT_FOCUSED_INDEX, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        onWindowsForAccessibilityChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
         // The active window should be changed.
         assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
         // The top focused window should be changed.
@@ -312,53 +309,181 @@
 
     @Test
     public void onWindowsChanged_shouldReportCorrectLayer() {
-        // AccessibilityWindowManager#onWindowsForAccessibilityChanged already invoked in setup.
+        // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
         List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
         for (int i = 0; i < a11yWindows.size(); i++) {
             final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
-            final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(i);
-            assertThat(mWindowInfos.get(Display.DEFAULT_DISPLAY).size() - windowInfo.layer - 1,
+            assertThat(mWindows.get(Display.DEFAULT_DISPLAY).size() - i - 1,
                     is(a11yWindow.getLayer()));
         }
     }
 
     @Test
     public void onWindowsChanged_shouldReportCorrectOrder() {
-        // AccessibilityWindowManager#onWindowsForAccessibilityChanged already invoked in setup.
+        // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
         List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
         for (int i = 0; i < a11yWindows.size(); i++) {
             final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
             final IBinder windowToken = mA11yWindowManager
                     .getWindowTokenForUserAndWindowIdLocked(USER_SYSTEM_ID, a11yWindow.getId());
-            final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(i);
+            final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY)
+                    .get(i).getWindowInfo();
             assertThat(windowToken, is(windowInfo.token));
         }
     }
 
     @Test
-    public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
-        final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        final int correctLayer =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer();
-        windowInfo.layer += 1;
+    public void onWindowsChanged_shouldNotReportNonTouchableWindow() {
+        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        when(window.isTouchable()).thenReturn(false);
+        final int windowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, window.getWindowInfo().token);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-        assertNotEquals(correctLayer,
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer());
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, not(hasItem(windowId(windowId))));
     }
 
     @Test
-    public void onWindowsChangedNoForceSend_layerChanged_shouldNotUpdateWindows() {
-        final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        final int correctLayer =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer();
-        windowInfo.layer += 1;
+    public void onWindowsChanged_shouldReportFocusedNonTouchableWindow() {
+        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
+                DEFAULT_FOCUSED_INDEX);
+        when(window.isTouchable()).thenReturn(false);
+        final int windowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, window.getWindowInfo().token);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        assertEquals(correctLayer,
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer());
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasItem(windowId(windowId)));
+    }
+
+    @Test
+    public void onWindowsChanged_trustedFocusedNonTouchableWindow_shouldNotHideWindowsBelow() {
+        // Make the focused trusted un-touchable window fullscreen.
+        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
+                DEFAULT_FOCUSED_INDEX);
+        setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+        when(window.isTouchable()).thenReturn(false);
+        when(window.isTrustedOverlay()).thenReturn(true);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
+    }
+
+    @Test
+    public void onWindowsChanged_accessibilityOverlay_shouldNotHideWindowsBelow() {
+        // Make the a11y overlay window fullscreen.
+        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+        when(window.getType()).thenReturn(WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
+    }
+
+    @Test
+    public void onWindowsChanged_shouldReportFocusedWindowEvenIfOccluded() {
+        // Make the front window fullscreen.
+        final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(frontWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+        final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
+
+        final AccessibilityWindow focusedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(
+                DEFAULT_FOCUSED_INDEX);
+        final int focusedWindowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, focusedWindow.getWindowInfo().token);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(2));
+        assertThat(a11yWindows.get(0), windowId(frontWindowId));
+        assertThat(a11yWindows.get(1), windowId(focusedWindowId));
+    }
+
+    @Test
+    public void onWindowsChanged_embeddedWindows_shouldOnlyReportHost() throws RemoteException {
+        final Rect embeddingBounds = new Rect(0, 0, 200, 100);
+
+        // The embedded window comes front of the host window.
+        final IBinder embeddedWindowLeashToken = Mockito.mock(IBinder.class);
+        final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
+                false, embeddedWindowLeashToken, USER_SYSTEM_ID);
+        final AccessibilityWindow embeddedWindow = createMockAccessibilityWindow(
+                mA11yWindowTokens.get(embeddedWindowId), Display.DEFAULT_DISPLAY);
+        setRegionForMockAccessibilityWindow(embeddedWindow, new Region(embeddingBounds));
+        mWindows.get(Display.DEFAULT_DISPLAY).set(0, embeddedWindow);
+
+        final IBinder hostWindowLeashToken = Mockito.mock(IBinder.class);
+        final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
+                false, hostWindowLeashToken, USER_SYSTEM_ID);
+        final AccessibilityWindow hostWindow = createMockAccessibilityWindow(
+                mA11yWindowTokens.get(hostWindowId), Display.DEFAULT_DISPLAY);
+        setRegionForMockAccessibilityWindow(hostWindow, new Region(embeddingBounds));
+        mWindows.get(Display.DEFAULT_DISPLAY).set(1, hostWindow);
+
+        mA11yWindowManager.associateEmbeddedHierarchyLocked(
+                hostWindowLeashToken, embeddedWindowLeashToken);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, not(hasItem(windowId(embeddedWindowId))));
+        assertThat(a11yWindows.get(0), windowId(hostWindowId));
+        final Rect bounds = new Rect();
+        a11yWindows.get(0).getBoundsInScreen(bounds);
+        assertEquals(bounds, embeddingBounds);
+    }
+
+    @Test
+    public void onWindowsChanged_shouldNotReportfullyOccludedWindow() {
+        final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(frontWindow, new Region(100, 100, 300, 300));
+        final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
+
+        // index 1 is focused. Let's use the next one for this test.
+        final AccessibilityWindow occludedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(2);
+        setRegionForMockAccessibilityWindow(occludedWindow, new Region(150, 150, 250, 250));
+        final int occludedWindowId = mA11yWindowManager.findWindowIdLocked(
+                USER_SYSTEM_ID, occludedWindow.getWindowInfo().token);
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+        final List<AccessibilityWindowInfo> a11yWindows =
+                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasItem(windowId(frontWindowId)));
+        assertThat(a11yWindows, not(hasItem(windowId(occludedWindowId))));
+    }
+
+    @Test
+    public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
+        assertNotEquals("new title",
+                toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
+                        .get(0).getTitle()));
+
+        mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().title = "new title";
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+        assertEquals("new title",
+                toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
+                        .get(0).getTitle()));
     }
 
     @Test
@@ -368,14 +493,10 @@
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0);
         final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
                 true, USER_SYSTEM_ID);
-        final WindowInfo windowInfo = WindowInfo.obtain();
-        windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
-        windowInfo.token = token.asBinder();
-        windowInfo.layer = 0;
-        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-        mWindowInfos.get(Display.DEFAULT_DISPLAY).set(0, windowInfo);
+        mWindows.get(Display.DEFAULT_DISPLAY).set(0,
+                createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
         assertNotEquals(oldWindow,
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0));
     }
@@ -383,12 +504,12 @@
     @Test
     public void onWindowsChangedNoForceSend_focusChanged_shouldUpdateWindows() {
         final WindowInfo focusedWindowInfo =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX);
-        final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
+                mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
+        final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo();
         focusedWindowInfo.focused = false;
         windowInfo.focused = true;
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
         assertTrue(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0)
                 .isFocused());
     }
@@ -497,15 +618,18 @@
     @Test
     public void computePartialInteractiveRegionForWindow_wholeVisible_returnWholeRegion() {
         // Updates top 2 z-order WindowInfo are whole visible.
-        WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
-        windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(1);
-        windowInfo.regionInScreen.set(0, SCREEN_HEIGHT / 2,
-                SCREEN_WIDTH, SCREEN_HEIGHT);
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(firstWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
+        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
+        setRegionForMockAccessibilityWindow(secondWindow,
+                new Region(0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         final List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(2));
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(0).getId();
 
@@ -523,12 +647,17 @@
     @Test
     public void computePartialInteractiveRegionForWindow_halfVisible_returnHalfRegion() {
         // Updates z-order #1 WindowInfo is half visible.
-        WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
+        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(firstWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
+        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
+        setRegionForMockAccessibilityWindow(secondWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
         final List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(2));
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(1).getId();
 
@@ -539,9 +668,17 @@
 
     @Test
     public void computePartialInteractiveRegionForWindow_notVisible_returnEmptyRegion() {
-        // Since z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
+        // z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
+        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(firstWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
         final List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        // Note that the second window is also exposed even if region is empty because it's focused.
+        assertThat(a11yWindows, hasSize(2));
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(1).getId();
 
@@ -552,16 +689,21 @@
     @Test
     public void computePartialInteractiveRegionForWindow_partialVisible_returnVisibleRegion() {
         // Updates z-order #0 WindowInfo to have two interact-able areas.
-        Region region = new Region(0, 0, SCREEN_WIDTH, 200);
+        final Region region = new Region(0, 0, SCREEN_WIDTH, 200);
         region.op(0, SCREEN_HEIGHT - 200, SCREEN_WIDTH, SCREEN_HEIGHT, Region.Op.UNION);
-        WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
-        windowInfo.regionInScreen.set(region);
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+        setRegionForMockAccessibilityWindow(firstWindow, region);
+        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
+        setRegionForMockAccessibilityWindow(secondWindow,
+                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         final List<AccessibilityWindowInfo> a11yWindows =
                 mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+        assertThat(a11yWindows, hasSize(2));
         final Region outBounds = new Region();
-        int windowId = a11yWindows.get(1).getId();
+        final int windowId = a11yWindows.get(1).getId();
 
         mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
         assertFalse(outBounds.getBounds().isEmpty());
@@ -572,7 +714,8 @@
     @Test
     public void updateActiveAndA11yFocusedWindow_windowStateChangedEvent_noTracking_shouldUpdate() {
         final IBinder eventWindowToken =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX + 1).token;
+                mWindows.get(Display.DEFAULT_DISPLAY)
+                        .get(DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().token;
         final int eventWindowId = mA11yWindowManager.findWindowIdLocked(
                 USER_SYSTEM_ID, eventWindowToken);
         when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
@@ -611,11 +754,11 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(currentActiveWindowId),
+                        eventWindowId(currentActiveWindowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
         assertThat(captor.getAllValues().get(1),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(eventWindowId),
+                        eventWindowId(eventWindowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
     }
 
@@ -641,7 +784,7 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(eventWindowId),
+                        eventWindowId(eventWindowId),
                         a11yWindowChanges(
                                 AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
     }
@@ -690,12 +833,12 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(initialDisplayId),
-                        a11yWindowId(initialWindowId),
+                        eventWindowId(initialWindowId),
                         a11yWindowChanges(
                                 AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
         assertThat(captor.getAllValues().get(1),
                 allOf(displayId(eventDisplayId),
-                        a11yWindowId(eventWindowId),
+                        eventWindowId(eventWindowId),
                         a11yWindowChanges(
                                 AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
     }
@@ -722,7 +865,7 @@
                 AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
                 noUse);
         assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY),
+                        AccessibilityNodeInfo.FOCUS_ACCESSIBILITY),
                 is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));
     }
 
@@ -751,11 +894,11 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(eventWindowId),
+                        eventWindowId(eventWindowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
         assertThat(captor.getAllValues().get(1),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(currentActiveWindowId),
+                        eventWindowId(currentActiveWindowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
     }
 
@@ -763,7 +906,8 @@
     public void onTouchInteractionEnd_noServiceInteractiveWindow_shouldClearA11yFocus()
             throws RemoteException {
         final IBinder defaultFocusWinToken =
-                mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).token;
+                mWindows.get(Display.DEFAULT_DISPLAY).get(
+                        DEFAULT_FOCUSED_INDEX).getWindowInfo().token;
         final int defaultFocusWindowId = mA11yWindowManager.findWindowIdLocked(
                 USER_SYSTEM_ID, defaultFocusWinToken);
         when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
@@ -808,8 +952,8 @@
     @Test
     public void getPictureInPictureWindow_shouldNotNull() {
         assertNull(mA11yWindowManager.getPictureInPictureWindowLocked());
-        mWindowInfos.get(Display.DEFAULT_DISPLAY).get(1).inPictureInPicture = true;
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        mWindows.get(Display.DEFAULT_DISPLAY).get(1).getWindowInfo().inPictureInPicture = true;
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         assertNotNull(mA11yWindowManager.getPictureInPictureWindowLocked());
     }
@@ -823,8 +967,9 @@
         final IAccessibilityInteractionConnection mockRemoteConnection =
                 mA11yWindowManager.getConnectionLocked(
                         USER_SYSTEM_ID, outsideWindowId).getRemote();
-        mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0).hasFlagWatchOutsideTouch = true;
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+        mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().hasFlagWatchOutsideTouch =
+                true;
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
 
         mA11yWindowManager.notifyOutsideTouch(USER_SYSTEM_ID, targetWindowId);
         verify(mockRemoteConnection).notifyOutsideTouch();
@@ -942,18 +1087,14 @@
 
     @Test
     public void sendAccessibilityEventOnWindowRemoval() {
-        final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
+        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
 
         // Removing index 0 because it's not focused, and avoids unnecessary layer change.
         final int windowId =
                 getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-        infos.remove(0);
-        for (WindowInfo info : infos) {
-            // Adjust layer number because it should start from 0.
-            info.layer--;
-        }
+        windows.remove(0);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
 
         final ArgumentCaptor<AccessibilityEvent> captor =
                 ArgumentCaptor.forClass(AccessibilityEvent.class);
@@ -961,27 +1102,21 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(windowId),
+                        eventWindowId(windowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_REMOVED)));
     }
 
     @Test
     public void sendAccessibilityEventOnWindowAddition() throws RemoteException {
-        final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
-
-        for (WindowInfo info : infos) {
-            // Adjust layer number because new window will have 0 so that layer number in
-            // A11yWindowInfo in window won't be changed.
-            info.layer++;
-        }
+        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
 
         final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
                 false, USER_SYSTEM_ID);
-        addWindowInfo(infos, token, 0);
-        final int windowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, infos.size() - 1);
+        // Adding window to the front so that other windows' layer won't change.
+        windows.add(0, createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
+        final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
 
         final ArgumentCaptor<AccessibilityEvent> captor =
                 ArgumentCaptor.forClass(AccessibilityEvent.class);
@@ -989,17 +1124,17 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(windowId),
+                        eventWindowId(windowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ADDED)));
     }
 
     @Test
     public void sendAccessibilityEventOnWindowChange() {
-        final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
-        infos.get(0).title = "new title";
+        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
+        windows.get(0).getWindowInfo().title = "new title";
         final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
 
-        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
 
         final ArgumentCaptor<AccessibilityEvent> captor =
                 ArgumentCaptor.forClass(AccessibilityEvent.class);
@@ -1007,7 +1142,7 @@
                 .sendAccessibilityEventForCurrentUserLocked(captor.capture());
         assertThat(captor.getAllValues().get(0),
                 allOf(displayId(Display.DEFAULT_DISPLAY),
-                        a11yWindowId(windowId),
+                        eventWindowId(windowId),
                         a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_TITLE)));
     }
 
@@ -1017,48 +1152,47 @@
     }
 
     private void startTrackingPerDisplay(int displayId) throws RemoteException {
-        ArrayList<WindowInfo> windowInfosForDisplay = new ArrayList<>();
+        ArrayList<AccessibilityWindow> windowsForDisplay = new ArrayList<>();
         // Adds RemoteAccessibilityConnection into AccessibilityWindowManager, and copy
         // mock window token into mA11yWindowTokens. Also, preparing WindowInfo mWindowInfos
         // for the test.
-        int layer = 0;
         for (int i = 0; i < NUM_GLOBAL_WINDOWS; i++) {
             final IWindow token = addAccessibilityInteractionConnection(displayId,
                     true, USER_SYSTEM_ID);
-            addWindowInfo(windowInfosForDisplay, token, layer++);
+            windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
 
         }
         for (int i = 0; i < NUM_APP_WINDOWS; i++) {
             final IWindow token = addAccessibilityInteractionConnection(displayId,
                     false, USER_SYSTEM_ID);
-            addWindowInfo(windowInfosForDisplay, token, layer++);
+            windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
         }
         // Sets up current focused window of display.
         // Each display has its own current focused window if config_perDisplayFocusEnabled is true.
         // Otherwise only default display needs to current focused window.
         if (mSupportPerDisplayFocus || displayId == Display.DEFAULT_DISPLAY) {
-            windowInfosForDisplay.get(DEFAULT_FOCUSED_INDEX).focused = true;
+            windowsForDisplay.get(DEFAULT_FOCUSED_INDEX).getWindowInfo().focused = true;
         }
         // Turns on windows tracking, and update window info.
         mA11yWindowManager.startTrackingWindows(displayId, false);
         // Puts window lists into array.
-        mWindowInfos.put(displayId, windowInfosForDisplay);
+        mWindows.put(displayId, windowsForDisplay);
         // Sets the default display is the top focused display and
         // its current focused window is the top focused window.
         if (displayId == Display.DEFAULT_DISPLAY) {
             setTopFocusedWindowAndDisplay(displayId, DEFAULT_FOCUSED_INDEX);
         }
         // Invokes callback for sending window lists to A11y framework.
-        onWindowsForAccessibilityChanged(displayId, FORCE_SEND);
+        onAccessibilityWindowsChanged(displayId, FORCE_SEND);
 
         assertEquals(mA11yWindowManager.getWindowListLocked(displayId).size(),
-                windowInfosForDisplay.size());
+                windowsForDisplay.size());
     }
 
     private WindowsForAccessibilityCallback getWindowsForAccessibilityCallbacks(int displayId) {
         ArgumentCaptor<WindowsForAccessibilityCallback> windowsForAccessibilityCallbacksCaptor =
                 ArgumentCaptor.forClass(
-                        WindowManagerInternal.WindowsForAccessibilityCallback.class);
+                        WindowsForAccessibilityCallback.class);
         verify(mMockWindowManagerInternal)
                 .setWindowsForAccessibilityCallback(eq(displayId),
                         windowsForAccessibilityCallbacksCaptor.capture());
@@ -1106,36 +1240,28 @@
         return windowId;
     }
 
-    private void addWindowInfo(ArrayList<WindowInfo> windowInfos, IWindow windowToken, int layer) {
-        final WindowInfo windowInfo = WindowInfo.obtain();
-        windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
-        windowInfo.token = windowToken.asBinder();
-        windowInfo.layer = layer;
-        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-        windowInfos.add(windowInfo);
-    }
-
     private int getWindowIdFromWindowInfosForDisplay(int displayId, int index) {
-        final IBinder windowToken = mWindowInfos.get(displayId).get(index).token;
+        final IBinder windowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
         return mA11yWindowManager.findWindowIdLocked(
                 USER_SYSTEM_ID, windowToken);
     }
 
     private void setTopFocusedWindowAndDisplay(int displayId, int index) {
         // Sets the top focus window.
-        mTopFocusedWindowToken = mWindowInfos.get(displayId).get(index).token;
+        mTopFocusedWindowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
         // Sets the top focused display.
         mTopFocusedDisplayId = displayId;
     }
 
-    private void onWindowsForAccessibilityChanged(int displayId, boolean forceSend) {
+    private void onAccessibilityWindowsChanged(int displayId, boolean forceSend) {
         WindowsForAccessibilityCallback callbacks = mCallbackOfWindows.get(displayId);
         if (callbacks == null) {
             callbacks = getWindowsForAccessibilityCallbacks(displayId);
             mCallbackOfWindows.put(displayId, callbacks);
         }
-        callbacks.onWindowsForAccessibilityChanged(forceSend, mTopFocusedDisplayId,
-                mTopFocusedWindowToken, mWindowInfos.get(displayId));
+        callbacks.onAccessibilityWindowsChanged(forceSend, mTopFocusedDisplayId,
+                mTopFocusedWindowToken, new Point(SCREEN_WIDTH, SCREEN_HEIGHT),
+                mWindows.get(displayId));
     }
 
     private void changeFocusedWindowOnDisplayPerDisplayFocusConfig(
@@ -1144,23 +1270,23 @@
         if (mSupportPerDisplayFocus) {
             // Gets the old focused window of display which wants to change focused window.
             WindowInfo focusedWindowInfo =
-                    mWindowInfos.get(changeFocusedDisplayId).get(oldFocusedWindowIndex);
+                    mWindows.get(changeFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
             // Resets the focus of old focused window.
             focusedWindowInfo.focused = false;
             // Gets the new window of display which wants to change focused window.
             focusedWindowInfo =
-                    mWindowInfos.get(changeFocusedDisplayId).get(newFocusedWindowIndex);
+                    mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
             // Sets the focus of new focused window.
             focusedWindowInfo.focused = true;
         } else {
             // Gets the window of display which wants to change focused window.
             WindowInfo focusedWindowInfo =
-                    mWindowInfos.get(changeFocusedDisplayId).get(newFocusedWindowIndex);
+                    mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
             // Sets the focus of new focused window.
             focusedWindowInfo.focused = true;
             // Gets the old focused window of old top focused display.
             focusedWindowInfo =
-                    mWindowInfos.get(oldTopFocusedDisplayId).get(oldFocusedWindowIndex);
+                    mWindows.get(oldTopFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
             // Resets the focus of old focused window.
             focusedWindowInfo.focused = false;
             // Changes the top focused display and window.
@@ -1168,6 +1294,39 @@
         }
     }
 
+    private AccessibilityWindow createMockAccessibilityWindow(IWindow windowToken, int displayId) {
+        final WindowInfo windowInfo = WindowInfo.obtain();
+        windowInfo.type = WindowManager.LayoutParams.TYPE_APPLICATION;
+        windowInfo.token = windowToken.asBinder();
+
+        final AccessibilityWindow window = Mockito.mock(AccessibilityWindow.class);
+        when(window.getWindowInfo()).thenReturn(windowInfo);
+        when(window.isFocused()).thenAnswer(invocation -> windowInfo.focused);
+        when(window.isTouchable()).thenReturn(true);
+        when(window.getType()).thenReturn(windowInfo.type);
+
+        setRegionForMockAccessibilityWindow(window, nextToucableRegion(displayId));
+        return window;
+    }
+
+    private void setRegionForMockAccessibilityWindow(AccessibilityWindow window, Region region) {
+        doAnswer(invocation -> {
+            ((Region) invocation.getArgument(0)).set(region);
+            return null;
+        }).when(window).getTouchableRegionInScreen(any(Region.class));
+        doAnswer(invocation -> {
+            ((Region) invocation.getArgument(0)).set(region);
+            return null;
+        }).when(window).getTouchableRegionInWindow(any(Region.class));
+    }
+
+    private Region nextToucableRegion(int displayId) {
+        final int topLeft = mNextRegionOffsets.get(displayId, 0);
+        final int bottomRight = topLeft + 100;
+        mNextRegionOffsets.put(displayId, topLeft + 10);
+        return new Region(topLeft, topLeft, bottomRight, bottomRight);
+    }
+
     @Nullable
     private static String toString(@Nullable CharSequence cs) {
         return cs == null ? null : cs.toString();
@@ -1196,16 +1355,16 @@
         }
     }
 
-    static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
+    static class EventWindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
         private int mWindowId;
 
-        WindowIdMatcher(int windowId) {
+        EventWindowIdMatcher(int windowId) {
             super();
             mWindowId = windowId;
         }
 
-        static WindowIdMatcher a11yWindowId(int windowId) {
-            return new WindowIdMatcher(windowId);
+        static EventWindowIdMatcher eventWindowId(int windowId) {
+            return new EventWindowIdMatcher(windowId);
         }
 
         @Override
@@ -1241,5 +1400,27 @@
             description.appendText("Matching to window changes " + mWindowChanges);
         }
     }
+
+    static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityWindowInfo> {
+        private final int mWindowId;
+
+        WindowIdMatcher(int windowId) {
+            super();
+            mWindowId = windowId;
+        }
+
+        static WindowIdMatcher windowId(int windowId) {
+            return new WindowIdMatcher(windowId);
+        }
+
+        @Override
+        protected boolean matchesSafely(AccessibilityWindowInfo window) {
+            return window.getId() == mWindowId;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("Matching to windowId " + mWindowId);
+        }
+    }
 }
-// LINT.ThenChange(/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java)
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java
deleted file mode 100644
index 1904145..0000000
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java
+++ /dev/null
@@ -1,1444 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.accessibility;
-
-import static com.android.server.accessibility.AbstractAccessibilityServiceConnection.DISPLAY_TYPE_DEFAULT;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.DisplayIdMatcher.displayId;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.WindowIdMatcher.windowId;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.WindowChangesMatcher.a11yWindowChanges;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.EventWindowIdMatcher.eventWindowId;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.allOf;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.Nullable;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.IBinder;
-import android.os.LocaleList;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.util.SparseArray;
-import android.view.Display;
-import android.view.IWindow;
-import android.view.WindowInfo;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityWindowAttributes;
-import android.view.accessibility.AccessibilityWindowInfo;
-import android.view.accessibility.IAccessibilityInteractionConnection;
-
-import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
-import com.android.server.accessibility.test.MessageCapturingHandler;
-import com.android.server.wm.AccessibilityWindowsPopulator.AccessibilityWindow;
-import com.android.server.wm.WindowManagerInternal;
-import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for the AccessibilityWindowManager with Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2
- * TODO(b/322444245): Merge with AccessibilityWindowManagerTest
- *  after completing the flag migration.
- */
-@RequiresFlagsEnabled(Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2)
-public class AccessibilityWindowManagerWithAccessibilityWindowTest {
-    private static final String PACKAGE_NAME = "com.android.server.accessibility";
-    private static final boolean FORCE_SEND = true;
-    private static final boolean SEND_ON_WINDOW_CHANGES = false;
-    private static final int USER_SYSTEM_ID = UserHandle.USER_SYSTEM;
-    private static final int USER_PROFILE = 11;
-    private static final int USER_PROFILE_PARENT = 1;
-    private static final int SECONDARY_DISPLAY_ID = Display.DEFAULT_DISPLAY + 1;
-    private static final int NUM_GLOBAL_WINDOWS = 4;
-    private static final int NUM_APP_WINDOWS = 4;
-    private static final int NUM_OF_WINDOWS = (NUM_GLOBAL_WINDOWS + NUM_APP_WINDOWS);
-    private static final int DEFAULT_FOCUSED_INDEX = 1;
-    private static final int SCREEN_WIDTH = 1080;
-    private static final int SCREEN_HEIGHT = 1920;
-    private static final int INVALID_ID = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
-    private static final int HOST_WINDOW_ID = 10;
-    private static final int EMBEDDED_WINDOW_ID = 11;
-    private static final int OTHER_WINDOW_ID = 12;
-
-    private AccessibilityWindowManager mA11yWindowManager;
-    // Window manager will support multiple focused window if config_perDisplayFocusEnabled is true,
-    // i.e., each display would have its current focused window, and one of all focused windows
-    // would be top focused window. Otherwise, window manager only supports one focused window
-    // at all displays, and that focused window would be top focused window.
-    private boolean mSupportPerDisplayFocus = false;
-    private int mTopFocusedDisplayId = Display.INVALID_DISPLAY;
-    private IBinder mTopFocusedWindowToken = null;
-
-    // List of window token, mapping from windowId -> window token.
-    private final SparseArray<IWindow> mA11yWindowTokens = new SparseArray<>();
-    // List of window info lists, mapping from displayId -> a11y window lists.
-    private final SparseArray<ArrayList<AccessibilityWindow>> mWindows = new SparseArray<>();
-    // List of callback, mapping from displayId -> callback.
-    private final SparseArray<WindowsForAccessibilityCallback> mCallbackOfWindows =
-            new SparseArray<>();
-    // List of display ID.
-    private final ArrayList<Integer> mExpectedDisplayList = new ArrayList<>(Arrays.asList(
-            Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID));
-
-    private final MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
-
-    // This maps displayId -> next region offset.
-    // Touchable region must have un-occluded area so that it's exposed to a11y services.
-    // This offset can be used as left and top of new region so that top-left of each region are
-    // kept visible.
-    // It's expected to be incremented by some amount everytime the value is used.
-    private final SparseArray<Integer> mNextRegionOffsets = new SparseArray<>();
-
-    @Mock
-    private WindowManagerInternal mMockWindowManagerInternal;
-    @Mock
-    private AccessibilityWindowManager.AccessibilityEventSender mMockA11yEventSender;
-    @Mock
-    private AccessibilitySecurityPolicy mMockA11ySecurityPolicy;
-    @Mock
-    private AccessibilitySecurityPolicy.AccessibilityUserManager mMockA11yUserManager;
-    @Mock
-    private AccessibilityTraceManager mMockA11yTraceManager;
-
-    @Mock
-    private IBinder mMockHostToken;
-    @Mock
-    private IBinder mMockEmbeddedToken;
-    @Mock
-    private IBinder mMockInvalidToken;
-
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockA11yUserManager.getCurrentUserIdLocked()).thenReturn(USER_SYSTEM_ID);
-        when(mMockA11ySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
-                USER_PROFILE)).thenReturn(USER_PROFILE_PARENT);
-        when(mMockA11ySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
-                USER_SYSTEM_ID)).thenReturn(USER_SYSTEM_ID);
-        when(mMockA11ySecurityPolicy.resolveValidReportedPackageLocked(
-                anyString(), anyInt(), anyInt(), anyInt())).thenReturn(PACKAGE_NAME);
-
-        doAnswer((invocation) -> {
-            onAccessibilityWindowsChanged(invocation.getArgument(0), false);
-            return null;
-        }).when(mMockWindowManagerInternal).computeWindowsForAccessibility(anyInt());
-
-        mA11yWindowManager = new AccessibilityWindowManager(new Object(), mHandler,
-                mMockWindowManagerInternal,
-                mMockA11yEventSender,
-                mMockA11ySecurityPolicy,
-                mMockA11yUserManager,
-                mMockA11yTraceManager);
-        // Starts tracking window of default display and sets the default display
-        // as top focused display before each testing starts.
-        startTrackingPerDisplay(Display.DEFAULT_DISPLAY);
-
-        // AccessibilityEventSender is invoked during onAccessibilityWindowsChanged.
-        // Resets it for mockito verify of further test case.
-        Mockito.reset(mMockA11yEventSender);
-
-        registerLeashedTokenAndWindowId();
-    }
-
-    @After
-    public void tearDown() {
-        mHandler.removeAllMessages();
-    }
-
-    @Test
-    public void startTrackingWindows_shouldEnableWindowManagerCallback() {
-        // AccessibilityWindowManager#startTrackingWindows already invoked in setup.
-        assertTrue(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
-        final WindowsForAccessibilityCallback callbacks =
-                mCallbackOfWindows.get(Display.DEFAULT_DISPLAY);
-        verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(
-                eq(Display.DEFAULT_DISPLAY), eq(callbacks));
-    }
-
-    @Test
-    public void stopTrackingWindows_shouldDisableWindowManagerCallback() {
-        assertTrue(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
-        Mockito.reset(mMockWindowManagerInternal);
-
-        mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
-        assertFalse(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
-        verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(
-                eq(Display.DEFAULT_DISPLAY), isNull());
-
-    }
-
-    @Test
-    public void stopTrackingWindows_shouldClearWindows() {
-        assertTrue(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
-        final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-
-        mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
-        assertNull(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY));
-        assertEquals(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
-                AccessibilityWindowInfo.UNDEFINED_WINDOW_ID);
-        assertEquals(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID),
-                activeWindowId);
-    }
-
-    @Test
-    public void stopTrackingWindows_onNonTopFocusedDisplay_shouldNotResetTopFocusWindow()
-            throws RemoteException {
-        // At setup, the default display sets be the top focused display and
-        // its current focused window sets be the top focused window.
-        // Starts tracking window of second display.
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-        assertTrue(mA11yWindowManager.isTrackingWindowsLocked(SECONDARY_DISPLAY_ID));
-        // Stops tracking windows of second display.
-        mA11yWindowManager.stopTrackingWindows(SECONDARY_DISPLAY_ID);
-        assertNotEquals(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
-                AccessibilityWindowInfo.UNDEFINED_WINDOW_ID);
-    }
-
-    @Test
-    public void onWindowsChanged_duringTouchInteractAndFocusChange_shouldChangeActiveWindow() {
-        final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        final WindowInfo focusedWindowInfo =
-                mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
-        assertEquals(activeWindowId, mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, focusedWindowInfo.token));
-
-        focusedWindowInfo.focused = false;
-        mWindows.get(Display.DEFAULT_DISPLAY).get(
-                DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().focused = true;
-
-        mA11yWindowManager.onTouchInteractionStart();
-        setTopFocusedWindowAndDisplay(Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX + 1);
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
-    }
-
-    @Test
-    public void
-            onWindowsChanged_focusChangeOnNonTopFocusedDisplay_perDisplayFocusOn_notChangeWindow()
-            throws RemoteException {
-        // At setup, the default display sets be the top focused display and
-        // its current focused window sets be the top focused window.
-        // Sets supporting multiple focused window, i.e., config_perDisplayFocusEnabled is true.
-        mSupportPerDisplayFocus = true;
-        // Starts tracking window of second display.
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-        // Gets the active window.
-        final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        // Gets the top focused window.
-        final int topFocusedWindowId =
-                mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT);
-        // Changes the current focused window at second display.
-        changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
-                DEFAULT_FOCUSED_INDEX + 1, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
-
-        onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
-        // The active window should not be changed.
-        assertEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
-        // The top focused window should not be changed.
-        assertEquals(topFocusedWindowId,
-                mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT));
-    }
-
-    @Test
-    public void
-            onWindowChange_focusChangeToNonTopFocusedDisplay_perDisplayFocusOff_shouldChangeWindow()
-            throws RemoteException {
-        // At setup, the default display sets be the top focused display and
-        // its current focused window sets be the top focused window.
-        // Sets not supporting multiple focused window, i.e., config_perDisplayFocusEnabled is
-        // false.
-        mSupportPerDisplayFocus = false;
-        // Starts tracking window of second display.
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-        // Gets the active window.
-        final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        // Gets the top focused window.
-        final int topFocusedWindowId =
-                mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT);
-        // Changes the current focused window from default display to second display.
-        changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
-                DEFAULT_FOCUSED_INDEX, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
-        // The active window should be changed.
-        assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
-        // The top focused window should be changed.
-        assertNotEquals(topFocusedWindowId,
-                mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT));
-    }
-
-    @Test
-    public void onWindowsChanged_shouldReportCorrectLayer() {
-        // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
-        List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        for (int i = 0; i < a11yWindows.size(); i++) {
-            final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
-            assertThat(mWindows.get(Display.DEFAULT_DISPLAY).size() - i - 1,
-                    is(a11yWindow.getLayer()));
-        }
-    }
-
-    @Test
-    public void onWindowsChanged_shouldReportCorrectOrder() {
-        // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
-        List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        for (int i = 0; i < a11yWindows.size(); i++) {
-            final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
-            final IBinder windowToken = mA11yWindowManager
-                    .getWindowTokenForUserAndWindowIdLocked(USER_SYSTEM_ID, a11yWindow.getId());
-            final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY)
-                    .get(i).getWindowInfo();
-            assertThat(windowToken, is(windowInfo.token));
-        }
-    }
-
-    @Test
-    public void onWindowsChanged_shouldNotReportNonTouchableWindow() {
-        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        when(window.isTouchable()).thenReturn(false);
-        final int windowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, window.getWindowInfo().token);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, not(hasItem(windowId(windowId))));
-    }
-
-    @Test
-    public void onWindowsChanged_shouldReportFocusedNonTouchableWindow() {
-        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
-                DEFAULT_FOCUSED_INDEX);
-        when(window.isTouchable()).thenReturn(false);
-        final int windowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, window.getWindowInfo().token);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasItem(windowId(windowId)));
-    }
-
-    @Test
-    public void onWindowsChanged_trustedFocusedNonTouchableWindow_shouldNotHideWindowsBelow() {
-        // Make the focused trusted un-touchable window fullscreen.
-        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
-                DEFAULT_FOCUSED_INDEX);
-        setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-        when(window.isTouchable()).thenReturn(false);
-        when(window.isTrustedOverlay()).thenReturn(true);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
-    }
-
-    @Test
-    public void onWindowsChanged_accessibilityOverlay_shouldNotHideWindowsBelow() {
-        // Make the a11y overlay window fullscreen.
-        final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-        when(window.getType()).thenReturn(WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
-    }
-
-    @Test
-    public void onWindowsChanged_shouldReportFocusedWindowEvenIfOccluded() {
-        // Make the front window fullscreen.
-        final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(frontWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-        final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
-
-        final AccessibilityWindow focusedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(
-                DEFAULT_FOCUSED_INDEX);
-        final int focusedWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, focusedWindow.getWindowInfo().token);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(2));
-        assertThat(a11yWindows.get(0), windowId(frontWindowId));
-        assertThat(a11yWindows.get(1), windowId(focusedWindowId));
-    }
-
-    @Test
-    public void onWindowsChanged_embeddedWindows_shouldOnlyReportHost() throws RemoteException {
-        final Rect embeddingBounds = new Rect(0, 0, 200, 100);
-
-        // The embedded window comes front of the host window.
-        final IBinder embeddedWindowLeashToken = Mockito.mock(IBinder.class);
-        final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, embeddedWindowLeashToken, USER_SYSTEM_ID);
-        final AccessibilityWindow embeddedWindow = createMockAccessibilityWindow(
-                mA11yWindowTokens.get(embeddedWindowId), Display.DEFAULT_DISPLAY);
-        setRegionForMockAccessibilityWindow(embeddedWindow, new Region(embeddingBounds));
-        mWindows.get(Display.DEFAULT_DISPLAY).set(0, embeddedWindow);
-
-        final IBinder hostWindowLeashToken = Mockito.mock(IBinder.class);
-        final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, hostWindowLeashToken, USER_SYSTEM_ID);
-        final AccessibilityWindow hostWindow = createMockAccessibilityWindow(
-                mA11yWindowTokens.get(hostWindowId), Display.DEFAULT_DISPLAY);
-        setRegionForMockAccessibilityWindow(hostWindow, new Region(embeddingBounds));
-        mWindows.get(Display.DEFAULT_DISPLAY).set(1, hostWindow);
-
-        mA11yWindowManager.associateEmbeddedHierarchyLocked(
-                hostWindowLeashToken, embeddedWindowLeashToken);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, not(hasItem(windowId(embeddedWindowId))));
-        assertThat(a11yWindows.get(0), windowId(hostWindowId));
-        final Rect bounds = new Rect();
-        a11yWindows.get(0).getBoundsInScreen(bounds);
-        assertEquals(bounds, embeddingBounds);
-    }
-
-    @Test
-    public void onWindowsChanged_shouldNotReportfullyOccludedWindow() {
-        final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(frontWindow, new Region(100, 100, 300, 300));
-        final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
-
-        // index 1 is focused. Let's use the next one for this test.
-        final AccessibilityWindow occludedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(2);
-        setRegionForMockAccessibilityWindow(occludedWindow, new Region(150, 150, 250, 250));
-        final int occludedWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, occludedWindow.getWindowInfo().token);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasItem(windowId(frontWindowId)));
-        assertThat(a11yWindows, not(hasItem(windowId(occludedWindowId))));
-    }
-
-    @Test
-    public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
-        assertNotEquals("new title",
-                toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
-                        .get(0).getTitle()));
-
-        mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().title = "new title";
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-        assertEquals("new title",
-                toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
-                        .get(0).getTitle()));
-    }
-
-    @Test
-    public void onWindowsChangedNoForceSend_windowChanged_shouldUpdateWindows()
-            throws RemoteException {
-        final AccessibilityWindowInfo oldWindow =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0);
-        final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                true, USER_SYSTEM_ID);
-        mWindows.get(Display.DEFAULT_DISPLAY).set(0,
-                createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        assertNotEquals(oldWindow,
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0));
-    }
-
-    @Test
-    public void onWindowsChangedNoForceSend_focusChanged_shouldUpdateWindows() {
-        final WindowInfo focusedWindowInfo =
-                mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
-        final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo();
-        focusedWindowInfo.focused = false;
-        windowInfo.focused = true;
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        assertTrue(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0)
-                .isFocused());
-    }
-
-    @Test
-    public void removeAccessibilityInteractionConnection_byWindowToken_shouldRemoved() {
-        for (int i = 0; i < NUM_OF_WINDOWS; i++) {
-            final int windowId = mA11yWindowTokens.keyAt(i);
-            final IWindow windowToken = mA11yWindowTokens.valueAt(i);
-            assertNotNull(mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId));
-
-            mA11yWindowManager.removeAccessibilityInteractionConnection(windowToken);
-            assertNull(mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId));
-        }
-    }
-
-    @Test
-    public void remoteAccessibilityConnection_binderDied_shouldRemoveConnection() {
-        for (int i = 0; i < NUM_OF_WINDOWS; i++) {
-            final int windowId = mA11yWindowTokens.keyAt(i);
-            final RemoteAccessibilityConnection remoteA11yConnection =
-                    mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId);
-            assertNotNull(remoteA11yConnection);
-
-            remoteA11yConnection.binderDied();
-            assertNull(mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId));
-        }
-    }
-
-    @Test
-    public void getWindowTokenForUserAndWindowId_shouldNotNull() {
-        final List<AccessibilityWindowInfo> windows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        for (int i = 0; i < windows.size(); i++) {
-            final int windowId = windows.get(i).getId();
-
-            assertNotNull(mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(
-                    USER_SYSTEM_ID, windowId));
-        }
-    }
-
-    @Test
-    public void findWindowId() {
-        final List<AccessibilityWindowInfo> windows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        for (int i = 0; i < windows.size(); i++) {
-            final int windowId = windows.get(i).getId();
-            final IBinder windowToken = mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(
-                    USER_SYSTEM_ID, windowId);
-
-            assertEquals(mA11yWindowManager.findWindowIdLocked(
-                    USER_SYSTEM_ID, windowToken), windowId);
-        }
-    }
-
-    @Test
-    public void resolveParentWindowId_windowIsNotEmbedded_shouldReturnGivenId()
-            throws RemoteException {
-        final int windowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY, false,
-                Mockito.mock(IBinder.class), USER_SYSTEM_ID);
-        assertEquals(windowId, mA11yWindowManager.resolveParentWindowIdLocked(windowId));
-    }
-
-    @Test
-    public void resolveParentWindowId_windowIsNotRegistered_shouldReturnGivenId() {
-        final int windowId = -1;
-        assertEquals(windowId, mA11yWindowManager.resolveParentWindowIdLocked(windowId));
-    }
-
-    @Test
-    public void resolveParentWindowId_windowIsAssociated_shouldReturnParentWindowId()
-            throws RemoteException {
-        final IBinder mockHostToken = Mockito.mock(IBinder.class);
-        final IBinder mockEmbeddedToken = Mockito.mock(IBinder.class);
-        final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, mockHostToken, USER_SYSTEM_ID);
-        final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, mockEmbeddedToken, USER_SYSTEM_ID);
-
-        mA11yWindowManager.associateEmbeddedHierarchyLocked(mockHostToken, mockEmbeddedToken);
-
-        final int resolvedWindowId = mA11yWindowManager.resolveParentWindowIdLocked(
-                embeddedWindowId);
-        assertEquals(hostWindowId, resolvedWindowId);
-    }
-
-    @Test
-    public void resolveParentWindowId_windowIsDisassociated_shouldReturnGivenId()
-            throws RemoteException {
-        final IBinder mockHostToken = Mockito.mock(IBinder.class);
-        final IBinder mockEmbeddedToken = Mockito.mock(IBinder.class);
-        final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, mockHostToken, USER_SYSTEM_ID);
-        final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, mockEmbeddedToken, USER_SYSTEM_ID);
-
-        mA11yWindowManager.associateEmbeddedHierarchyLocked(mockHostToken, mockEmbeddedToken);
-        mA11yWindowManager.disassociateEmbeddedHierarchyLocked(mockEmbeddedToken);
-
-        final int resolvedWindowId = mA11yWindowManager.resolveParentWindowIdLocked(
-                embeddedWindowId);
-        assertNotEquals(hostWindowId, resolvedWindowId);
-        assertEquals(embeddedWindowId, resolvedWindowId);
-    }
-
-    @Test
-    public void computePartialInteractiveRegionForWindow_wholeVisible_returnWholeRegion() {
-        // Updates top 2 z-order WindowInfo are whole visible.
-        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(firstWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
-        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
-        setRegionForMockAccessibilityWindow(secondWindow,
-                new Region(0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(2));
-        final Region outBounds = new Region();
-        int windowId = a11yWindows.get(0).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
-        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
-
-        windowId = a11yWindows.get(1).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
-        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
-    }
-
-    @Test
-    public void computePartialInteractiveRegionForWindow_halfVisible_returnHalfRegion() {
-        // Updates z-order #1 WindowInfo is half visible.
-        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(firstWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
-        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
-        setRegionForMockAccessibilityWindow(secondWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(2));
-        final Region outBounds = new Region();
-        int windowId = a11yWindows.get(1).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
-        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
-    }
-
-    @Test
-    public void computePartialInteractiveRegionForWindow_notVisible_returnEmptyRegion() {
-        // z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
-        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(firstWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        // Note that the second window is also exposed even if region is empty because it's focused.
-        assertThat(a11yWindows, hasSize(2));
-        final Region outBounds = new Region();
-        int windowId = a11yWindows.get(1).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertTrue(outBounds.getBounds().isEmpty());
-    }
-
-    @Test
-    public void computePartialInteractiveRegionForWindow_partialVisible_returnVisibleRegion() {
-        // Updates z-order #0 WindowInfo to have two interact-able areas.
-        final Region region = new Region(0, 0, SCREEN_WIDTH, 200);
-        region.op(0, SCREEN_HEIGHT - 200, SCREEN_WIDTH, SCREEN_HEIGHT, Region.Op.UNION);
-        final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
-        setRegionForMockAccessibilityWindow(firstWindow, region);
-        final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
-        setRegionForMockAccessibilityWindow(secondWindow,
-                new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        final List<AccessibilityWindowInfo> a11yWindows =
-                mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
-        assertThat(a11yWindows, hasSize(2));
-        final Region outBounds = new Region();
-        final int windowId = a11yWindows.get(1).getId();
-
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
-        assertFalse(outBounds.getBounds().isEmpty());
-        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
-        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT - 400));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_windowStateChangedEvent_noTracking_shouldUpdate() {
-        final IBinder eventWindowToken =
-                mWindows.get(Display.DEFAULT_DISPLAY)
-                        .get(DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().token;
-        final int eventWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, eventWindowToken);
-        when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
-                .thenReturn(eventWindowToken);
-
-        final int noUse = 0;
-        mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(eventWindowId));
-        assertThat(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
-                is(eventWindowId));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_hoverEvent_touchInteract_shouldSetActiveWindow() {
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX + 1);
-        final int currentActiveWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        assertThat(currentActiveWindowId, is(not(eventWindowId)));
-
-        final int noUse = 0;
-        mA11yWindowManager.onTouchInteractionStart();
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(eventWindowId));
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(2))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(currentActiveWindowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
-        assertThat(captor.getAllValues().get(1),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(eventWindowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_shouldUpdateA11yFocus() {
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX);
-        final int currentA11yFocusedWindowId = mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
-        assertThat(currentA11yFocusedWindowId, is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));
-
-        final int noUse = 0;
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(1))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(eventWindowId),
-                        a11yWindowChanges(
-                                AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_defaultToSecondary()
-            throws RemoteException {
-        runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
-                Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID);
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_SecondaryToDefault()
-            throws RemoteException {
-        runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
-                SECONDARY_DISPLAY_ID, Display.DEFAULT_DISPLAY);
-    }
-
-    private void runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
-            int initialDisplayId, int eventDisplayId) throws RemoteException {
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-        final int initialWindowId = getWindowIdFromWindowInfosForDisplay(
-                initialDisplayId, DEFAULT_FOCUSED_INDEX);
-        final int noUse = 0;
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                initialWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(initialWindowId));
-        Mockito.reset(mMockA11yEventSender);
-
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(
-                eventDisplayId, DEFAULT_FOCUSED_INDEX);
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(2))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(initialDisplayId),
-                        eventWindowId(initialWindowId),
-                        a11yWindowChanges(
-                                AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
-        assertThat(captor.getAllValues().get(1),
-                allOf(displayId(eventDisplayId),
-                        eventWindowId(eventWindowId),
-                        a11yWindowChanges(
-                                AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
-    }
-
-    @Test
-    public void updateActiveAndA11yFocusedWindow_clearA11yFocusEvent_shouldClearA11yFocus() {
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX);
-        final int currentA11yFocusedWindowId = mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
-        assertThat(currentA11yFocusedWindowId, is(not(eventWindowId)));
-
-        final int noUse = 0;
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
-                noUse);
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                        AccessibilityNodeInfo.FOCUS_ACCESSIBILITY),
-                is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));
-    }
-
-    @Test
-    public void onTouchInteractionEnd_shouldRollbackActiveWindow() {
-        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX + 1);
-        final int currentActiveWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        assertThat(currentActiveWindowId, is(not(eventWindowId)));
-
-        final int noUse = 0;
-        mA11yWindowManager.onTouchInteractionStart();
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                eventWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(eventWindowId));
-        // AccessibilityEventSender is invoked after active window changed. Reset it.
-        Mockito.reset(mMockA11yEventSender);
-
-        mA11yWindowManager.onTouchInteractionEnd();
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(2))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(eventWindowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
-        assertThat(captor.getAllValues().get(1),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(currentActiveWindowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
-    }
-
-    @Test
-    public void onTouchInteractionEnd_noServiceInteractiveWindow_shouldClearA11yFocus()
-            throws RemoteException {
-        final IBinder defaultFocusWinToken =
-                mWindows.get(Display.DEFAULT_DISPLAY).get(
-                        DEFAULT_FOCUSED_INDEX).getWindowInfo().token;
-        final int defaultFocusWindowId = mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, defaultFocusWinToken);
-        when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
-                .thenReturn(defaultFocusWinToken);
-        final int newFocusWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
-                DEFAULT_FOCUSED_INDEX + 1);
-        final IAccessibilityInteractionConnection mockNewFocusConnection =
-                mA11yWindowManager.getConnectionLocked(
-                        USER_SYSTEM_ID, newFocusWindowId).getRemote();
-
-        mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
-        final int noUse = 0;
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                defaultFocusWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(defaultFocusWindowId));
-        assertThat(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
-                is(defaultFocusWindowId));
-
-        mA11yWindowManager.onTouchInteractionStart();
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                newFocusWindowId,
-                noUse,
-                AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
-                noUse);
-        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
-                newFocusWindowId,
-                AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
-                noUse);
-        assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(newFocusWindowId));
-        assertThat(mA11yWindowManager.getFocusedWindowId(
-                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(newFocusWindowId));
-
-        mA11yWindowManager.onTouchInteractionEnd();
-        mHandler.sendLastMessage();
-        verify(mockNewFocusConnection).clearAccessibilityFocus();
-    }
-
-    @Test
-    public void getPictureInPictureWindow_shouldNotNull() {
-        assertNull(mA11yWindowManager.getPictureInPictureWindowLocked());
-        mWindows.get(Display.DEFAULT_DISPLAY).get(1).getWindowInfo().inPictureInPicture = true;
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        assertNotNull(mA11yWindowManager.getPictureInPictureWindowLocked());
-    }
-
-    @Test
-    public void notifyOutsideTouch() throws RemoteException {
-        final int targetWindowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 1);
-        final int outsideWindowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-        final IAccessibilityInteractionConnection mockRemoteConnection =
-                mA11yWindowManager.getConnectionLocked(
-                        USER_SYSTEM_ID, outsideWindowId).getRemote();
-        mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().hasFlagWatchOutsideTouch =
-                true;
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
-        mA11yWindowManager.notifyOutsideTouch(USER_SYSTEM_ID, targetWindowId);
-        verify(mockRemoteConnection).notifyOutsideTouch();
-    }
-
-    @Test
-    public void addAccessibilityInteractionConnection_profileUser_findInParentUser()
-            throws RemoteException {
-        final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, USER_PROFILE);
-        final int windowId = mA11yWindowManager.findWindowIdLocked(
-                USER_PROFILE_PARENT, token.asBinder());
-        assertTrue(windowId >= 0);
-    }
-
-    @Test
-    public void getDisplayList() throws RemoteException {
-        // Starts tracking window of second display.
-        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-
-        final ArrayList<Integer> displayList = mA11yWindowManager.getDisplayListLocked(
-                DISPLAY_TYPE_DEFAULT);
-        assertTrue(displayList.equals(mExpectedDisplayList));
-    }
-
-    @Test
-    public void setAccessibilityWindowIdToSurfaceMetadata()
-            throws RemoteException {
-        final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                true, USER_SYSTEM_ID);
-        int windowId = -1;
-        for (int i = 0; i < mA11yWindowTokens.size(); i++) {
-            if (mA11yWindowTokens.valueAt(i).equals(token)) {
-                windowId = mA11yWindowTokens.keyAt(i);
-            }
-        }
-        assertNotEquals("Returned token is not found in mA11yWindowTokens", -1, windowId);
-        verify(mMockWindowManagerInternal, times(1)).setAccessibilityIdToSurfaceMetadata(
-                token.asBinder(), windowId);
-
-        mA11yWindowManager.removeAccessibilityInteractionConnection(token);
-        verify(mMockWindowManagerInternal, times(1)).setAccessibilityIdToSurfaceMetadata(
-                token.asBinder(), -1);
-    }
-
-    @Test
-    public void getHostTokenLocked_hierarchiesAreAssociated_shouldReturnHostToken() {
-        mA11yWindowManager.associateLocked(mMockEmbeddedToken, mMockHostToken);
-        final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockEmbeddedToken);
-        assertEquals(hostToken, mMockHostToken);
-    }
-
-    @Test
-    public void getHostTokenLocked_hierarchiesAreNotAssociated_shouldReturnNull() {
-        final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockEmbeddedToken);
-        assertNull(hostToken);
-    }
-
-    @Test
-    public void getHostTokenLocked_embeddedHierarchiesAreDisassociated_shouldReturnNull() {
-        mA11yWindowManager.associateLocked(mMockEmbeddedToken, mMockHostToken);
-        mA11yWindowManager.disassociateLocked(mMockEmbeddedToken);
-        final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockEmbeddedToken);
-        assertNull(hostToken);
-    }
-
-    @Test
-    public void getHostTokenLocked_hostHierarchiesAreDisassociated_shouldReturnNull() {
-        mA11yWindowManager.associateLocked(mMockEmbeddedToken, mMockHostToken);
-        mA11yWindowManager.disassociateLocked(mMockHostToken);
-        final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockHostToken);
-        assertNull(hostToken);
-    }
-
-    @Test
-    public void getWindowIdLocked_windowIsRegistered_shouldReturnWindowId() {
-        final int windowId = mA11yWindowManager.getWindowIdLocked(mMockHostToken);
-        assertEquals(windowId, HOST_WINDOW_ID);
-    }
-
-    @Test
-    public void getWindowIdLocked_windowIsNotRegistered_shouldReturnInvalidWindowId() {
-        final int windowId = mA11yWindowManager.getWindowIdLocked(mMockInvalidToken);
-        assertEquals(windowId, INVALID_ID);
-    }
-
-    @Test
-    public void getTokenLocked_windowIsRegistered_shouldReturnToken() {
-        final IBinder token = mA11yWindowManager.getLeashTokenLocked(HOST_WINDOW_ID);
-        assertEquals(token, mMockHostToken);
-    }
-
-    @Test
-    public void getTokenLocked_windowIsNotRegistered_shouldReturnNull() {
-        final IBinder token = mA11yWindowManager.getLeashTokenLocked(OTHER_WINDOW_ID);
-        assertNull(token);
-    }
-
-    @Test
-    public void setAccessibilityWindowAttributes_windowIsNotRegistered_titleIsChanged() {
-        final int windowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
-        layoutParams.accessibilityTitle = "accessibility window title";
-        final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
-                layoutParams, new LocaleList());
-
-        mA11yWindowManager.setAccessibilityWindowAttributes(Display.DEFAULT_DISPLAY, windowId,
-                USER_SYSTEM_ID, attributes);
-
-        final AccessibilityWindowInfo a11yWindow = mA11yWindowManager.findA11yWindowInfoByIdLocked(
-                windowId);
-        assertEquals(toString(layoutParams.accessibilityTitle), toString(a11yWindow.getTitle()));
-    }
-
-    @Test
-    public void sendAccessibilityEventOnWindowRemoval() {
-        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
-
-        // Removing index 0 because it's not focused, and avoids unnecessary layer change.
-        final int windowId =
-                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-        windows.remove(0);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(1))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(windowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_REMOVED)));
-    }
-
-    @Test
-    public void sendAccessibilityEventOnWindowAddition() throws RemoteException {
-        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
-
-        final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
-                false, USER_SYSTEM_ID);
-        // Adding window to the front so that other windows' layer won't change.
-        windows.add(0, createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
-        final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(1))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(windowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ADDED)));
-    }
-
-    @Test
-    public void sendAccessibilityEventOnWindowChange() {
-        final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
-        windows.get(0).getWindowInfo().title = "new title";
-        final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-
-        onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-
-        final ArgumentCaptor<AccessibilityEvent> captor =
-                ArgumentCaptor.forClass(AccessibilityEvent.class);
-        verify(mMockA11yEventSender, times(1))
-                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
-        assertThat(captor.getAllValues().get(0),
-                allOf(displayId(Display.DEFAULT_DISPLAY),
-                        eventWindowId(windowId),
-                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_TITLE)));
-    }
-
-    private void registerLeashedTokenAndWindowId() {
-        mA11yWindowManager.registerIdLocked(mMockHostToken, HOST_WINDOW_ID);
-        mA11yWindowManager.registerIdLocked(mMockEmbeddedToken, EMBEDDED_WINDOW_ID);
-    }
-
-    private void startTrackingPerDisplay(int displayId) throws RemoteException {
-        ArrayList<AccessibilityWindow> windowsForDisplay = new ArrayList<>();
-        // Adds RemoteAccessibilityConnection into AccessibilityWindowManager, and copy
-        // mock window token into mA11yWindowTokens. Also, preparing WindowInfo mWindowInfos
-        // for the test.
-        for (int i = 0; i < NUM_GLOBAL_WINDOWS; i++) {
-            final IWindow token = addAccessibilityInteractionConnection(displayId,
-                    true, USER_SYSTEM_ID);
-            windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
-
-        }
-        for (int i = 0; i < NUM_APP_WINDOWS; i++) {
-            final IWindow token = addAccessibilityInteractionConnection(displayId,
-                    false, USER_SYSTEM_ID);
-            windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
-        }
-        // Sets up current focused window of display.
-        // Each display has its own current focused window if config_perDisplayFocusEnabled is true.
-        // Otherwise only default display needs to current focused window.
-        if (mSupportPerDisplayFocus || displayId == Display.DEFAULT_DISPLAY) {
-            windowsForDisplay.get(DEFAULT_FOCUSED_INDEX).getWindowInfo().focused = true;
-        }
-        // Turns on windows tracking, and update window info.
-        mA11yWindowManager.startTrackingWindows(displayId, false);
-        // Puts window lists into array.
-        mWindows.put(displayId, windowsForDisplay);
-        // Sets the default display is the top focused display and
-        // its current focused window is the top focused window.
-        if (displayId == Display.DEFAULT_DISPLAY) {
-            setTopFocusedWindowAndDisplay(displayId, DEFAULT_FOCUSED_INDEX);
-        }
-        // Invokes callback for sending window lists to A11y framework.
-        onAccessibilityWindowsChanged(displayId, FORCE_SEND);
-
-        assertEquals(mA11yWindowManager.getWindowListLocked(displayId).size(),
-                windowsForDisplay.size());
-    }
-
-    private WindowsForAccessibilityCallback getWindowsForAccessibilityCallbacks(int displayId) {
-        ArgumentCaptor<WindowsForAccessibilityCallback> windowsForAccessibilityCallbacksCaptor =
-                ArgumentCaptor.forClass(
-                        WindowsForAccessibilityCallback.class);
-        verify(mMockWindowManagerInternal)
-                .setWindowsForAccessibilityCallback(eq(displayId),
-                        windowsForAccessibilityCallbacksCaptor.capture());
-        return windowsForAccessibilityCallbacksCaptor.getValue();
-    }
-
-    private IWindow addAccessibilityInteractionConnection(int displayId, boolean bGlobal,
-            int userId) throws RemoteException {
-        final IWindow mockWindowToken = Mockito.mock(IWindow.class);
-        final IAccessibilityInteractionConnection mockA11yConnection = Mockito.mock(
-                IAccessibilityInteractionConnection.class);
-        final IBinder mockConnectionBinder = Mockito.mock(IBinder.class);
-        final IBinder mockWindowBinder = Mockito.mock(IBinder.class);
-        final IBinder mockLeashToken = Mockito.mock(IBinder.class);
-        when(mockA11yConnection.asBinder()).thenReturn(mockConnectionBinder);
-        when(mockWindowToken.asBinder()).thenReturn(mockWindowBinder);
-        when(mMockA11ySecurityPolicy.isCallerInteractingAcrossUsers(userId))
-                .thenReturn(bGlobal);
-        when(mMockWindowManagerInternal.getDisplayIdForWindow(mockWindowBinder))
-                .thenReturn(displayId);
-
-        int windowId = mA11yWindowManager.addAccessibilityInteractionConnection(
-                mockWindowToken, mockLeashToken, mockA11yConnection, PACKAGE_NAME, userId);
-        mA11yWindowTokens.put(windowId, mockWindowToken);
-        return mockWindowToken;
-    }
-
-    private int addAccessibilityInteractionConnection(int displayId, boolean bGlobal,
-            IBinder leashToken, int userId) throws RemoteException {
-        final IWindow mockWindowToken = Mockito.mock(IWindow.class);
-        final IAccessibilityInteractionConnection mockA11yConnection = Mockito.mock(
-                IAccessibilityInteractionConnection.class);
-        final IBinder mockConnectionBinder = Mockito.mock(IBinder.class);
-        final IBinder mockWindowBinder = Mockito.mock(IBinder.class);
-        when(mockA11yConnection.asBinder()).thenReturn(mockConnectionBinder);
-        when(mockWindowToken.asBinder()).thenReturn(mockWindowBinder);
-        when(mMockA11ySecurityPolicy.isCallerInteractingAcrossUsers(userId))
-                .thenReturn(bGlobal);
-        when(mMockWindowManagerInternal.getDisplayIdForWindow(mockWindowBinder))
-                .thenReturn(displayId);
-
-        int windowId = mA11yWindowManager.addAccessibilityInteractionConnection(
-                mockWindowToken, leashToken, mockA11yConnection, PACKAGE_NAME, userId);
-        mA11yWindowTokens.put(windowId, mockWindowToken);
-        return windowId;
-    }
-
-    private int getWindowIdFromWindowInfosForDisplay(int displayId, int index) {
-        final IBinder windowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
-        return mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, windowToken);
-    }
-
-    private void setTopFocusedWindowAndDisplay(int displayId, int index) {
-        // Sets the top focus window.
-        mTopFocusedWindowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
-        // Sets the top focused display.
-        mTopFocusedDisplayId = displayId;
-    }
-
-    private void onAccessibilityWindowsChanged(int displayId, boolean forceSend) {
-        WindowsForAccessibilityCallback callbacks = mCallbackOfWindows.get(displayId);
-        if (callbacks == null) {
-            callbacks = getWindowsForAccessibilityCallbacks(displayId);
-            mCallbackOfWindows.put(displayId, callbacks);
-        }
-        callbacks.onAccessibilityWindowsChanged(forceSend, mTopFocusedDisplayId,
-                mTopFocusedWindowToken, new Point(SCREEN_WIDTH, SCREEN_HEIGHT),
-                mWindows.get(displayId));
-    }
-
-    private void changeFocusedWindowOnDisplayPerDisplayFocusConfig(
-            int changeFocusedDisplayId, int newFocusedWindowIndex, int oldTopFocusedDisplayId,
-            int oldFocusedWindowIndex) {
-        if (mSupportPerDisplayFocus) {
-            // Gets the old focused window of display which wants to change focused window.
-            WindowInfo focusedWindowInfo =
-                    mWindows.get(changeFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
-            // Resets the focus of old focused window.
-            focusedWindowInfo.focused = false;
-            // Gets the new window of display which wants to change focused window.
-            focusedWindowInfo =
-                    mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
-            // Sets the focus of new focused window.
-            focusedWindowInfo.focused = true;
-        } else {
-            // Gets the window of display which wants to change focused window.
-            WindowInfo focusedWindowInfo =
-                    mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
-            // Sets the focus of new focused window.
-            focusedWindowInfo.focused = true;
-            // Gets the old focused window of old top focused display.
-            focusedWindowInfo =
-                    mWindows.get(oldTopFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
-            // Resets the focus of old focused window.
-            focusedWindowInfo.focused = false;
-            // Changes the top focused display and window.
-            setTopFocusedWindowAndDisplay(changeFocusedDisplayId, newFocusedWindowIndex);
-        }
-    }
-
-    private AccessibilityWindow createMockAccessibilityWindow(IWindow windowToken, int displayId) {
-        final WindowInfo windowInfo = WindowInfo.obtain();
-        windowInfo.type = WindowManager.LayoutParams.TYPE_APPLICATION;
-        windowInfo.token = windowToken.asBinder();
-
-        final AccessibilityWindow window = Mockito.mock(AccessibilityWindow.class);
-        when(window.getWindowInfo()).thenReturn(windowInfo);
-        when(window.isFocused()).thenAnswer(invocation -> windowInfo.focused);
-        when(window.isTouchable()).thenReturn(true);
-        when(window.getType()).thenReturn(windowInfo.type);
-
-        setRegionForMockAccessibilityWindow(window, nextToucableRegion(displayId));
-        return window;
-    }
-
-    private void setRegionForMockAccessibilityWindow(AccessibilityWindow window, Region region) {
-        doAnswer(invocation -> {
-            ((Region) invocation.getArgument(0)).set(region);
-            return null;
-        }).when(window).getTouchableRegionInScreen(any(Region.class));
-        doAnswer(invocation -> {
-            ((Region) invocation.getArgument(0)).set(region);
-            return null;
-        }).when(window).getTouchableRegionInWindow(any(Region.class));
-    }
-
-    private Region nextToucableRegion(int displayId) {
-        final int topLeft = mNextRegionOffsets.get(displayId, 0);
-        final int bottomRight = topLeft + 100;
-        mNextRegionOffsets.put(displayId, topLeft + 10);
-        return new Region(topLeft, topLeft, bottomRight, bottomRight);
-    }
-
-    @Nullable
-    private static String toString(@Nullable CharSequence cs) {
-        return cs == null ? null : cs.toString();
-    }
-
-    static class DisplayIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
-        private final int mDisplayId;
-
-        DisplayIdMatcher(int displayId) {
-            super();
-            mDisplayId = displayId;
-        }
-
-        static DisplayIdMatcher displayId(int displayId) {
-            return new DisplayIdMatcher(displayId);
-        }
-
-        @Override
-        protected boolean matchesSafely(AccessibilityEvent event) {
-            return event.getDisplayId() == mDisplayId;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("Matching to displayId " + mDisplayId);
-        }
-    }
-
-    static class EventWindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
-        private int mWindowId;
-
-        EventWindowIdMatcher(int windowId) {
-            super();
-            mWindowId = windowId;
-        }
-
-        static EventWindowIdMatcher eventWindowId(int windowId) {
-            return new EventWindowIdMatcher(windowId);
-        }
-
-        @Override
-        protected boolean matchesSafely(AccessibilityEvent event) {
-            return event.getWindowId() == mWindowId;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("Matching to windowId " + mWindowId);
-        }
-    }
-
-    static class WindowChangesMatcher extends TypeSafeMatcher<AccessibilityEvent> {
-        private int mWindowChanges;
-
-        WindowChangesMatcher(int windowChanges) {
-            super();
-            mWindowChanges = windowChanges;
-        }
-
-        static WindowChangesMatcher a11yWindowChanges(int windowChanges) {
-            return new WindowChangesMatcher(windowChanges);
-        }
-
-        @Override
-        protected boolean matchesSafely(AccessibilityEvent event) {
-            return event.getWindowChanges() == mWindowChanges;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("Matching to window changes " + mWindowChanges);
-        }
-    }
-
-    static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityWindowInfo> {
-        private final int mWindowId;
-
-        WindowIdMatcher(int windowId) {
-            super();
-            mWindowId = windowId;
-        }
-
-        static WindowIdMatcher windowId(int windowId) {
-            return new WindowIdMatcher(windowId);
-        }
-
-        @Override
-        protected boolean matchesSafely(AccessibilityWindowInfo window) {
-            return window.getId() == mWindowId;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("Matching to windowId " + mWindowId);
-        }
-    }
-}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e22d75e..ad5d42a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -19599,4 +19599,37 @@
             throw ex.rethrowAsRuntimeException();
         }
     }
+
+    /**
+     * Returns carrier id maps to the passing CarrierIdentifier.
+     * To recognize a carrier (including MVNO) as a first-class identity,
+     * Android assigns each carrier with a canonical integer a.k.a. carrier id.
+     * The carrier ID is an Android platform-wide identifier for a carrier.
+     * AOSP maintains carrier ID assignments in
+     * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
+     *
+     * @param carrierIdentifier {@link CarrierIdentifier}
+     *
+     * @return Carrier id. Return {@link #UNKNOWN_CARRIER_ID} if the carrier cannot be identified.
+     * @throws UnsupportedOperationException If the device does not have
+     *          {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_CARRIER_ID_FROM_CARRIER_IDENTIFIER)
+    @SystemApi
+    @WorkerThread
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public int getCarrierIdFromCarrierIdentifier(@NonNull CarrierIdentifier carrierIdentifier) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.getCarrierIdFromIdentifier(carrierIdentifier);
+            }
+        } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
+        }
+        return UNKNOWN_CARRIER_ID;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d22e9fa..294c93c 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -3519,4 +3519,15 @@
     * @hide
     */
     void setNtnSmsSupported(boolean ntnSmsSupported);
+
+    /**
+     * Returns carrier id maps to the passing {@link CarrierIdentifier}.
+     *
+     * @param {@link CarrierIdentifier}.
+     *
+     * @return carrier id from passing {@link CarrierIdentifier} or {@link #UNKNOWN_CARRIER_ID}
+     * if the carrier cannot be identified
+     * @hide
+     */
+    int getCarrierIdFromIdentifier(in CarrierIdentifier carrierIdentifier);
 }
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
index 6432827..e0900a6 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
@@ -23,6 +23,7 @@
 import android.graphics.Region
 import android.os.SystemClock
 import android.platform.uiautomatorhelpers.DeviceHelpers
+import android.tools.PlatformConsts
 import android.tools.device.apphelpers.IStandardAppHelper
 import android.tools.helpers.SYSTEMUI_PACKAGE
 import android.tools.traces.parsers.WindowManagerStateHelper
@@ -163,7 +164,10 @@
             .StateSyncBuilder()
             .withAppTransitionIdle()
             .apply {
-                if (isPip) withPipShown() else withWindowSurfaceDisappeared(innerHelper)
+                if (isPip) withPipShown()
+                else
+                    withWindowSurfaceDisappeared(innerHelper)
+                        .withActivityState(innerHelper, PlatformConsts.STATE_STOPPED)
             }
             .waitForAndVerify()
     }
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index fe974e3..af87bf7 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -1014,7 +1014,7 @@
             triggerFailureCount = 1;
         }
         for (int i = 0; i < triggerFailureCount; i++) {
-            watchdog.onPackageFailure(packages, failureReason);
+            watchdog.notifyPackageFailure(packages, failureReason);
         }
         mTestLooper.dispatchAll();
         if (Flags.recoverabilityDetection()) {
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index c25bed2..5a8a6be 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -392,7 +392,7 @@
 
         // Then fail APP_A below the threshold
         for (int i = 0; i < watchdog.getTriggerFailureCount() - 1; i++) {
-            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+            watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                     PackageWatchdog.FAILURE_REASON_UNKNOWN);
         }
 
@@ -1025,14 +1025,14 @@
         watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
         // Fail APP_A below the threshold which should not trigger package failures
         for (int i = 0; i < PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT - 1; i++) {
-            watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+            watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                     PackageWatchdog.FAILURE_REASON_UNKNOWN);
         }
         mTestLooper.dispatchAll();
         assertThat(observer.mHealthCheckFailedPackages).isEmpty();
 
         // One more to trigger the package failure
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
         assertThat(observer.mHealthCheckFailedPackages).containsExactly(APP_A);
@@ -1051,10 +1051,10 @@
         TestObserver observer = new TestObserver(OBSERVER_NAME_1);
 
         watchdog.startObservingHealth(observer, Arrays.asList(APP_A, APP_B), Long.MAX_VALUE);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS + 1);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
 
@@ -1062,10 +1062,10 @@
         // DEFAULT_TRIGGER_FAILURE_DURATION_MS.
         assertThat(observer.mHealthCheckFailedPackages).isEmpty();
 
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS - 1);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
 
@@ -1129,17 +1129,17 @@
 
         watchdog.startObservingHealth(observer, Arrays.asList(APP_A), Long.MAX_VALUE);
         // Raise 2 failures at t=0 and t=900 respectively
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         moveTimeForwardAndDispatch(900);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
 
         // Raise 2 failures at t=1100
         moveTimeForwardAndDispatch(200);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
-        watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
 
@@ -1433,13 +1433,13 @@
         TestObserver observer = new TestObserver(OBSERVER_NAME_1);
         watchdog.startObservingHealth(observer, List.of(APP_A), SHORT_DURATION);
         for (int i = 0; i < PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT - 1; i++) {
-            watchdog.onPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
+            watchdog.notifyPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
                     PackageWatchdog.FAILURE_REASON_UNKNOWN);
         }
         mTestLooper.dispatchAll();
         assertThat(observer.mMitigatedPackages).isEmpty();
         watchdog.startObservingHealth(observer, List.of(APP_A), LONG_DURATION);
-        watchdog.onPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
+        watchdog.notifyPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
                 PackageWatchdog.FAILURE_REASON_UNKNOWN);
         mTestLooper.dispatchAll();
         assertThat(observer.mMitigatedPackages).isEqualTo(List.of(APP_A));
@@ -1737,7 +1737,7 @@
             triggerFailureCount = 1;
         }
         for (int i = 0; i < triggerFailureCount; i++) {
-            watchdog.onPackageFailure(packages, failureReason);
+            watchdog.notifyPackageFailure(packages, failureReason);
         }
         mTestLooper.dispatchAll();
         if (Flags.recoverabilityDetection()) {