Introduce provider for drag resize handle sizes.

Bug: 335850704
Test: atest WMShellUnitTests:ResizeHandleSizeRepositoryTests
Test: atest WMShellUnitTests:ResizeHandleSizeRepositoryParamaterizedTests
Flag: com.android.window.flags.enable_windowing_edge_drag_resize
Change-Id: I68802939f7ad419175c491cbc00d1001d223e580
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index a1910c5..bc8201b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -100,6 +100,7 @@
 import com.android.wm.shell.unfold.qualifier.UnfoldTransition;
 import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel;
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel;
+import com.android.wm.shell.windowdecor.ResizeHandleSizeRepository;
 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
 
 import dagger.Binds;
@@ -220,7 +221,8 @@
             SyncTransactionQueue syncQueue,
             Transitions transitions,
             Optional<DesktopTasksController> desktopTasksController,
-            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+            ResizeHandleSizeRepository resizeHandleSizeRepository) {
         if (DesktopModeStatus.canEnterDesktopMode(context)) {
             return new DesktopModeWindowDecorViewModel(
                     context,
@@ -237,7 +239,8 @@
                     syncQueue,
                     transitions,
                     desktopTasksController,
-                    rootTaskDisplayAreaOrganizer);
+                    rootTaskDisplayAreaOrganizer,
+                    resizeHandleSizeRepository);
         }
         return new CaptionWindowDecorViewModel(
                 context,
@@ -247,7 +250,8 @@
                 displayController,
                 rootTaskDisplayAreaOrganizer,
                 syncQueue,
-                transitions);
+                transitions,
+                resizeHandleSizeRepository);
     }
 
     //
@@ -529,7 +533,8 @@
                 exitDesktopTransitionHandler, toggleResizeDesktopTaskTransitionHandler,
                 dragToDesktopTransitionHandler, desktopModeTaskRepository,
                 desktopModeLoggerTransitionObserver, launchAdjacentController,
-                recentsTransitionHandler, multiInstanceHelper, mainExecutor, desktopTasksLimiter);
+                recentsTransitionHandler, multiInstanceHelper,
+                mainExecutor, desktopTasksLimiter);
     }
 
     @WMSingleton
@@ -622,6 +627,12 @@
         return new DesktopModeEventLogger();
     }
 
+    @WMSingleton
+    @Provides
+    static ResizeHandleSizeRepository provideResizeHandleSizeRepository() {
+        return new ResizeHandleSizeRepository();
+    }
+
     //
     // Drag and drop
     //
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index e85cb64..bfa163c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -63,6 +63,7 @@
     private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
     private final SyncTransactionQueue mSyncQueue;
     private final Transitions mTransitions;
+    private final ResizeHandleSizeRepository mResizeHandleSizeRepository;
     private TaskOperations mTaskOperations;
 
     private final SparseArray<CaptionWindowDecoration> mWindowDecorByTaskId = new SparseArray<>();
@@ -75,7 +76,8 @@
             DisplayController displayController,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
             SyncTransactionQueue syncQueue,
-            Transitions transitions) {
+            Transitions transitions,
+            ResizeHandleSizeRepository resizeHandleSizeRepository) {
         mContext = context;
         mMainHandler = mainHandler;
         mMainChoreographer = mainChoreographer;
@@ -84,6 +86,7 @@
         mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
         mSyncQueue = syncQueue;
         mTransitions = transitions;
+        mResizeHandleSizeRepository = resizeHandleSizeRepository;
         if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
             mTaskOperations = new TaskOperations(null, mContext, mSyncQueue);
         }
@@ -231,7 +234,8 @@
                         taskSurface,
                         mMainHandler,
                         mMainChoreographer,
-                        mSyncQueue);
+                        mSyncQueue,
+                        mResizeHandleSizeRepository);
         mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
 
         final FluidResizeTaskPositioner taskPositioner =
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 6671391..1be3b02 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -16,11 +16,11 @@
 
 package com.android.wm.shell.windowdecor;
 
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getFineResizeCornerSize;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getLargeResizeCornerSize;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeEdgeHandleSize;
+import static com.android.wm.shell.windowdecor.ResizeHandleSizeRepository.getFineResizeCornerPixels;
+import static com.android.wm.shell.windowdecor.ResizeHandleSizeRepository.getLargeResizeCornerPixels;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.WindowConfiguration;
 import android.app.WindowConfiguration.WindowingMode;
@@ -45,6 +45,8 @@
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
 
+import java.util.function.Consumer;
+
 /**
  * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
  * {@link CaptionWindowDecorViewModel}. The caption bar contains a back button, minimize button,
@@ -58,12 +60,28 @@
     private View.OnClickListener mOnCaptionButtonClickListener;
     private View.OnTouchListener mOnCaptionTouchListener;
     private DragPositioningCallback mDragPositioningCallback;
+    // Listener for handling drag resize events. Will be null if the task cannot be resized.
+    @Nullable
     private DragResizeInputListener mDragResizeListener;
     private DragDetector mDragDetector;
 
     private RelayoutParams mRelayoutParams = new RelayoutParams();
     private final RelayoutResult<WindowDecorLinearLayout> mResult =
             new RelayoutResult<>();
+    private final ResizeHandleSizeRepository mResizeHandleSizeRepository;
+    private final Consumer<ResizeHandleSizeRepository> mResizeHandleSizeChangedFunction =
+            (ResizeHandleSizeRepository sizeRepository) -> {
+                if (mDragResizeListener == null) {
+                    return;
+                }
+                final Resources res = mResult.mRootView.getResources();
+                mDragResizeListener.setGeometry(
+                        new DragResizeWindowGeometry(0 /* taskCornerRadius */,
+                                new Size(mResult.mWidth, mResult.mHeight),
+                                sizeRepository.getResizeEdgeHandlePixels(res),
+                                getFineResizeCornerPixels(res), getLargeResizeCornerPixels(res)),
+                        mDragDetector.getTouchSlop());
+            };
 
     CaptionWindowDecoration(
             Context context,
@@ -73,13 +91,16 @@
             SurfaceControl taskSurface,
             Handler handler,
             Choreographer choreographer,
-            SyncTransactionQueue syncQueue) {
+            SyncTransactionQueue syncQueue,
+            ResizeHandleSizeRepository resizeHandleSizeRepository) {
         super(context, displayController, taskOrganizer, taskInfo, taskSurface,
                 taskInfo.getConfiguration());
 
         mHandler = handler;
         mChoreographer = choreographer;
         mSyncQueue = syncQueue;
+        mResizeHandleSizeRepository = resizeHandleSizeRepository;
+        mResizeHandleSizeRepository.registerSizeChangeFunction(mResizeHandleSizeChangedFunction);
     }
 
     void setCaptionListeners(
@@ -238,10 +259,7 @@
                 .getScaledTouchSlop();
         mDragDetector.setTouchSlop(touchSlop);
 
-        final Resources res = mResult.mRootView.getResources();
-        mDragResizeListener.setGeometry(new DragResizeWindowGeometry(0 /* taskCornerRadius */,
-                new Size(mResult.mWidth, mResult.mHeight), getResizeEdgeHandleSize(res),
-                getFineResizeCornerSize(res), getLargeResizeCornerSize(res)), touchSlop);
+        mResizeHandleSizeChangedFunction.accept(mResizeHandleSizeRepository);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index dfdb58a..3c0f60a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -149,6 +149,7 @@
             new DesktopModeKeyguardChangeListener();
     private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
     private final DisplayInsetsController mDisplayInsetsController;
+    private final ResizeHandleSizeRepository mResizeHandleSizeRepository;
     private final Region mExclusionRegion = Region.obtain();
     private boolean mInImmersiveMode;
 
@@ -181,7 +182,8 @@
             SyncTransactionQueue syncQueue,
             Transitions transitions,
             Optional<DesktopTasksController> desktopTasksController,
-            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer
+            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+            ResizeHandleSizeRepository resizeHandleSizeRepository
     ) {
         this(
                 context,
@@ -202,7 +204,8 @@
                 new InputMonitorFactory(),
                 SurfaceControl.Transaction::new,
                 rootTaskDisplayAreaOrganizer,
-                new SparseArray<>());
+                new SparseArray<>(),
+                resizeHandleSizeRepository);
     }
 
     @VisibleForTesting
@@ -225,7 +228,8 @@
             InputMonitorFactory inputMonitorFactory,
             Supplier<SurfaceControl.Transaction> transactionFactory,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
-            SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId) {
+            SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId,
+            ResizeHandleSizeRepository resizeHandleSizeRepository) {
         mContext = context;
         mMainExecutor = shellExecutor;
         mMainHandler = mainHandler;
@@ -246,6 +250,7 @@
         mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
         mInputManager = mContext.getSystemService(InputManager.class);
         mWindowDecorByTaskId = windowDecorByTaskId;
+        mResizeHandleSizeRepository = resizeHandleSizeRepository;
 
         shellInit.addInitCallback(this::onInit, this);
     }
@@ -1060,7 +1065,8 @@
                         mMainHandler,
                         mMainChoreographer,
                         mSyncQueue,
-                        mRootTaskDisplayAreaOrganizer);
+                        mRootTaskDisplayAreaOrganizer,
+                        mResizeHandleSizeRepository);
         mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
 
         final DragPositioningCallback dragPositioningCallback;
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 4c347ad..20223fe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -24,11 +24,11 @@
 import static android.view.MotionEvent.ACTION_UP;
 
 import static com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getFineResizeCornerSize;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getLargeResizeCornerSize;
-import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeEdgeHandleSize;
+import static com.android.wm.shell.windowdecor.ResizeHandleSizeRepository.getFineResizeCornerPixels;
+import static com.android.wm.shell.windowdecor.ResizeHandleSizeRepository.getLargeResizeCornerPixels;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.WindowConfiguration.WindowingMode;
 import android.content.Context;
@@ -75,6 +75,7 @@
 
 import kotlin.Unit;
 
+import java.util.function.Function;
 import java.util.function.Supplier;
 
 /**
@@ -96,6 +97,8 @@
     private View.OnLongClickListener mOnCaptionLongClickListener;
     private View.OnGenericMotionListener mOnCaptionGenericMotionListener;
     private DragPositioningCallback mDragPositioningCallback;
+    // Listener for handling drag resize events. Will be null if the task cannot be resized.
+    @Nullable
     private DragResizeInputListener mDragResizeListener;
     private DragDetector mDragDetector;
 
@@ -118,6 +121,19 @@
 
     private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
 
+    private final ResizeHandleSizeRepository mResizeHandleSizeRepository;
+    private final Function<ResizeHandleSizeRepository, Boolean> mResizeHandleSizeChangedFunction =
+            (ResizeHandleSizeRepository sizeRepository) -> {
+                final Resources res = mResult.mRootView.getResources();
+                return mDragResizeListener == null || mDragResizeListener.setGeometry(
+                        new DragResizeWindowGeometry(mRelayoutParams.mCornerRadius,
+                                new Size(mResult.mWidth, mResult.mHeight),
+                                sizeRepository.getResizeEdgeHandlePixels(res),
+                                getFineResizeCornerPixels(res),
+                                getLargeResizeCornerPixels(res)),
+                        mDragDetector.getTouchSlop());
+            };
+
     DesktopModeWindowDecoration(
             Context context,
             DisplayController displayController,
@@ -128,12 +144,13 @@
             Handler handler,
             Choreographer choreographer,
             SyncTransactionQueue syncQueue,
-            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+            ResizeHandleSizeRepository resizeHandleSizeRepository) {
         this (context, displayController, taskOrganizer, taskInfo, taskSurface, windowDecorConfig,
                 handler, choreographer, syncQueue, rootTaskDisplayAreaOrganizer,
-                SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
-                WindowContainerTransaction::new, SurfaceControl::new,
-                new SurfaceControlViewHostFactory() {});
+                resizeHandleSizeRepository, SurfaceControl.Builder::new,
+                SurfaceControl.Transaction::new, WindowContainerTransaction::new,
+                SurfaceControl::new, new SurfaceControlViewHostFactory() {});
     }
 
     DesktopModeWindowDecoration(
@@ -147,6 +164,7 @@
             Choreographer choreographer,
             SyncTransactionQueue syncQueue,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+            ResizeHandleSizeRepository resizeHandleSizeRepository,
             Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
             Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
             Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
@@ -160,6 +178,9 @@
         mChoreographer = choreographer;
         mSyncQueue = syncQueue;
         mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+        mResizeHandleSizeRepository = resizeHandleSizeRepository;
+        mResizeHandleSizeRepository.registerSizeChangeFunction(
+                mResizeHandleSizeChangedFunction::apply);
     }
 
     void setCaptionListeners(
@@ -305,11 +326,7 @@
 
         // If either task geometry or position have changed, update this task's
         // exclusion region listener
-        final Resources res = mResult.mRootView.getResources();
-        if (mDragResizeListener.setGeometry(
-                new DragResizeWindowGeometry(mRelayoutParams.mCornerRadius,
-                        new Size(mResult.mWidth, mResult.mHeight), getResizeEdgeHandleSize(res),
-                        getFineResizeCornerSize(res), getLargeResizeCornerSize(res)), touchSlop)
+        if (mResizeHandleSizeChangedFunction.apply(mResizeHandleSizeRepository)
                 || !mTaskInfo.positionInParent.equals(mPositionInParent)) {
             updateExclusionRegion();
         }
@@ -936,7 +953,8 @@
                 Handler handler,
                 Choreographer choreographer,
                 SyncTransactionQueue syncQueue,
-                RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+                RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+                ResizeHandleSizeRepository resizeHandleSizeRepository) {
             final Configuration windowDecorConfig =
                     DesktopTasksController.isDesktopDensityOverrideSet()
                     ? context.getResources().getConfiguration() // Use system context
@@ -951,7 +969,8 @@
                     handler,
                     choreographer,
                     syncQueue,
-                    rootTaskDisplayAreaOrganizer);
+                    rootTaskDisplayAreaOrganizer,
+                    resizeHandleSizeRepository);
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
index da26898..a3b0a71 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
@@ -119,6 +119,10 @@
         mTouchSlop = touchSlop;
     }
 
+    int getTouchSlop() {
+        return mTouchSlop;
+    }
+
     private void resetState() {
         mIsDragEvent = false;
         mInputDownPoint.set(0, 0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
index 4f513f0..80d60d4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
@@ -26,7 +26,6 @@
 import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED;
 
 import android.annotation.NonNull;
-import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -36,8 +35,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.wm.shell.R;
-
 import java.util.Objects;
 
 /**
@@ -63,6 +60,10 @@
     // Extra-large edge bounds for logging to help debug when an edge resize is ignored.
     private final @Nullable TaskEdges mDebugTaskEdges;
 
+    /**
+     * Constructs an instance representing the drag resize touch input regions, where all sizes
+     * are represented in pixels.
+     */
     DragResizeWindowGeometry(int taskCornerRadius, @NonNull Size taskSize,
             int resizeHandleThickness, int fineCornerSize, int largeCornerSize) {
         mTaskCornerRadius = taskCornerRadius;
@@ -82,31 +83,6 @@
     }
 
     /**
-     * Returns the resource value to use for the resize handle on the edge of the window.
-     */
-    static int getResizeEdgeHandleSize(@NonNull Resources res) {
-        return enableWindowingEdgeDragResize()
-                ? res.getDimensionPixelSize(R.dimen.desktop_mode_edge_handle)
-                : res.getDimensionPixelSize(R.dimen.freeform_resize_handle);
-    }
-
-    /**
-     * Returns the resource value to use for course input, such as touch, that benefits from a large
-     * square on each of the window's corners.
-     */
-    static int getLargeResizeCornerSize(@NonNull Resources res) {
-        return res.getDimensionPixelSize(R.dimen.desktop_mode_corner_resize_large);
-    }
-
-    /**
-     * Returns the resource value to use for fine input, such as stylus, that can use a smaller
-     * square on each of the window's corners.
-     */
-    static int getFineResizeCornerSize(@NonNull Resources res) {
-        return res.getDimensionPixelSize(R.dimen.freeform_resize_corner);
-    }
-
-    /**
      * Returns the size of the task this geometry is calculated for.
      */
     @NonNull Size getTaskSize() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepository.kt
new file mode 100644
index 0000000..be7a301
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepository.kt
@@ -0,0 +1,133 @@
+/*
+ * 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.windowdecor
+
+import android.content.res.Resources
+import com.android.window.flags.Flags.enableWindowingEdgeDragResize
+import com.android.wm.shell.R
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+import com.android.wm.shell.util.KtProtoLog
+import java.util.function.Consumer
+
+/** Repository for desktop mode drag resize handle sizes. */
+class ResizeHandleSizeRepository {
+    private val TAG = "ResizeHandleSizeRepository"
+    private var edgeResizeHandleSizePixels: Int? = null
+    private var sizeChangeFunctions: MutableList<Consumer<ResizeHandleSizeRepository>> =
+        mutableListOf()
+
+    /**
+     * Resets the window edge resize handle size if necessary.
+     */
+    fun resetResizeEdgeHandlePixels() {
+        if (enableWindowingEdgeDragResize() && edgeResizeHandleSizePixels != null) {
+            edgeResizeHandleSizePixels = null
+            applyToAll()
+        }
+    }
+
+    /**
+     * Sets the window edge resize handle to the given size in pixels.
+     */
+    fun setResizeEdgeHandlePixels(sizePixels: Int) {
+        if (enableWindowingEdgeDragResize()) {
+            KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "$TAG: Set edge handle size to $sizePixels")
+            if (edgeResizeHandleSizePixels != null && edgeResizeHandleSizePixels == sizePixels) {
+                // Skip updating since override is the same size
+                return
+            }
+            edgeResizeHandleSizePixels = sizePixels
+            applyToAll()
+        } else {
+            KtProtoLog.d(
+                WM_SHELL_DESKTOP_MODE,
+                "$TAG: Can't set edge handle size to $sizePixels since " +
+                    "enable_windowing_edge_drag_resize disabled"
+            )
+        }
+    }
+
+    /**
+     * Returns the resource value, in pixels, to use for the resize handle on the edge of the
+     * window.
+     */
+    fun getResizeEdgeHandlePixels(res: Resources): Int {
+        try {
+            return if (enableWindowingEdgeDragResize()) {
+                val resPixelSize = res.getDimensionPixelSize(R.dimen.desktop_mode_edge_handle)
+                val size = edgeResizeHandleSizePixels ?: resPixelSize
+                KtProtoLog.d(
+                    WM_SHELL_DESKTOP_MODE,
+                    "$TAG: Get edge handle size of $size from (vs base value $resPixelSize)"
+                )
+                size
+            } else {
+                KtProtoLog.d(
+                    WM_SHELL_DESKTOP_MODE,
+                    "$TAG: Get edge handle size from freeform since flag is disabled"
+                )
+                res.getDimensionPixelSize(R.dimen.freeform_resize_handle)
+            }
+        } catch (e: Resources.NotFoundException) {
+            KtProtoLog.e(WM_SHELL_DESKTOP_MODE, "$TAG: Unable to get edge handle size", e)
+            return 0
+        }
+    }
+
+    /** Register function to run when the resize handle size changes. */
+    fun registerSizeChangeFunction(function: Consumer<ResizeHandleSizeRepository>) {
+        sizeChangeFunctions.add(function)
+    }
+
+    private fun applyToAll() {
+        for (f in sizeChangeFunctions) {
+            f.accept(this)
+        }
+    }
+
+    companion object {
+        private val TAG = "ResizeHandleSizeRepositoryCompanion"
+
+        /**
+         * Returns the resource value in pixels to use for course input, such as touch, that
+         * benefits from a large square on each of the window's corners.
+         */
+        @JvmStatic
+        fun getLargeResizeCornerPixels(res: Resources): Int {
+            return try {
+                res.getDimensionPixelSize(R.dimen.desktop_mode_corner_resize_large)
+            } catch (e: Resources.NotFoundException) {
+                KtProtoLog.e(WM_SHELL_DESKTOP_MODE, "$TAG: Unable to get large corner size", e)
+                0
+            }
+        }
+
+        /**
+         * Returns the resource value, in pixels, to use for fine input, such as stylus, that can
+         * use a smaller square on each of the window's corners.
+         */
+        @JvmStatic
+        fun getFineResizeCornerPixels(res: Resources): Int {
+            return try {
+                res.getDimensionPixelSize(R.dimen.freeform_resize_corner)
+            } catch (e: Resources.NotFoundException) {
+                KtProtoLog.e(WM_SHELL_DESKTOP_MODE, "$TAG: Unable to get fine corner size", e)
+                0
+            }
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 7d19f3c..fedd7896 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -121,6 +121,7 @@
     @Mock private lateinit var mockShellController: ShellController
     @Mock private lateinit var mockShellExecutor: ShellExecutor
     @Mock private lateinit var mockRootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
+    @Mock private lateinit var mockResizeHandleSizeRepository: ResizeHandleSizeRepository
     @Mock private lateinit var mockShellCommandHandler: ShellCommandHandler
     @Mock private lateinit var mockWindowManager: IWindowManager
 
@@ -156,7 +157,8 @@
                 mockInputMonitorFactory,
                 transactionFactory,
                 mockRootTaskDisplayAreaOrganizer,
-            windowDecorByTaskIdSpy
+                windowDecorByTaskIdSpy,
+                mockResizeHandleSizeRepository
         )
 
         whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -197,7 +199,8 @@
                 mockMainHandler,
                 mockMainChoreographer,
                 mockSyncQueue,
-                mockRootTaskDisplayAreaOrganizer
+                mockRootTaskDisplayAreaOrganizer,
+                mockResizeHandleSizeRepository
         )
         verify(decoration).close()
     }
@@ -221,7 +224,8 @@
                 mockMainHandler,
                 mockMainChoreographer,
                 mockSyncQueue,
-                mockRootTaskDisplayAreaOrganizer
+                mockRootTaskDisplayAreaOrganizer,
+                mockResizeHandleSizeRepository
         )
 
         task.setWindowingMode(WINDOWING_MODE_FREEFORM)
@@ -236,7 +240,8 @@
                 mockMainHandler,
                 mockMainChoreographer,
                 mockSyncQueue,
-                mockRootTaskDisplayAreaOrganizer
+                mockRootTaskDisplayAreaOrganizer,
+                mockResizeHandleSizeRepository
         )
     }
 
@@ -296,7 +301,7 @@
         onTaskChanging(task)
 
         verify(mockDesktopModeWindowDecorFactory, never())
-                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
     }
 
     @Test
@@ -309,7 +314,7 @@
         onTaskOpening(task)
 
         verify(mockDesktopModeWindowDecorFactory, never())
-                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
     }
 
     @Test
@@ -406,7 +411,7 @@
 
             onTaskOpening(task)
             verify(mockDesktopModeWindowDecorFactory, never())
-                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
         } finally {
             mockitoSession.finishMocking()
         }
@@ -430,7 +435,7 @@
 
             onTaskOpening(task)
             verify(mockDesktopModeWindowDecorFactory)
-                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
         } finally {
             mockitoSession.finishMocking()
         }
@@ -453,7 +458,7 @@
 
             onTaskOpening(task)
             verify(mockDesktopModeWindowDecorFactory)
-                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+                .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
         } finally {
             mockitoSession.finishMocking()
         }
@@ -497,7 +502,7 @@
         val decoration = mock(DesktopModeWindowDecoration::class.java)
         whenever(
             mockDesktopModeWindowDecorFactory.create(
-                any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+                any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any())
         ).thenReturn(decoration)
         decoration.mTaskInfo = task
         whenever(decoration.isFocused).thenReturn(task.isFocused)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 608f74b..d79fe7d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -107,6 +107,8 @@
     private WindowDecoration.SurfaceControlViewHostFactory mMockSurfaceControlViewHostFactory;
     @Mock
     private TypedArray mMockRoundedCornersRadiusArray;
+    @Mock
+    private ResizeHandleSizeRepository mMockResizeHandleSizeRepository;
 
     private final Configuration mConfiguration = new Configuration();
 
@@ -296,8 +298,8 @@
         return new DesktopModeWindowDecoration(mContext, mMockDisplayController,
                 mMockShellTaskOrganizer, taskInfo, mMockSurfaceControl, mConfiguration,
                 mMockHandler, mMockChoreographer, mMockSyncQueue, mMockRootTaskDisplayAreaOrganizer,
-                SurfaceControl.Builder::new, mMockTransactionSupplier,
-                WindowContainerTransaction::new, SurfaceControl::new,
+                mMockResizeHandleSizeRepository, SurfaceControl.Builder::new,
+                mMockTransactionSupplier, WindowContainerTransaction::new, SurfaceControl::new,
                 mMockSurfaceControlViewHostFactory);
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
index 5464508..62fb1c4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
@@ -27,10 +27,7 @@
 import android.annotation.NonNull;
 import android.graphics.Point;
 import android.graphics.Region;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.testing.AndroidTestingRunner;
 import android.util.Size;
 
@@ -74,7 +71,7 @@
             TASK_SIZE.getHeight() + EDGE_RESIZE_THICKNESS / 2);
 
     @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     /**
      * Check that both groups of objects satisfy equals/hashcode within each group, and that each
@@ -147,8 +144,8 @@
      * capture all eligible input regardless of source (touch or cursor).
      */
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
     public void testRegionUnion_edgeDragResizeEnabled_containsLargeCorners() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
         Region region = new Region();
         GEOMETRY.union(region);
         // Make sure we're choosing a point outside of any debug region buffer.
@@ -164,8 +161,8 @@
      * size.
      */
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
     public void testRegionUnion_edgeDragResizeDisabled_containsFineCorners() {
+        mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
         Region region = new Region();
         GEOMETRY.union(region);
         final int cornerRadius = DragResizeWindowGeometry.DEBUG
@@ -176,16 +173,16 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
     public void testCalculateControlType_edgeDragResizeEnabled_edges() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
         // The input source (touch or cursor) shouldn't impact the edge resize size.
         validateCtrlTypeForEdges(/* isTouch= */ false);
         validateCtrlTypeForEdges(/* isTouch= */ true);
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
     public void testCalculateControlType_edgeDragResizeDisabled_edges() {
+        mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
         // Edge resizing is not supported when the flag is disabled.
         validateCtrlTypeForEdges(/* isTouch= */ false);
         validateCtrlTypeForEdges(/* isTouch= */ false);
@@ -203,8 +200,8 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
     public void testCalculateControlType_edgeDragResizeEnabled_corners() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
         final TestPoints fineTestPoints = new TestPoints(TASK_SIZE, FINE_CORNER_SIZE / 2);
         final TestPoints largeCornerTestPoints = new TestPoints(TASK_SIZE, LARGE_CORNER_SIZE / 2);
 
@@ -226,8 +223,8 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
     public void testCalculateControlType_edgeDragResizeDisabled_corners() {
+        mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE);
         final TestPoints fineTestPoints = new TestPoints(TASK_SIZE, FINE_CORNER_SIZE / 2);
         final TestPoints largeCornerTestPoints = new TestPoints(TASK_SIZE, LARGE_CORNER_SIZE / 2);
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryParameterizedTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryParameterizedTests.kt
new file mode 100644
index 0000000..a9fddc6
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryParameterizedTests.kt
@@ -0,0 +1,150 @@
+/*
+ * 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.windowdecor
+
+import android.content.Context
+import android.platform.test.flag.junit.SetFlagsRule
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags
+import java.util.function.Consumer
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameter
+import org.junit.runners.Parameterized.Parameters
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+/**
+ * Tests for {@link ResizeHandleSizeRepository}.
+ *
+ * Build/Install/Run: atest WMShellUnitTests:ResizeHandleSizeRepositoryParameterizedTests
+ */
+@SmallTest
+@RunWith(Parameterized::class)
+class ResizeHandleSizeRepositoryParameterizedTests {
+    private val resources = ApplicationProvider.getApplicationContext<Context>().resources
+    private val resizeHandleSizeRepository = ResizeHandleSizeRepository()
+    @Mock private lateinit var mockSizeChangeFunctionOne: Consumer<ResizeHandleSizeRepository>
+    @Mock private lateinit var mockSizeChangeFunctionTwo: Consumer<ResizeHandleSizeRepository>
+
+    @JvmField @Rule val setFlagsRule = SetFlagsRule()
+
+    @Parameter(0) lateinit var name: String
+    // The current ResizeHandleSizeRepository API under test.
+
+    @Parameter(1) lateinit var operation: (ResizeHandleSizeRepository) -> Unit
+
+    @Before
+    fun setOverrideBeforeResetResizeHandle() {
+        MockitoAnnotations.initMocks(this)
+        if (name != "reset") return
+        val originalEdgeHandle =
+            resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources)
+        resizeHandleSizeRepository.setResizeEdgeHandlePixels(originalEdgeHandle + 2)
+    }
+
+    companion object {
+        @Parameters(name = "{index}: {0}")
+        @JvmStatic
+        fun data(): Iterable<Array<Any>> {
+            return listOf(
+                arrayOf(
+                    "reset",
+                    { sizeRepository: ResizeHandleSizeRepository ->
+                        sizeRepository.resetResizeEdgeHandlePixels()
+                    }
+                ),
+                arrayOf(
+                    "set",
+                    { sizeRepository: ResizeHandleSizeRepository ->
+                        sizeRepository.setResizeEdgeHandlePixels(99)
+                    }
+                )
+            )
+        }
+    }
+
+    // =================
+    // Validate that listeners are notified correctly for reset resize handle API.
+    // =================
+
+    @Test
+    fun testUpdateResizeHandleSize_flagDisabled() {
+        setFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+        registerSizeChangeFunctions()
+        operation.invoke(resizeHandleSizeRepository)
+        // Nothing is notified since flag is disabled.
+        verify(mockSizeChangeFunctionOne, never()).accept(any())
+        verify(mockSizeChangeFunctionTwo, never()).accept(any())
+    }
+
+    @Test
+    fun testUpdateResizeHandleSize_flagEnabled_noListeners() {
+        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+        operation.invoke(resizeHandleSizeRepository)
+        // Nothing is notified since nothing was registered.
+        verify(mockSizeChangeFunctionOne, never()).accept(any())
+        verify(mockSizeChangeFunctionTwo, never()).accept(any())
+    }
+
+    @Test
+    fun testUpdateResizeHandleSize_flagEnabled_listenersNotified() {
+        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+        registerSizeChangeFunctions()
+        operation.invoke(resizeHandleSizeRepository)
+        // Functions notified when reset.
+        verify(mockSizeChangeFunctionOne).accept(any())
+        verify(mockSizeChangeFunctionTwo).accept(any())
+    }
+
+    @Test
+    fun testUpdateResizeHandleSize_flagEnabled_listenerFails() {
+        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+        registerSizeChangeFunctions()
+        operation.invoke(resizeHandleSizeRepository)
+        // Functions notified when reset.
+        verify(mockSizeChangeFunctionOne).accept(any())
+        verify(mockSizeChangeFunctionTwo).accept(any())
+    }
+
+    @Test
+    fun testUpdateResizeHandleSize_flagEnabled_ignoreSecondListener() {
+        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+        registerSizeChangeFunctions()
+        val extraConsumerMock = mock(Consumer::class.java) as Consumer<ResizeHandleSizeRepository>
+        resizeHandleSizeRepository.registerSizeChangeFunction(extraConsumerMock)
+        // First listener succeeds, second one that fails is ignored.
+        operation.invoke(resizeHandleSizeRepository)
+        // Functions notified when reset.
+        verify(mockSizeChangeFunctionOne).accept(any())
+        verify(mockSizeChangeFunctionTwo).accept(any())
+        verify(extraConsumerMock).accept(any())
+    }
+
+    private fun registerSizeChangeFunctions() {
+        resizeHandleSizeRepository.registerSizeChangeFunction(mockSizeChangeFunctionOne)
+        resizeHandleSizeRepository.registerSizeChangeFunction(mockSizeChangeFunctionTwo)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryTests.kt
new file mode 100644
index 0000000..59bbc72
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeHandleSizeRepositoryTests.kt
@@ -0,0 +1,77 @@
+/*
+ * 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.windowdecor
+
+import android.content.Context
+import android.platform.test.flag.junit.SetFlagsRule
+import android.testing.AndroidTestingRunner
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for {@link ResizeHandleSizeRepository}. Validate that get/reset/set work correctly.
+ *
+ * Build/Install/Run: atest WMShellUnitTests:ResizeHandleSizeRepositoryTests
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ResizeHandleSizeRepositoryTests {
+    private val resources = ApplicationProvider.getApplicationContext<Context>().resources
+    private val resizeHandleSizeRepository = ResizeHandleSizeRepository()
+
+    @JvmField @Rule val setFlagsRule = SetFlagsRule()
+
+    @Test
+    fun testOverrideResizeEdgeHandlePixels_flagEnabled_resetSucceeds() {
+        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+        // Reset does nothing when no override is set.
+        val originalEdgeHandle =
+            resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources)
+        resizeHandleSizeRepository.resetResizeEdgeHandlePixels()
+        assertThat(resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources))
+            .isEqualTo(originalEdgeHandle)
+
+        // Now try to set the value; reset should succeed.
+        resizeHandleSizeRepository.setResizeEdgeHandlePixels(originalEdgeHandle + 2)
+        resizeHandleSizeRepository.resetResizeEdgeHandlePixels()
+        assertThat(resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources))
+            .isEqualTo(originalEdgeHandle)
+    }
+
+    @Test
+    fun testOverrideResizeEdgeHandlePixels_flagDisabled_resetFails() {
+        setFlagsRule.disableFlags(Flags.FLAG_ENABLE_WINDOWING_EDGE_DRAG_RESIZE)
+        // Reset does nothing when no override is set.
+        val originalEdgeHandle =
+            resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources)
+        resizeHandleSizeRepository.resetResizeEdgeHandlePixels()
+        assertThat(resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources))
+            .isEqualTo(originalEdgeHandle)
+
+        // Now try to set the value; reset should do nothing.
+        val newEdgeHandle = originalEdgeHandle + 2
+        resizeHandleSizeRepository.setResizeEdgeHandlePixels(newEdgeHandle)
+        resizeHandleSizeRepository.resetResizeEdgeHandlePixels()
+        assertThat(resizeHandleSizeRepository.getResizeEdgeHandlePixels(resources))
+            .isEqualTo(originalEdgeHandle)
+    }
+}