Merge "Fix a typo in AppFunctionManager constructor javadoc." into main
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 6454e73..121a9ae 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1797,11 +1797,15 @@
 
   public class InputSettings {
     method @FlaggedApi("com.android.hardware.input.keyboard_a11y_bounce_keys_flag") public static int getAccessibilityBounceKeysThreshold(@NonNull android.content.Context);
+    method @FlaggedApi("com.android.hardware.input.keyboard_repeat_keys") public static int getAccessibilityRepeatKeysDelay(@NonNull android.content.Context);
+    method @FlaggedApi("com.android.hardware.input.keyboard_repeat_keys") public static int getAccessibilityRepeatKeysTimeout(@NonNull android.content.Context);
     method @FlaggedApi("com.android.hardware.input.keyboard_a11y_slow_keys_flag") public static int getAccessibilitySlowKeysThreshold(@NonNull android.content.Context);
     method @FlaggedApi("com.android.hardware.input.keyboard_a11y_mouse_keys") public static boolean isAccessibilityMouseKeysEnabled(@NonNull android.content.Context);
     method @FlaggedApi("com.android.hardware.input.keyboard_a11y_sticky_keys_flag") public static boolean isAccessibilityStickyKeysEnabled(@NonNull android.content.Context);
     method @FlaggedApi("com.android.hardware.input.keyboard_a11y_bounce_keys_flag") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityBounceKeysThreshold(@NonNull android.content.Context, int);
     method @FlaggedApi("com.android.hardware.input.keyboard_a11y_mouse_keys") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityMouseKeysEnabled(@NonNull android.content.Context, boolean);
+    method @FlaggedApi("com.android.hardware.input.keyboard_repeat_keys") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityRepeatKeysDelay(@NonNull android.content.Context, int);
+    method @FlaggedApi("com.android.hardware.input.keyboard_repeat_keys") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityRepeatKeysTimeout(@NonNull android.content.Context, int);
     method @FlaggedApi("com.android.hardware.input.keyboard_a11y_slow_keys_flag") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilitySlowKeysThreshold(@NonNull android.content.Context, int);
     method @FlaggedApi("com.android.hardware.input.keyboard_a11y_sticky_keys_flag") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityStickyKeysEnabled(@NonNull android.content.Context, boolean);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static void setMaximumObscuringOpacityForTouch(@NonNull android.content.Context, @FloatRange(from=0, to=1) float);
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index c5d0caf22..8592ded 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -20,10 +20,12 @@
 import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_MOUSE_KEYS;
 import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SLOW_KEYS_FLAG;
 import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_STICKY_KEYS_FLAG;
+import static com.android.hardware.input.Flags.FLAG_KEYBOARD_REPEAT_KEYS;
 import static com.android.hardware.input.Flags.keyboardA11yBounceKeysFlag;
 import static com.android.hardware.input.Flags.keyboardA11ySlowKeysFlag;
 import static com.android.hardware.input.Flags.keyboardA11yStickyKeysFlag;
 import static com.android.hardware.input.Flags.keyboardA11yMouseKeys;
+import static com.android.hardware.input.Flags.keyboardRepeatKeys;
 import static com.android.hardware.input.Flags.touchpadTapDragging;
 import static com.android.hardware.input.Flags.touchpadVisualizer;
 import static com.android.input.flags.Flags.enableInputFilterRustImpl;
@@ -40,6 +42,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.sysprop.InputProperties;
+import android.view.ViewConfiguration;
 
 /**
  * InputSettings encapsulates reading and writing settings related to input
@@ -90,6 +93,30 @@
      */
     public static final int DEFAULT_STYLUS_POINTER_ICON_ENABLED = 1;
 
+    /**
+     * The minimum allowed repeat keys timeout before starting key repeats.
+     * @hide
+     */
+    public static final int MIN_KEY_REPEAT_TIMEOUT_MILLIS = 150;
+
+    /**
+     * The maximum allowed repeat keys timeout before starting key repeats.
+     * @hide
+     */
+    public static final int MAX_KEY_REPEAT_TIMEOUT_MILLIS = 2000;
+
+    /**
+     * The minimum allowed repeat keys delay between successive key repeats.
+     * @hide
+     */
+    public static final int MIN_KEY_REPEAT_DELAY_MILLIS = 20;
+
+    /**
+     * The maximum allowed repeat keys delay between successive key repeats.
+     * @hide
+     */
+    public static final int MAX_KEY_REPEAT_DELAY_MILLIS = 2000;
+
     private InputSettings() {
     }
 
@@ -767,4 +794,141 @@
                 Settings.Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED, enabled ? 1 : 0,
                 UserHandle.USER_CURRENT);
     }
+
+    /**
+     * Whether "Repeat keys" feature flag is enabled.
+     *
+     * <p>
+     * ‘Repeat keys’ is a feature which allows users to generate key repeats when a particular
+     * key on the physical keyboard is held down. This accessibility feature allows the user
+     * to configure the timeout before the key repeats begin as well as the delay
+     * between successive key repeats.
+     * </p>
+     *
+     * @hide
+     */
+    public static boolean isRepeatKeysFeatureFlagEnabled() {
+        return keyboardRepeatKeys();
+    }
+
+    /**
+     * Get Accessibility repeat keys timeout duration in milliseconds.
+     * The default key repeat timeout is {@link ViewConfiguration#DEFAULT_KEY_REPEAT_TIMEOUT_MS}.
+     *
+     * @param context The application context
+     * @return The time duration for which a key should be pressed after
+     *         which the pressed key will be repeated. The timeout must be between
+     *         {@link #MIN_KEY_REPEAT_TIMEOUT_MILLIS} and
+     *         {@link #MAX_KEY_REPEAT_TIMEOUT_MILLIS}
+     *
+     * <p>
+     * ‘Repeat keys’ is a feature which allows users to generate key repeats when a particular
+     * key on the physical keyboard is held down. This accessibility feature allows the user
+     * to configure the timeout before the key repeats begin as well as the delay
+     * between successive key repeats.
+     * </p>
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_KEYBOARD_REPEAT_KEYS)
+    public static int getAccessibilityRepeatKeysTimeout(@NonNull Context context) {
+        return Settings.Secure.getIntForUser(context.getContentResolver(),
+                Settings.Secure.KEY_REPEAT_TIMEOUT_MS, ViewConfiguration.getKeyRepeatTimeout(),
+                UserHandle.USER_CURRENT);
+    }
+
+    /**
+     * Get Accessibility repeat keys delay rate in milliseconds.
+     * The default key repeat delay is {@link ViewConfiguration#DEFAULT_KEY_REPEAT_DELAY_MS}.
+     *
+     * @param context The application context
+     * @return Time duration between successive key repeats when a key is
+     *         pressed down. The delay duration must be between
+     *         {@link #MIN_KEY_REPEAT_DELAY_MILLIS} and
+     *         {@link #MAX_KEY_REPEAT_DELAY_MILLIS}
+     *
+     * <p>
+     * ‘Repeat keys’ is a feature which allows users to generate key repeats when a particular
+     * key on the physical keyboard is held down. This accessibility feature allows the user
+     * to configure the timeout before the key repeats begin as well as the delay
+     * between successive key repeats.
+     * </p>
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_KEYBOARD_REPEAT_KEYS)
+    public static int getAccessibilityRepeatKeysDelay(@NonNull Context context) {
+        return Settings.Secure.getIntForUser(context.getContentResolver(),
+                Settings.Secure.KEY_REPEAT_DELAY_MS, ViewConfiguration.getKeyRepeatDelay(),
+                UserHandle.USER_CURRENT);
+    }
+
+    /**
+     * Set Accessibility repeat keys timeout duration in milliseconds.
+     *
+     * @param timeoutTimeMillis time duration for which a key should be pressed after which the
+     *                          pressed key will be repeated. The timeout must be between
+     *                          {@link #MIN_KEY_REPEAT_TIMEOUT_MILLIS} and
+     *                          {@link #MAX_KEY_REPEAT_TIMEOUT_MILLIS}
+     *
+     *  <p>
+     * ‘Repeat keys’ is a feature which allows users to generate key repeats when a particular
+     * key on the physical keyboard is held down. This accessibility feature allows the user
+     * to configure the timeout before the key repeats begin as well as the delay
+     *  between successive key repeats.
+     * </p>
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_KEYBOARD_REPEAT_KEYS)
+    @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
+    public static void setAccessibilityRepeatKeysTimeout(@NonNull Context context,
+            int timeoutTimeMillis) {
+        if (timeoutTimeMillis < MIN_KEY_REPEAT_TIMEOUT_MILLIS
+                || timeoutTimeMillis > MAX_KEY_REPEAT_TIMEOUT_MILLIS) {
+            throw new IllegalArgumentException(
+                    "Provided repeat keys timeout should be in range ("
+                            + MIN_KEY_REPEAT_TIMEOUT_MILLIS + ","
+                            + MAX_KEY_REPEAT_TIMEOUT_MILLIS + ")");
+        }
+        Settings.Secure.putIntForUser(context.getContentResolver(),
+                Settings.Secure.KEY_REPEAT_TIMEOUT_MS, timeoutTimeMillis,
+                UserHandle.USER_CURRENT);
+    }
+
+    /**
+     * Set Accessibility repeat key delay duration in milliseconds.
+     *
+     * @param delayTimeMillis Time duration between successive key repeats when a key is
+     *                        pressed down. The delay duration must be between
+     *                        {@link #MIN_KEY_REPEAT_DELAY_MILLIS} and
+     *                        {@link #MAX_KEY_REPEAT_DELAY_MILLIS}
+     * <p>
+     * ‘Repeat keys’ is a feature which allows users to generate key repeats when a particular
+     * key on the physical keyboard is held down. This accessibility feature allows the user
+     * to configure the timeout before the key repeats begin as well as the delay
+     * between successive key repeats.
+     * </p>
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(FLAG_KEYBOARD_REPEAT_KEYS)
+    @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
+    public static void setAccessibilityRepeatKeysDelay(@NonNull Context context,
+            int delayTimeMillis) {
+        if (delayTimeMillis < MIN_KEY_REPEAT_DELAY_MILLIS
+                || delayTimeMillis > MAX_KEY_REPEAT_DELAY_MILLIS) {
+            throw new IllegalArgumentException(
+                    "Provided repeat keys delay should be in range ("
+                            + MIN_KEY_REPEAT_DELAY_MILLIS + ","
+                            + MAX_KEY_REPEAT_DELAY_MILLIS + ")");
+        }
+        Settings.Secure.putIntForUser(context.getContentResolver(),
+                Settings.Secure.KEY_REPEAT_DELAY_MS, delayTimeMillis,
+                UserHandle.USER_CURRENT);
+    }
 }
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index 83c4de3..077bd82 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -99,3 +99,10 @@
   description: "Refactor ModifierShortcutManager internal representation of shortcuts."
   bug: "358603902"
 }
+
+flag {
+  name: "keyboard_repeat_keys"
+  namespace: "input"
+  description: "Allow configurable timeout before key repeat and repeat delay rate for key repeats"
+  bug: "336585002"
+}
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index b338a2a..a79bc97 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -39,17 +39,6 @@
     path: "src",
 }
 
-// Sources that have no dependencies that can be used directly downstream of this library
-// TODO(b/322791067): move these sources to WindowManager-Shell-shared
-filegroup {
-    name: "wm_shell_util-sources",
-    srcs: [
-        "src/com/android/wm/shell/common/bubbles/*.kt",
-        "src/com/android/wm/shell/common/bubbles/*.java",
-    ],
-    path: "src",
-}
-
 // Aidls which can be used directly downstream of this library
 filegroup {
     name: "wm_shell-aidls",
@@ -184,9 +173,11 @@
         ":wm_shell-shared-aidls",
     ],
     static_libs: [
+        "androidx.core_core-animation",
         "androidx.dynamicanimation_dynamicanimation",
         "jsr330",
     ],
+    kotlincflags: ["-Xjvm-default=all"],
 }
 
 java_library {
@@ -212,7 +203,6 @@
     ],
     static_libs: [
         "androidx.appcompat_appcompat",
-        "androidx.core_core-animation",
         "androidx.core_core-ktx",
         "androidx.arch.core_core-runtime",
         "androidx.datastore_datastore",
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/bubbles/BubbleEducationViewScreenshotTest.kt b/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/bubbles/BubbleEducationViewScreenshotTest.kt
index d35f493..f09969d 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/bubbles/BubbleEducationViewScreenshotTest.kt
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/bubbles/BubbleEducationViewScreenshotTest.kt
@@ -16,7 +16,7 @@
 package com.android.wm.shell.bubbles
 
 import android.view.LayoutInflater
-import com.android.wm.shell.common.bubbles.BubblePopupView
+import com.android.wm.shell.shared.bubbles.BubblePopupView
 import com.android.wm.shell.testing.goldenpathmanager.WMShellGoldenPathManager
 import com.android.wm.shell.R
 import org.junit.Rule
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
index 4b97451..b38d00da 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
@@ -30,7 +30,7 @@
 import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.R
 import com.android.wm.shell.bubbles.BubblePositioner.MAX_HEIGHT
-import com.android.wm.shell.common.bubbles.BubbleBarLocation
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
 import com.google.common.truth.Truth.assertThat
 import com.google.common.util.concurrent.MoreExecutors.directExecutor
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
index faadf1d..96ffa03 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
@@ -53,7 +53,7 @@
 import org.mockito.kotlin.mock
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
-import com.android.wm.shell.common.bubbles.BubbleBarLocation
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
 import java.util.concurrent.Semaphore
 import java.util.concurrent.TimeUnit
 import java.util.function.Consumer
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
index 935d129..ecb2b25 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
@@ -31,12 +31,12 @@
 import com.android.wm.shell.R
 import com.android.wm.shell.bubbles.BubblePositioner
 import com.android.wm.shell.bubbles.DeviceConfig
-import com.android.wm.shell.common.bubbles.BaseBubblePinController
-import com.android.wm.shell.common.bubbles.BaseBubblePinController.Companion.DROP_TARGET_ALPHA_IN_DURATION
-import com.android.wm.shell.common.bubbles.BaseBubblePinController.Companion.DROP_TARGET_ALPHA_OUT_DURATION
-import com.android.wm.shell.common.bubbles.BubbleBarLocation
-import com.android.wm.shell.common.bubbles.BubbleBarLocation.LEFT
-import com.android.wm.shell.common.bubbles.BubbleBarLocation.RIGHT
+import com.android.wm.shell.shared.bubbles.BaseBubblePinController
+import com.android.wm.shell.shared.bubbles.BaseBubblePinController.Companion.DROP_TARGET_ALPHA_IN_DURATION
+import com.android.wm.shell.shared.bubbles.BaseBubblePinController.Companion.DROP_TARGET_ALPHA_OUT_DURATION
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation.LEFT
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation.RIGHT
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
index a0a06f1..806d026 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<com.android.wm.shell.common.bubbles.BubblePopupView
+<com.android.wm.shell.shared.bubbles.BubblePopupView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
@@ -53,4 +53,4 @@
         android:textAlignment="center"
         android:text="@string/bubble_bar_education_manage_text"/>
 
-</com.android.wm.shell.common.bubbles.BubblePopupView>
\ No newline at end of file
+</com.android.wm.shell.shared.bubbles.BubblePopupView>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
index b489a5c..7fa586c 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<com.android.wm.shell.common.bubbles.BubblePopupView
+<com.android.wm.shell.shared.bubbles.BubblePopupView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
@@ -53,4 +53,4 @@
         android:textAlignment="center"
         android:text="@string/bubble_bar_education_stack_text"/>
 
-</com.android.wm.shell.common.bubbles.BubblePopupView>
\ No newline at end of file
+</com.android.wm.shell.shared.bubbles.BubblePopupView>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BaseBubblePinController.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BaseBubblePinController.kt
similarity index 96%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BaseBubblePinController.kt
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BaseBubblePinController.kt
index eec2468..7086691 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BaseBubblePinController.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BaseBubblePinController.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles
+package com.android.wm.shell.shared.bubbles
 
 import android.graphics.Point
 import android.graphics.RectF
@@ -23,9 +23,9 @@
 import androidx.core.animation.Animator
 import androidx.core.animation.AnimatorListenerAdapter
 import androidx.core.animation.ObjectAnimator
-import com.android.wm.shell.common.bubbles.BaseBubblePinController.LocationChangeListener
-import com.android.wm.shell.common.bubbles.BubbleBarLocation.LEFT
-import com.android.wm.shell.common.bubbles.BubbleBarLocation.RIGHT
+import com.android.wm.shell.shared.bubbles.BaseBubblePinController.LocationChangeListener
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation.LEFT
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation.RIGHT
 
 /**
  * Base class for common logic shared between different bubble views to support pinning bubble bar
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.aidl b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarLocation.aidl
similarity index 93%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.aidl
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarLocation.aidl
index 3c5beeb..4fe7611 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.aidl
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarLocation.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles;
+package com.android.wm.shell.shared.bubbles;
 
 parcelable BubbleBarLocation;
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarLocation.kt
similarity index 97%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.kt
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarLocation.kt
index f0bdfde..191875d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarLocation.kt
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.wm.shell.common.bubbles
+package com.android.wm.shell.shared.bubbles
 
 import android.os.Parcel
 import android.os.Parcelable
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarUpdate.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarUpdate.java
similarity index 98%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarUpdate.java
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarUpdate.java
index ec3c601..5bde1e8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarUpdate.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarUpdate.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles;
+package com.android.wm.shell.shared.bubbles;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleConstants.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleConstants.java
similarity index 89%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleConstants.java
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleConstants.java
index 0329b8d..3396bc4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleConstants.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleConstants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles;
+package com.android.wm.shell.shared.bubbles;
 
 /**
  * Constants shared between bubbles in shell & things we have to do for bubbles in launcher.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleInfo.java
similarity index 97%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleInfo.java
index e873cbd..5876682 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles;
+package com.android.wm.shell.shared.bubbles;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupDrawable.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubblePopupDrawable.kt
similarity index 98%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupDrawable.kt
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubblePopupDrawable.kt
index 887af17..8681acf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupDrawable.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubblePopupDrawable.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.wm.shell.common.bubbles
+package com.android.wm.shell.shared.bubbles
 
 import android.annotation.ColorInt
 import android.graphics.Canvas
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupView.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubblePopupView.kt
similarity index 95%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupView.kt
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubblePopupView.kt
index 444fbf7..802d7d1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubblePopupView.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubblePopupView.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.wm.shell.common.bubbles
+package com.android.wm.shell.shared.bubbles
 
 import android.content.Context
 import android.graphics.Rect
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/DismissCircleView.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DismissCircleView.java
similarity index 96%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/DismissCircleView.java
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DismissCircleView.java
index 7c5bb21..0c05156 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/DismissCircleView.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DismissCircleView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles;
+package com.android.wm.shell.shared.bubbles;
 
 import android.content.Context;
 import android.content.res.Configuration;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/DismissView.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DismissView.kt
similarity index 98%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/DismissView.kt
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DismissView.kt
index e06de9e..2bb66b0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/DismissView.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DismissView.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles
+package com.android.wm.shell.shared.bubbles
 
 import android.animation.ObjectAnimator
 import android.content.Context
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/OWNERS b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/OWNERS
similarity index 100%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/OWNERS
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/OWNERS
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/RelativeTouchListener.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/RelativeTouchListener.kt
similarity index 98%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/RelativeTouchListener.kt
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/RelativeTouchListener.kt
index 4e55ba2..b1f4e33 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/RelativeTouchListener.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/RelativeTouchListener.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles
+package com.android.wm.shell.shared.bubbles
 
 import android.graphics.PointF
 import android.view.MotionEvent
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/RemovedBubble.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/RemovedBubble.java
similarity index 94%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/RemovedBubble.java
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/RemovedBubble.java
index f90591b..c83696c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/RemovedBubble.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/RemovedBubble.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles;
+package com.android.wm.shell.shared.bubbles;
 
 import android.annotation.NonNull;
 import android.os.Parcel;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 4622dcf..0c95934 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -53,9 +53,9 @@
 import com.android.wm.shell.Flags;
 import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView;
 import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
-import com.android.wm.shell.common.bubbles.BubbleInfo;
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.shared.bubbles.BubbleInfo;
 
 import java.io.PrintWriter;
 import java.util.List;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index b508c1b..c545d73 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -104,14 +104,14 @@
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TaskStackListenerCallback;
 import com.android.wm.shell.common.TaskStackListenerImpl;
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
-import com.android.wm.shell.common.bubbles.BubbleBarUpdate;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.onehanded.OneHandedController;
 import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
 import com.android.wm.shell.pip.PinnedStackListenerForwarder;
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.BubbleBarUpdate;
 import com.android.wm.shell.sysui.ConfigurationChangeListener;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
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 4ad1802..709a7bd 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
@@ -41,10 +41,10 @@
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.bubbles.Bubbles.DismissReason;
-import com.android.wm.shell.common.bubbles.BubbleBarUpdate;
-import com.android.wm.shell.common.bubbles.RemovedBubble;
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.shared.bubbles.BubbleBarUpdate;
+import com.android.wm.shell.shared.bubbles.RemovedBubble;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
index 4e80e90..ec4854b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
@@ -16,7 +16,7 @@
 
 package com.android.wm.shell.bubbles
 
-import com.android.wm.shell.common.bubbles.BubbleBarLocation
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
 
 /** Manager interface for bubble expanded views. */
 interface BubbleExpandedViewManager {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
index bdb09e1..fd110a276 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
@@ -17,8 +17,8 @@
 
 import android.graphics.Color
 import com.android.wm.shell.R
-import com.android.wm.shell.common.bubbles.BubblePopupDrawable
-import com.android.wm.shell.common.bubbles.BubblePopupView
+import com.android.wm.shell.shared.bubbles.BubblePopupDrawable
+import com.android.wm.shell.shared.bubbles.BubblePopupView
 
 /**
  * A convenience method to setup the [BubblePopupView] with the correct config using local resources
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 0cf187b..c386c93 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -32,7 +32,7 @@
 import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconNormalizer;
 import com.android.wm.shell.R;
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
 
 /**
  * Keeps track of display size, configuration, and specific bubble sizes. One place for all
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 53bbf88..2795881 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -24,10 +24,10 @@
 import static com.android.wm.shell.bubbles.BubblePositioner.NUM_VISIBLE_WHEN_RESTING;
 import static com.android.wm.shell.bubbles.BubblePositioner.StackPinnedEdge.LEFT;
 import static com.android.wm.shell.bubbles.BubblePositioner.StackPinnedEdge.RIGHT;
-import static com.android.wm.shell.common.bubbles.BubbleConstants.BUBBLE_EXPANDED_SCRIM_ALPHA;
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES;
 import static com.android.wm.shell.shared.animation.Interpolators.ALPHA_IN;
 import static com.android.wm.shell.shared.animation.Interpolators.ALPHA_OUT;
+import static com.android.wm.shell.shared.bubbles.BubbleConstants.BUBBLE_EXPANDED_SCRIM_ALPHA;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -91,8 +91,8 @@
 import com.android.wm.shell.bubbles.animation.StackAnimationController;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.bubbles.DismissView;
-import com.android.wm.shell.common.bubbles.RelativeTouchListener;
+import com.android.wm.shell.shared.bubbles.DismissView;
+import com.android.wm.shell.shared.bubbles.RelativeTouchListener;
 import com.android.wm.shell.shared.animation.Interpolators;
 import com.android.wm.shell.shared.animation.PhysicsAnimator;
 import com.android.wm.shell.shared.magnetictarget.MagnetizedObject;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 9a27fb6..62895fe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -38,9 +38,9 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
 
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
-import com.android.wm.shell.common.bubbles.BubbleBarUpdate;
 import com.android.wm.shell.shared.annotations.ExternalThread;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.BubbleBarUpdate;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissViewExt.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissViewExt.kt
index 48692d4..00a8172 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissViewExt.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissViewExt.kt
@@ -18,7 +18,7 @@
 package com.android.wm.shell.bubbles
 
 import com.android.wm.shell.R
-import com.android.wm.shell.common.bubbles.DismissView
+import com.android.wm.shell.shared.bubbles.DismissView
 
 fun DismissView.setup() {
     setup(DismissView.Config(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
index 5779a8f..1855b93 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
@@ -20,7 +20,7 @@
 import android.graphics.Rect;
 import android.content.pm.ShortcutInfo;
 import com.android.wm.shell.bubbles.IBubblesListener;
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
 
 /**
  * Interface that is exposed to remote callers (launcher) to manipulate the bubbles feature when
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubblesListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubblesListener.aidl
index 14d29cd..eb907db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubblesListener.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubblesListener.aidl
@@ -17,7 +17,7 @@
 package com.android.wm.shell.bubbles;
 
 import android.os.Bundle;
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
 /**
  * Listener interface that Launcher attaches to SystemUI to get bubbles callbacks.
  */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 6d868d2..694b1b0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -46,7 +46,7 @@
 import com.android.wm.shell.bubbles.BubbleTaskView;
 import com.android.wm.shell.bubbles.BubbleTaskViewHelper;
 import com.android.wm.shell.bubbles.Bubbles;
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
 import com.android.wm.shell.taskview.TaskView;
 
 import java.util.function.Supplier;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
index eeb5c94..07463bb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
@@ -20,8 +20,8 @@
 import android.view.MotionEvent
 import android.view.View
 import com.android.wm.shell.bubbles.BubblePositioner
-import com.android.wm.shell.common.bubbles.DismissView
-import com.android.wm.shell.common.bubbles.RelativeTouchListener
+import com.android.wm.shell.shared.bubbles.DismissView
+import com.android.wm.shell.shared.bubbles.RelativeTouchListener
 import com.android.wm.shell.shared.magnetictarget.MagnetizedObject
 
 /** Controller for handling drag interactions with [BubbleBarExpandedView] */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index ac42453..1c9c195 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -44,9 +44,9 @@
 import com.android.wm.shell.bubbles.DeviceConfig;
 import com.android.wm.shell.bubbles.DismissViewUtils;
 import com.android.wm.shell.bubbles.bar.BubbleBarExpandedViewDragController.DragListener;
-import com.android.wm.shell.common.bubbles.BaseBubblePinController;
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
-import com.android.wm.shell.common.bubbles.DismissView;
+import com.android.wm.shell.shared.bubbles.BaseBubblePinController;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.DismissView;
 
 import kotlin.Unit;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt
index e108f7b..9fd255d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt
@@ -34,9 +34,9 @@
 import com.android.wm.shell.bubbles.BubbleEducationController
 import com.android.wm.shell.bubbles.BubbleViewProvider
 import com.android.wm.shell.bubbles.setup
-import com.android.wm.shell.common.bubbles.BubblePopupDrawable
-import com.android.wm.shell.common.bubbles.BubblePopupView
 import com.android.wm.shell.shared.animation.PhysicsAnimator
+import com.android.wm.shell.shared.bubbles.BubblePopupDrawable
+import com.android.wm.shell.shared.bubbles.BubblePopupView
 import kotlin.math.roundToInt
 
 /** Manages bubble education presentation and animation */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinController.kt
index 651bf02..23ba2bf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinController.kt
@@ -25,8 +25,8 @@
 import androidx.core.view.updateLayoutParams
 import com.android.wm.shell.R
 import com.android.wm.shell.bubbles.BubblePositioner
-import com.android.wm.shell.common.bubbles.BaseBubblePinController
-import com.android.wm.shell.common.bubbles.BubbleBarLocation
+import com.android.wm.shell.shared.bubbles.BaseBubblePinController
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
 
 /**
  * Controller to manage pinning bubble bar to left or right when dragging starts from the bubble bar
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
index 0acc7df..faa97ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
@@ -98,9 +98,8 @@
 ### Exposing shared code for use in Launcher
 Launcher doesn't currently build against the Shell library, but needs to have access to some shared
 AIDL interfaces and constants.  Currently, all AIDL files, and classes under the
-`com.android.wm.shell.util` package are automatically built into the `SystemUISharedLib` that
+`com.android.wm.shell.shared` package are automatically built into the `SystemUISharedLib` that
 Launcher uses.
 
-If the new code doesn't fall into those categories, they can be added explicitly in the Shell's
-[Android.bp](/libs/WindowManager/Shell/Android.bp) file under the
-`wm_shell_util-sources` filegroup.
\ No newline at end of file
+If the new code doesn't fall into those categories, they should be moved to the Shell shared
+package (`com.android.wm.shell.shared`) under the `WindowManager-Shell-shared` library.
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
index 0d2b8e7..06d2311 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
@@ -35,9 +35,9 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.bubbles.DismissViewUtils;
 import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.bubbles.DismissCircleView;
-import com.android.wm.shell.common.bubbles.DismissView;
 import com.android.wm.shell.common.pip.PipUiEventLogger;
+import com.android.wm.shell.shared.bubbles.DismissCircleView;
+import com.android.wm.shell.shared.bubbles.DismissView;
 import com.android.wm.shell.shared.magnetictarget.MagnetizedObject;
 
 import kotlin.Unit;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java
index e04178e..b3070f2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java
@@ -35,9 +35,9 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.bubbles.DismissViewUtils;
 import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.bubbles.DismissCircleView;
-import com.android.wm.shell.common.bubbles.DismissView;
 import com.android.wm.shell.common.pip.PipUiEventLogger;
+import com.android.wm.shell.shared.bubbles.DismissCircleView;
+import com.android.wm.shell.shared.bubbles.DismissView;
 import com.android.wm.shell.shared.magnetictarget.MagnetizedObject;
 
 import kotlin.Unit;
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
index 507ad64..880e021 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
@@ -153,6 +153,22 @@
                 assertions = AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS
             )
 
+        val EDGE_RESIZE =
+            FlickerConfigEntry(
+                scenarioId = ScenarioId("EDGE_RESIZE"),
+                extractor =
+                TaggedScenarioExtractorBuilder()
+                    .setTargetTag(CujType.CUJ_DESKTOP_MODE_RESIZE_WINDOW)
+                    .setTransitionMatcher(
+                        TaggedCujTransitionMatcher(associatedTransitionRequired = false)
+                    )
+                    .build(),
+                assertions = AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS +
+                        listOf(
+                            AppLayerIncreasesInSize(DESKTOP_MODE_APP),
+                        ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
+            )
+
         val CORNER_RESIZE_TO_MINIMUM_SIZE =
             FlickerConfigEntry(
                 scenarioId = ScenarioId("CORNER_RESIZE_TO_MINIMUM_SIZE"),
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithEdgeResizeMouse.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithEdgeResizeMouse.kt
new file mode 100644
index 0000000..c3abf23
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithEdgeResizeMouse.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.helpers.MotionEventHelper.InputMethod
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.EDGE_RESIZE
+import com.android.wm.shell.scenarios.ResizeAppWithEdgeResize
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class ResizeAppWithEdgeResizeMouse : ResizeAppWithEdgeResize(InputMethod.MOUSE) {
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeRight() = super.resizeAppWithEdgeResizeRight()
+
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeLeft() = super.resizeAppWithEdgeResizeLeft()
+
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeTop() = super.resizeAppWithEdgeResizeTop()
+
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeBottom() = super.resizeAppWithEdgeResizeBottom()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(EDGE_RESIZE)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithEdgeResizeStylus.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithEdgeResizeStylus.kt
new file mode 100644
index 0000000..86b0e6f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithEdgeResizeStylus.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.helpers.MotionEventHelper.InputMethod
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.EDGE_RESIZE
+import com.android.wm.shell.scenarios.ResizeAppWithEdgeResize
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class ResizeAppWithEdgeResizeStylus : ResizeAppWithEdgeResize(InputMethod.STYLUS) {
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeRight() = super.resizeAppWithEdgeResizeRight()
+
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeLeft() = super.resizeAppWithEdgeResizeLeft()
+
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeTop() = super.resizeAppWithEdgeResizeTop()
+
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeBottom() = super.resizeAppWithEdgeResizeBottom()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(EDGE_RESIZE)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithEdgeResizeTouchpad.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithEdgeResizeTouchpad.kt
new file mode 100644
index 0000000..e6bb9ef
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithEdgeResizeTouchpad.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.server.wm.flicker.helpers.MotionEventHelper.InputMethod
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.EDGE_RESIZE
+import com.android.wm.shell.scenarios.ResizeAppWithEdgeResize
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class ResizeAppWithEdgeResizeTouchpad : ResizeAppWithEdgeResize(InputMethod.TOUCHPAD) {
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeRight() = super.resizeAppWithEdgeResizeRight()
+
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeLeft() = super.resizeAppWithEdgeResizeLeft()
+
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeTop() = super.resizeAppWithEdgeResizeTop()
+
+    @ExpectedScenarios(["EDGE_RESIZE"])
+    @Test
+    override fun resizeAppWithEdgeResizeBottom() = super.resizeAppWithEdgeResizeBottom()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(EDGE_RESIZE)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppWithEdgeResize.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppWithEdgeResize.kt
new file mode 100644
index 0000000..d094967
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppWithEdgeResize.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.platform.test.annotations.Postsubmit
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.MotionEventHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class ResizeAppWithEdgeResize
+@JvmOverloads
+constructor(
+    val inputMethod: MotionEventHelper.InputMethod,
+    val rotation: Rotation = Rotation.ROTATION_90
+) {
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val device = UiDevice.getInstance(instrumentation)
+    private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+    private val motionEventHelper = MotionEventHelper(instrumentation, inputMethod)
+
+    @Rule
+    @JvmField
+    val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+    @Before
+    fun setup() {
+        Assume.assumeTrue(
+            Flags.enableDesktopWindowingMode()
+                    && Flags.enableWindowingEdgeDragResize() && tapl.isTablet
+        )
+        tapl.setEnableRotation(true)
+        tapl.setExpectedRotation(rotation.value)
+        testApp.enterDesktopWithDrag(wmHelper, device)
+    }
+
+    @Test
+    open fun resizeAppWithEdgeResizeRight() {
+        testApp.edgeResize(
+            wmHelper,
+            motionEventHelper,
+            DesktopModeAppHelper.Edges.RIGHT
+        )
+    }
+
+    @Test
+    open fun resizeAppWithEdgeResizeLeft() {
+        testApp.edgeResize(
+            wmHelper,
+            motionEventHelper,
+            DesktopModeAppHelper.Edges.LEFT
+        )
+    }
+
+    @Test
+    open fun resizeAppWithEdgeResizeTop() {
+        testApp.edgeResize(
+            wmHelper,
+            motionEventHelper,
+            DesktopModeAppHelper.Edges.TOP
+        )
+    }
+
+    @Test
+    open fun resizeAppWithEdgeResizeBottom() {
+        testApp.edgeResize(
+            wmHelper,
+            motionEventHelper,
+            DesktopModeAppHelper.Edges.BOTTOM
+        )
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 859602e..6fa3788 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -50,8 +50,8 @@
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.bubbles.BubbleData.TimeSource;
 import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
-import com.android.wm.shell.common.bubbles.BubbleBarUpdate;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.BubbleBarUpdate;
 
 import com.google.common.collect.ImmutableList;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
index 50c4a18..dca5fc4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
@@ -43,7 +43,7 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.bubbles.BubbleInfo;
+import com.android.wm.shell.shared.bubbles.BubbleInfo;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleBarLocationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleBarLocationTest.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleBarLocationTest.kt
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleBarLocationTest.kt
index 27e0b19..b9bf95b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleBarLocationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleBarLocationTest.kt
@@ -13,14 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.wm.shell.common.bubbles
+package com.android.wm.shell.shared.bubbles
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.common.bubbles.BubbleBarLocation.DEFAULT
-import com.android.wm.shell.common.bubbles.BubbleBarLocation.LEFT
-import com.android.wm.shell.common.bubbles.BubbleBarLocation.RIGHT
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation.DEFAULT
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation.LEFT
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation.RIGHT
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleInfoTest.kt
similarity index 97%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleInfoTest.kt
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleInfoTest.kt
index 6695a1e..641063c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/BubbleInfoTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.common.bubbles
+package com.android.wm.shell.shared.bubbles
 
 import android.os.Parcel
 import android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
index d7acaaf..80de087 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
@@ -33,7 +33,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.utils.TestUtils;
 import com.android.systemui.util.settings.SecureSettings;
-import com.android.wm.shell.common.bubbles.DismissView;
+import com.android.wm.shell.shared.bubbles.DismissView;
 import com.android.wm.shell.shared.magnetictarget.MagnetizedObject;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
index 4373c88..46f076a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
@@ -46,7 +46,7 @@
 import com.android.systemui.accessibility.MotionEventHelper;
 import com.android.systemui.accessibility.utils.TestUtils;
 import com.android.systemui.util.settings.SecureSettings;
-import com.android.wm.shell.common.bubbles.DismissView;
+import com.android.wm.shell.shared.bubbles.DismissView;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index e68da09..8f55961 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -49,7 +49,6 @@
         "src/**/*.aidl",
         ":wm_shell-aidls",
         ":wm_shell-shared-aidls",
-        ":wm_shell_util-sources",
     ],
     static_libs: [
         "BiometricsSharedLib",
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationController.java
index d718ae3..708f7f1 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationController.java
@@ -30,8 +30,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Flags;
-import com.android.wm.shell.common.bubbles.DismissCircleView;
-import com.android.wm.shell.common.bubbles.DismissView;
+import com.android.wm.shell.shared.bubbles.DismissCircleView;
+import com.android.wm.shell.shared.bubbles.DismissView;
 import com.android.wm.shell.shared.magnetictarget.MagnetizedObject;
 
 import java.util.Map;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractView.kt b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractView.kt
index c1b3962..13c1a45 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractView.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DragToInteractView.kt
@@ -39,9 +39,9 @@
 import androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY
 import androidx.dynamicanimation.animation.SpringForce.STIFFNESS_LOW
 import com.android.wm.shell.R
-import com.android.wm.shell.common.bubbles.DismissCircleView
-import com.android.wm.shell.common.bubbles.DismissView
 import com.android.wm.shell.shared.animation.PhysicsAnimator
+import com.android.wm.shell.shared.bubbles.DismissCircleView
+import com.android.wm.shell.shared.bubbles.DismissView
 
 /**
  * View that handles interactions between DismissCircleView and BubbleStackView.
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index d62162b..7a674e2 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -81,7 +81,7 @@
 import com.android.systemui.res.R;
 import com.android.systemui.util.settings.SecureSettings;
 import com.android.wm.shell.bubbles.DismissViewUtils;
-import com.android.wm.shell.common.bubbles.DismissView;
+import com.android.wm.shell.shared.bubbles.DismissView;
 import com.android.wm.shell.shared.magnetictarget.MagnetizedObject;
 
 import java.lang.annotation.Retention;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 6e39365..3e7980d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -184,11 +184,11 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TaskStackListenerImpl;
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
-import com.android.wm.shell.common.bubbles.BubbleBarUpdate;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.onehanded.OneHandedController;
 import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.BubbleBarUpdate;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
diff --git a/services/core/java/com/android/server/power/WakeLockLog.java b/services/core/java/com/android/server/power/WakeLockLog.java
index 968ff59..eda222e 100644
--- a/services/core/java/com/android/server/power/WakeLockLog.java
+++ b/services/core/java/com/android/server/power/WakeLockLog.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.PowerManager;
+import android.os.Process;
 import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -122,6 +123,9 @@
 
     private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
 
+    @VisibleForTesting
+    static final String SYSTEM_PACKAGE_NAME = "System";
+
     /**
      * Lock protects WakeLockLog.dump (binder thread) from conflicting with changes to the log
      * happening on the background thread.
@@ -516,21 +520,26 @@
                 return;
             }
 
-            String[] packages;
-            if (uidToPackagesCache.contains(tag.ownerUid)) {
-                packages = uidToPackagesCache.get(tag.ownerUid);
-            } else {
-                packages = packageManager.getPackagesForUid(tag.ownerUid);
-                uidToPackagesCache.put(tag.ownerUid, packages);
+            if (tag.ownerUid == Process.SYSTEM_UID) {
+                packageName = SYSTEM_PACKAGE_NAME;
             }
+            else {
+                String[] packages;
+                if (uidToPackagesCache.contains(tag.ownerUid)) {
+                    packages = uidToPackagesCache.get(tag.ownerUid);
+                } else {
+                    packages = packageManager.getPackagesForUid(tag.ownerUid);
+                    uidToPackagesCache.put(tag.ownerUid, packages);
+                }
 
-            if (packages != null && packages.length > 0) {
-                packageName = packages[0];
-                if (packages.length > 1) {
-                    StringBuilder sb = new StringBuilder();
-                    sb.append(packageName)
-                            .append(",...");
-                    packageName = sb.toString();
+                if (packages != null && packages.length > 0) {
+                    packageName = packages[0];
+                    if (packages.length > 1) {
+                        StringBuilder sb = new StringBuilder();
+                        sb.append(packageName)
+                                .append(",...");
+                        packageName = sb.toString();
+                    }
                 }
             }
         }
diff --git a/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java b/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java
index 1c4db6a..c1d7c7b 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java
@@ -25,6 +25,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.PowerManager;
+import android.os.Process;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -54,6 +55,8 @@
 
         when(mPackageManager.getPackagesForUid(101)).thenReturn(new String[]{ "some.package1" });
         when(mPackageManager.getPackagesForUid(102)).thenReturn(new String[]{ "some.package2" });
+        when(mPackageManager.getPackagesForUid(Process.SYSTEM_UID))
+                .thenReturn(new String[]{ "some.package3" });
     }
 
     @Test
@@ -70,14 +73,20 @@
         log.onWakeLockAcquired("TagFull", 102,
                 PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, -1);
 
+        when(injectorSpy.currentTimeMillis()).thenReturn(1250L);
+        log.onWakeLockAcquired("TagSystem", 1000,
+                PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, -1);
+
         assertEquals("Wake Lock Log\n"
                         + "  01-01 00:00:01.000 - 101 (some.package1) - ACQ TagPartial "
                         + "(partial,on-after-release)\n"
                         + "  01-01 00:00:01.150 - 102 (some.package2) - ACQ TagFull "
                         + "(full,acq-causes-wake)\n"
+                        + "  01-01 00:00:01.250 - 1000 (" + WakeLockLog.SYSTEM_PACKAGE_NAME + ")"
+                        + " - ACQ TagSystem (full,acq-causes-wake)\n"
                         + "  -\n"
-                        + "  Events: 2, Time-Resets: 0\n"
-                        + "  Buffer, Bytes used: 6\n",
+                        + "  Events: 3, Time-Resets: 0\n"
+                        + "  Buffer, Bytes used: 9\n",
                 dumpLog(log, false));
     }
 
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 753cb1f..3f6a0bf 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
@@ -48,6 +48,13 @@
         RIGHT_BOTTOM
     }
 
+    enum class Edges {
+        LEFT,
+        RIGHT,
+        TOP,
+        BOTTOM
+    }
+
     /** Wait for an app moved to desktop to finish its transition. */
     private fun waitForAppToMoveToDesktop(wmHelper: WindowManagerStateHelper) {
         wmHelper
@@ -124,7 +131,8 @@
 
         val displayRect = getDisplayRect(wmHelper)
         val insets = getWindowInsets(
-            context, WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
+            context, WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars()
+        )
         displayRect.inset(insets)
 
         val expectedWidth = displayRect.width() / 2
@@ -187,6 +195,40 @@
         dragWindow(startX, startY, endX, endY, wmHelper, device)
     }
 
+    /** Resize a desktop app from its edges. */
+    fun edgeResize(
+        wmHelper: WindowManagerStateHelper,
+        motionEvent: MotionEventHelper,
+        edge: Edges
+    ) {
+        val windowRect = wmHelper.getWindowRegion(innerHelper).bounds
+        val (startX, startY) = getStartCoordinatesForEdgeResize(windowRect, edge)
+        val verticalChange = when (edge) {
+            Edges.LEFT -> 0
+            Edges.RIGHT -> 0
+            Edges.TOP -> -100
+            Edges.BOTTOM -> 100
+        }
+        val horizontalChange = when (edge) {
+            Edges.LEFT -> -100
+            Edges.RIGHT -> 100
+            Edges.TOP -> 0
+            Edges.BOTTOM -> 0
+        }
+
+        // The position we want to drag to
+        val endY = startY + verticalChange
+        val endX = startX + horizontalChange
+
+        motionEvent.actionDown(startX, startY)
+        motionEvent.actionMove(startX, startY, endX, endY, /* steps= */100)
+        motionEvent.actionUp(endX, endY)
+        wmHelper
+            .StateSyncBuilder()
+            .withAppTransitionIdle()
+            .waitForAndVerify()
+    }
+
     /** Drag a window from a source coordinate to a destination coordinate. */
     fun dragWindow(
         startX: Int, startY: Int,
@@ -237,6 +279,18 @@
         }
     }
 
+    private fun getStartCoordinatesForEdgeResize(
+        windowRect: Rect,
+        edge: Edges
+    ): Pair<Int, Int> {
+        return when (edge) {
+            Edges.LEFT -> Pair(windowRect.left, windowRect.bottom / 2)
+            Edges.RIGHT -> Pair(windowRect.right, windowRect.bottom / 2)
+            Edges.TOP -> Pair(windowRect.right / 2, windowRect.top)
+            Edges.BOTTOM -> Pair(windowRect.right / 2, windowRect.bottom)
+        }
+    }
+
     /** Exit desktop mode by dragging the app handle to the top drag zone. */
     fun exitDesktopWithDragToTopDragZone(
         wmHelper: WindowManagerStateHelper,
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/MotionEventHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/MotionEventHelper.kt
new file mode 100644
index 0000000..0835398
--- /dev/null
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/MotionEventHelper.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.helpers
+
+import android.app.Instrumentation
+import android.os.SystemClock
+import android.view.ContentInfo.Source
+import android.view.InputDevice.SOURCE_MOUSE
+import android.view.InputDevice.SOURCE_STYLUS
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_UP
+import android.view.MotionEvent.TOOL_TYPE_FINGER
+import android.view.MotionEvent.TOOL_TYPE_MOUSE
+import android.view.MotionEvent.TOOL_TYPE_STYLUS
+import android.view.MotionEvent.ToolType
+
+/**
+ * Helper class for injecting a custom motion event and performing some actions. This is used for
+ * instrumenting input injections like stylus, mouse and touchpad.
+ */
+class MotionEventHelper(
+    private val instr: Instrumentation,
+    private val inputMethod: InputMethod
+) {
+    enum class InputMethod(@ToolType val toolType: Int, @Source val source: Int) {
+        STYLUS(TOOL_TYPE_STYLUS, SOURCE_STYLUS),
+        MOUSE(TOOL_TYPE_MOUSE, SOURCE_MOUSE),
+        TOUCHPAD(TOOL_TYPE_FINGER, SOURCE_MOUSE)
+    }
+
+    fun actionDown(x: Int, y: Int) {
+        injectMotionEvent(ACTION_DOWN, x, y)
+    }
+
+    fun actionUp(x: Int, y: Int) {
+        injectMotionEvent(ACTION_UP, x, y)
+    }
+
+    fun actionMove(startX: Int, startY: Int, endX: Int, endY: Int, steps: Int) {
+        val incrementX = (endX - startX).toFloat() / (steps - 1)
+        val incrementY = (endY - startY).toFloat() / (steps - 1)
+
+        for (i in 0..steps) {
+            val time = SystemClock.uptimeMillis()
+            val x = startX + incrementX * i
+            val y = startY + incrementY * i
+
+            val moveEvent = getMotionEvent(time, time, ACTION_MOVE, x, y)
+            injectMotionEvent(moveEvent)
+        }
+    }
+
+    private fun injectMotionEvent(action: Int, x: Int, y: Int): MotionEvent {
+        val eventTime = SystemClock.uptimeMillis()
+        val event = getMotionEvent(eventTime, eventTime, action, x.toFloat(), y.toFloat())
+        injectMotionEvent(event)
+        return event
+    }
+
+    private fun injectMotionEvent(event: MotionEvent) {
+        instr.uiAutomation.injectInputEvent(event, true, false)
+    }
+
+    private fun getMotionEvent(
+        downTime: Long,
+        eventTime: Long,
+        action: Int,
+        x: Float,
+        y: Float,
+    ): MotionEvent {
+        val properties = MotionEvent.PointerProperties.createArray(1)
+        properties[0].toolType = inputMethod.toolType
+        properties[0].id = 1
+
+        val coords = MotionEvent.PointerCoords.createArray(1)
+        coords[0].x = x
+        coords[0].y = y
+        coords[0].pressure = 1f
+
+        val event =
+            MotionEvent.obtain(
+                downTime,
+                eventTime,
+                action,
+                /* pointerCount= */ 1,
+                properties,
+                coords,
+                /* metaState= */ 0,
+                /* buttonState= */ 0,
+                /* xPrecision = */ 1f,
+                /* yPrecision = */ 1f,
+                /* deviceId = */ 0,
+                /* edgeFlags = */ 0,
+                inputMethod.source,
+                /* flags = */ 0
+            )
+        event.displayId = 0
+        return event
+    }
+}
\ No newline at end of file