Merge changes from topic "magnification_settings" into udc-dev am: 9c31e2931a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22101150

Change-Id: I31a646caad3441202367a26dcc877bb256523772
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
index 62d029b..8a30f8c 100644
--- a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
+++ b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
@@ -103,6 +103,13 @@
     void removeMagnificationButton(int displayId);
 
     /**
+     * Requests System UI remove magnification settings panel on the specified display.
+     *
+     * @param displayId the logical display id.
+     */
+    void removeMagnificationSettingsPanel(int displayId);
+
+    /**
      * Sets {@link IWindowMagnificationConnectionCallback} to receive the request or the callback.
      *
      * @param callback the interface to be called.
diff --git a/packages/SystemUI/res/drawable/ic_open_in_new_window.xml b/packages/SystemUI/res/drawable/ic_open_in_new_window.xml
index f41f784..ef450af 100644
--- a/packages/SystemUI/res/drawable/ic_open_in_new_window.xml
+++ b/packages/SystemUI/res/drawable/ic_open_in_new_window.xml
@@ -17,29 +17,26 @@
 
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/magnification_switch_button_color" />
+            <stroke
+                android:color="@android:color/black"
+                android:width="@dimen/magnifier_stroke_width"/>
+            <corners android:radius="@dimen/magnification_setting_drag_corner_radius" />
+            <solid android:color="@color/magnification_border_color" />
             <size
-                android:width="48dp"
-                android:height="48dp" />
+                android:width="@dimen/magnification_setting_drag_size"
+                android:height="@dimen/magnification_setting_drag_size" />
         </shape>
     </item>
 
-    <item
-        android:gravity="center">
-        <vector
-            android:width="36dp"
-            android:height="36dp"
-            android:viewportWidth="24"
-            android:viewportHeight="24">
+    <item android:gravity="center">
+        <vector android:autoMirrored="true"
+                android:width="36dp"
+                android:height="36dp"
+                android:viewportWidth="48"
+                android:viewportHeight="48">
             <path
-                android:pathData="M2,12.05V22.05H22V2.05H12V4.05H20V20.05H4V12.05H2Z"
-                android:fillColor="#ffffff"/>
-            <path
-                android:pathData="M10,2.05H2V10.05H10V2.05Z"
-                android:fillColor="#ffffff"/>
-            <path
-                android:pathData="M18,11.05V13.05H14.41L18.95,17.59L17.54,19L13,14.46V18.05H11V11.05H18Z"
-                android:fillColor="#ffffff"/>
+                android:pathData="m19.4,44 l-1,-6.3q-0.95,-0.35 -2,-0.95t-1.85,-1.25l-5.9,2.7L4,30l5.4,-3.95q-0.1,-0.45 -0.125,-1.025Q9.25,24.45 9.25,24q0,-0.45 0.025,-1.025T9.4,21.95L4,18l4.65,-8.2 5.9,2.7q0.8,-0.65 1.85,-1.25t2,-0.9l1,-6.35h9.2l1,6.3q0.95,0.35 2.025,0.925Q32.7,11.8 33.45,12.5l5.9,-2.7L44,18l-5.4,3.85q0.1,0.5 0.125,1.075 0.025,0.575 0.025,1.075t-0.025,1.05q-0.025,0.55 -0.125,1.05L44,30l-4.65,8.2 -5.9,-2.7q-0.8,0.65 -1.825,1.275 -1.025,0.625 -2.025,0.925l-1,6.3ZM21.8,41h4.4l0.7,-5.6q1.65,-0.4 3.125,-1.25T32.7,32.1l5.3,2.3 2,-3.6 -4.7,-3.45q0.2,-0.85 0.325,-1.675 0.125,-0.825 0.125,-1.675 0,-0.85 -0.1,-1.675 -0.1,-0.825 -0.35,-1.675L40,17.2l-2,-3.6 -5.3,2.3q-1.15,-1.3 -2.6,-2.175 -1.45,-0.875 -3.2,-1.125L26.2,7h-4.4l-0.7,5.6q-1.7,0.35 -3.175,1.2 -1.475,0.85 -2.625,2.1L10,13.6l-2,3.6 4.7,3.45q-0.2,0.85 -0.325,1.675 -0.125,0.825 -0.125,1.675 0,0.85 0.125,1.675 0.125,0.825 0.325,1.675L8,30.8l2,3.6 5.3,-2.3q1.2,1.2 2.675,2.05Q19.45,35 21.1,35.4ZM24,30.5q2.7,0 4.6,-1.9 1.9,-1.9 1.9,-4.6 0,-2.7 -1.9,-4.6 -1.9,-1.9 -4.6,-1.9 -2.7,0 -4.6,1.9 -1.9,1.9 -1.9,4.6 0,2.7 1.9,4.6 1.9,1.9 4.6,1.9ZM24,24Z"
+                android:fillColor="#000000"/>
         </vector>
     </item>
 
diff --git a/packages/SystemUI/res/layout/window_magnification_settings_view.xml b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
index 3d0741c..db8191b 100644
--- a/packages/SystemUI/res/layout/window_magnification_settings_view.xml
+++ b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
@@ -63,7 +63,8 @@
             android:background="@drawable/accessibility_magnification_setting_view_image_btn_bg"
             android:src="@drawable/ic_magnification_menu_small"
             android:tint="@color/accessibility_magnification_image_button_tint"
-            android:tintMode="src_atop" />
+            android:tintMode="src_atop"
+            android:contentDescription="@string/accessibility_magnification_small" />
 
         <ImageButton
             android:id="@+id/magnifier_medium_button"
@@ -74,7 +75,8 @@
             android:background="@drawable/accessibility_magnification_setting_view_image_btn_bg"
             android:src="@drawable/ic_magnification_menu_medium"
             android:tint="@color/accessibility_magnification_image_button_tint"
-            android:tintMode="src_atop" />
+            android:tintMode="src_atop"
+            android:contentDescription="@string/accessibility_magnification_medium" />
 
         <ImageButton
             android:id="@+id/magnifier_large_button"
@@ -85,7 +87,8 @@
             android:background="@drawable/accessibility_magnification_setting_view_image_btn_bg"
             android:src="@drawable/ic_magnification_menu_large"
             android:tint="@color/accessibility_magnification_image_button_tint"
-            android:tintMode="src_atop" />
+            android:tintMode="src_atop"
+            android:contentDescription="@string/accessibility_magnification_large" />
 
         <ImageButton
             android:id="@+id/magnifier_full_button"
@@ -96,15 +99,16 @@
             android:background="@drawable/accessibility_magnification_setting_view_image_btn_bg"
             android:src="@drawable/ic_open_in_full"
             android:tint="@color/accessibility_magnification_image_button_tint"
-            android:tintMode="src_atop" />
+            android:tintMode="src_atop"
+            android:contentDescription="@string/accessibility_magnification_fullscreen" />
     </LinearLayout>
 
     <LinearLayout
+        android:id="@+id/magnifier_horizontal_lock_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:layout_marginTop="@dimen/magnification_setting_view_margin"
-        android:layout_marginBottom="@dimen/magnification_setting_view_margin"
         android:focusable="true">
 
         <TextView
@@ -132,6 +136,7 @@
         android:layout_height="wrap_content"
         android:text="@string/accessibility_magnification_zoom"
         android:textAppearance="@style/TextAppearance.MagnificationSetting.Title"
+        android:layout_marginTop="@dimen/magnification_setting_view_margin"
         android:focusable="true" />
 
     <com.android.systemui.common.ui.view.SeekBarWithIconButtonsView
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 0d638f6..96e6d4e 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -162,7 +162,6 @@
 
     <!-- Window magnification colors -->
     <color name="magnification_border_color">#F29900</color>
-    <color name="magnification_switch_button_color">#7F000000</color>
     <color name="magnification_drag_corner_background">#E5FFFFFF</color>
     <color name="magnification_drag_handle_stroke">#000000</color>
     <color name="magnification_drag_handle_background_change">#111111</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3ab654f..249fc86 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1175,6 +1175,8 @@
     <dimen name="magnification_setting_image_button_padding_horizontal">24dp</dimen>
     <dimen name="magnification_setting_image_button_open_in_full_padding_vertical">16dp</dimen>
     <dimen name="magnification_setting_image_button_open_in_full_padding_horizontal">28dp</dimen>
+    <dimen name="magnification_setting_drag_corner_radius">28dp</dimen>
+    <dimen name="magnification_setting_drag_size">56dp</dimen>
 
     <!-- Seekbar with icon buttons -->
     <dimen name="seekbar_icon_size">24dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 2aa912c..e7be6fc 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2335,8 +2335,6 @@
     <string name="magnification_mode_switch_state_full_screen">Magnify full screen</string>
     <!-- A11y state description for magnification mode switch that device is in window mode. [CHAR LIMIT=NONE] -->
     <string name="magnification_mode_switch_state_window">Magnify part of screen</string>
-    <!-- Click action label for magnification switch. [CHAR LIMIT=NONE] -->
-    <string name="magnification_mode_switch_click_label">Switch</string>
     <!-- Click action label for magnification settings panel. [CHAR LIMIT=NONE] -->
     <string name="magnification_open_settings_click_label">Open magnification settings</string>
     <!-- Label of the corner of a rectangle that you can tap and drag to resize the magnification area. [CHAR LIMIT=NONE] -->
@@ -2372,6 +2370,8 @@
     <string name="accessibility_magnification_small">Small</string>
     <!-- Click action label for magnification panel large size [CHAR LIMIT=NONE]-->
     <string name="accessibility_magnification_large">Large</string>
+    <!-- Click action label for magnification panel full screen size [CHAR LIMIT=NONE]-->
+    <string name="accessibility_magnification_fullscreen">Full screen</string>
     <!-- Click action label for magnification panel Done [CHAR LIMIT=20]-->
     <string name="accessibility_magnification_done">Done</string>
     <!-- Click action label for edit magnification size [CHAR LIMIT=20]-->
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index 59a5b15..f817c3c 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -77,7 +77,7 @@
     private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
     private int mMagnificationMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
     private final LayoutParams mParams;
-    private final SwitchListener mSwitchListener;
+    private final ClickListener mClickListener;
     private final Configuration mConfiguration;
     @VisibleForTesting
     final Rect mDraggableWindowBounds = new Rect();
@@ -86,30 +86,28 @@
     private boolean mSingleTapDetected = false;
     private boolean mToLeftScreenEdge = false;
 
-    public interface SwitchListener {
+    public interface ClickListener {
         /**
          * Called when the switch is clicked to change the magnification mode.
          * @param displayId the display id of the display to which the view's window has been
          *                  attached
-         * @param magnificationMode the magnification mode
          */
-        void onSwitch(int displayId, int magnificationMode);
+        void onClick(int displayId);
     }
 
-    MagnificationModeSwitch(@UiContext Context context,
-            SwitchListener switchListener) {
-        this(context, createView(context), new SfVsyncFrameCallbackProvider(), switchListener);
+    MagnificationModeSwitch(@UiContext Context context, ClickListener clickListener) {
+        this(context, createView(context), new SfVsyncFrameCallbackProvider(), clickListener);
     }
 
     @VisibleForTesting
     MagnificationModeSwitch(Context context, @NonNull ImageView imageView,
-            SfVsyncFrameCallbackProvider sfVsyncFrameProvider, SwitchListener switchListener) {
+            SfVsyncFrameCallbackProvider sfVsyncFrameProvider, ClickListener clickListener) {
         mContext = context;
         mConfiguration = new Configuration(context.getResources().getConfiguration());
         mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
         mWindowManager = mContext.getSystemService(WindowManager.class);
         mSfVsyncFrameProvider = sfVsyncFrameProvider;
-        mSwitchListener = switchListener;
+        mClickListener = clickListener;
         mParams = createLayoutParams(context);
         mImageView = imageView;
         mImageView.setOnTouchListener(this::onTouch);
@@ -122,7 +120,7 @@
                         R.string.magnification_mode_switch_description));
                 final AccessibilityAction clickAction = new AccessibilityAction(
                         AccessibilityAction.ACTION_CLICK.getId(), mContext.getResources().getString(
-                        R.string.magnification_mode_switch_click_label));
+                        R.string.magnification_open_settings_click_label));
                 info.addAction(clickAction);
                 info.setClickable(true);
                 info.addAction(new AccessibilityAction(R.id.accessibility_action_move_up,
@@ -396,22 +394,14 @@
         }
     }
 
-    private void toggleMagnificationMode() {
-        final int newMode =
-                mMagnificationMode ^ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
-        mMagnificationMode = newMode;
-        mImageView.setImageResource(getIconResId(newMode));
-        mSwitchListener.onSwitch(mContext.getDisplayId(), newMode);
-    }
-
     private void handleSingleTap() {
         removeButton();
-        toggleMagnificationMode();
+        mClickListener.onClick(mContext.getDisplayId());
     }
 
     private static ImageView createView(Context context) {
         ImageView imageView = new ImageView(context);
-        imageView.setScaleType(ImageView.ScaleType.CENTER);
+        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
         imageView.setClickable(true);
         imageView.setFocusable(true);
         imageView.setAlpha(0f);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
new file mode 100644
index 0000000..b6ee4cb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility;
+
+import static com.android.systemui.accessibility.WindowMagnificationSettings.MagnificationSize;
+
+import android.annotation.NonNull;
+import android.annotation.UiContext;
+import android.content.ComponentCallbacks;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.util.Range;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
+import com.android.systemui.util.settings.SecureSettings;
+
+/**
+ * A class to control {@link WindowMagnificationSettings} and receive settings panel callbacks by
+ * {@link WindowMagnificationSettingsCallback}.
+ * The settings panel callbacks will be delegated through
+ * {@link MagnificationSettingsController.Callback} to {@link WindowMagnification}.
+ */
+
+public class MagnificationSettingsController implements ComponentCallbacks {
+
+    // It should be consistent with the value defined in WindowMagnificationGestureHandler.
+    private static final Range<Float> A11Y_ACTION_SCALE_RANGE = new Range<>(1.0f, 8.0f);
+
+    private final Context mContext;
+
+    private final int mDisplayId;
+
+    @NonNull
+    private final Callback mSettingsControllerCallback;
+
+    // Window Magnification Setting view
+    private WindowMagnificationSettings mWindowMagnificationSettings;
+
+    private final Configuration mConfiguration;
+
+    MagnificationSettingsController(
+            @UiContext Context context,
+            SfVsyncFrameCallbackProvider sfVsyncFrameProvider,
+            @NonNull Callback settingsControllerCallback,
+            SecureSettings secureSettings) {
+        this(context, sfVsyncFrameProvider, settingsControllerCallback,  secureSettings, null);
+    }
+
+    @VisibleForTesting
+    MagnificationSettingsController(
+            @UiContext Context context,
+            SfVsyncFrameCallbackProvider sfVsyncFrameProvider,
+            @NonNull Callback settingsControllerCallback,
+            SecureSettings secureSettings,
+            WindowMagnificationSettings windowMagnificationSettings) {
+        mContext = context;
+        mDisplayId = mContext.getDisplayId();
+        mConfiguration = new Configuration(context.getResources().getConfiguration());
+        mSettingsControllerCallback = settingsControllerCallback;
+        if (windowMagnificationSettings != null) {
+            mWindowMagnificationSettings = windowMagnificationSettings;
+        } else {
+            mWindowMagnificationSettings = new WindowMagnificationSettings(context,
+                    mWindowMagnificationSettingsCallback,
+                    sfVsyncFrameProvider, secureSettings);
+        }
+    }
+
+    /**
+     * Shows magnification settings panel {@link WindowMagnificationSettings}. The panel ui would be
+     * various for different magnification mode.
+     *
+     * @param mode      The magnification mode
+     * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
+     * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
+     */
+    void showMagnificationSettings(int mode) {
+        if (!mWindowMagnificationSettings.isSettingPanelShowing()) {
+            onConfigurationChanged(mContext.getResources().getConfiguration());
+            mContext.registerComponentCallbacks(this);
+        }
+        mWindowMagnificationSettings.showSettingPanel(mode);
+    }
+
+    void closeMagnificationSettings() {
+        mContext.unregisterComponentCallbacks(this);
+        mWindowMagnificationSettings.hideSettingPanel();
+    }
+
+    boolean isMagnificationSettingsShowing() {
+        return mWindowMagnificationSettings.isSettingPanelShowing();
+    }
+
+    @Override
+    public void onConfigurationChanged(@NonNull Configuration newConfig) {
+        final int configDiff = newConfig.diff(mConfiguration);
+        mConfiguration.setTo(newConfig);
+        onConfigurationChanged(configDiff);
+    }
+
+    @VisibleForTesting
+    void onConfigurationChanged(int configDiff) {
+        mWindowMagnificationSettings.onConfigurationChanged(configDiff);
+    }
+
+    @Override
+    public void onLowMemory() {
+
+    }
+
+    interface Callback {
+
+        /**
+         * Called when change magnification size.
+         *
+         * @param displayId The logical display id.
+         * @param index Magnification size index.
+         *     0 : MagnificationSize.NONE,
+         *     1 : MagnificationSize.SMALL,
+         *     2 : MagnificationSize.MEDIUM,
+         *     3 : MagnificationSize.LARGE,
+         *     4 : MagnificationSize.FULLSCREEN
+         */
+        void onSetMagnifierSize(int displayId, @MagnificationSize int index);
+
+        /**
+         * Called when set allow diagonal scrolling.
+         *
+         * @param displayId The logical display id.
+         * @param enable Allow diagonal scrolling enable value.
+         */
+        void onSetDiagonalScrolling(int displayId, boolean enable);
+
+        /**
+         * Called when change magnification size on free mode.
+         *
+         * @param displayId The logical display id.
+         * @param enable Free mode enable value.
+         */
+        void onEditMagnifierSizeMode(int displayId, boolean enable);
+
+        /**
+         * Called when set magnification scale.
+         *
+         * @param displayId The logical display id.
+         * @param scale Magnification scale value.
+         */
+        void onMagnifierScale(int displayId, float scale);
+
+        /**
+         * Called when magnification mode changed.
+         *
+         * @param displayId The logical display id.
+         * @param newMode Magnification mode
+         *      1 : ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
+         *      2 : ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
+         */
+        void onModeSwitch(int displayId, int newMode);
+
+        /**
+         * Called when the visibility of the magnification settings panel changed.
+         *
+         * @param displayId The logical display id.
+         * @param shown The visibility of the magnification settings panel.
+         */
+        void onSettingsPanelVisibilityChanged(int displayId, boolean shown);
+    }
+
+    @VisibleForTesting
+    final WindowMagnificationSettingsCallback mWindowMagnificationSettingsCallback =
+            new WindowMagnificationSettingsCallback() {
+                @Override
+        public void onSetDiagonalScrolling(boolean enable) {
+            mSettingsControllerCallback.onSetDiagonalScrolling(mDisplayId, enable);
+        }
+
+        @Override
+        public void onModeSwitch(int newMode) {
+            mSettingsControllerCallback.onModeSwitch(mDisplayId, newMode);
+        }
+
+        @Override
+        public void onSettingsPanelVisibilityChanged(boolean shown) {
+            mSettingsControllerCallback.onSettingsPanelVisibilityChanged(mDisplayId, shown);
+        }
+
+        @Override
+        public void onSetMagnifierSize(@MagnificationSize int index) {
+            mSettingsControllerCallback.onSetMagnifierSize(mDisplayId, index);
+        }
+
+        @Override
+        public void onEditMagnifierSizeMode(boolean enable) {
+            mSettingsControllerCallback.onEditMagnifierSizeMode(mDisplayId, enable);
+        }
+
+        @Override
+        public void onMagnifierScale(float scale) {
+            mSettingsControllerCallback.onMagnifierScale(mDisplayId,
+                    A11Y_ACTION_SCALE_RANGE.clamp(scale));
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java b/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java
index 0cc1b2d..63f9cc2 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/ModeSwitchesController.java
@@ -18,7 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
 
-import static com.android.systemui.accessibility.MagnificationModeSwitch.SwitchListener;
+import static com.android.systemui.accessibility.MagnificationModeSwitch.ClickListener;
 
 import android.annotation.MainThread;
 import android.content.Context;
@@ -37,19 +37,18 @@
  *   <li> Both full-screen and window magnification mode are capable.</li>
  *   <li> The magnification scale is changed by a user.</li>
  * <ol>
- * The switch action will be handled by {@link #mSwitchListenerDelegate} which informs the system
- * server about the changed mode.
+ * The click action will be handled by {@link #mClickListenerDelegate} which opens the
+ * {@link WindowMagnificationSettings} panel.
  */
 @SysUISingleton
-public class ModeSwitchesController implements SwitchListener {
+public class ModeSwitchesController implements ClickListener {
 
     private final DisplayIdIndexSupplier<MagnificationModeSwitch> mSwitchSupplier;
-    private SwitchListener mSwitchListenerDelegate;
+    private ClickListener mClickListenerDelegate;
 
     @Inject
-    public ModeSwitchesController(Context context) {
-        mSwitchSupplier = new SwitchSupplier(context,
-                context.getSystemService(DisplayManager.class), this::onSwitch);
+    public ModeSwitchesController(Context context, DisplayManager displayManager) {
+        mSwitchSupplier = new SwitchSupplier(context, displayManager, this::onClick);
     }
 
     @VisibleForTesting
@@ -102,40 +101,40 @@
     }
 
     @Override
-    public void onSwitch(int displayId, int magnificationMode) {
-        if (mSwitchListenerDelegate != null) {
-            mSwitchListenerDelegate.onSwitch(displayId, magnificationMode);
+    public void onClick(int displayId) {
+        if (mClickListenerDelegate != null) {
+            mClickListenerDelegate.onClick(displayId);
         }
     }
 
-    public void setSwitchListenerDelegate(SwitchListener switchListenerDelegate) {
-        mSwitchListenerDelegate = switchListenerDelegate;
+    public void setClickListenerDelegate(ClickListener clickListenerDelegate) {
+        mClickListenerDelegate = clickListenerDelegate;
     }
 
     private static class SwitchSupplier extends DisplayIdIndexSupplier<MagnificationModeSwitch> {
 
         private final Context mContext;
-        private final SwitchListener mSwitchListener;
+        private final ClickListener mClickListener;
 
         /**
          * Supplies the switch for the given display.
          *
          * @param context        Context
          * @param displayManager DisplayManager
-         * @param switchListener The callback that will run when the switch is clicked
+         * @param clickListener The callback that will run when the switch is clicked
          */
         SwitchSupplier(Context context, DisplayManager displayManager,
-                SwitchListener switchListener) {
+                ClickListener clickListener) {
             super(displayManager);
             mContext = context;
-            mSwitchListener = switchListener;
+            mClickListener = clickListener;
         }
 
         @Override
         protected MagnificationModeSwitch createInstance(Display display) {
             final Context uiContext = mContext.createWindowContext(display,
                     TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, /* options */ null);
-            return new MagnificationModeSwitch(uiContext, mSwitchListener);
+            return new MagnificationModeSwitch(uiContext, mClickListener);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index 3653bc8..1c030da 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.accessibility;
 
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
 
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
@@ -55,8 +57,7 @@
  * when {@code IStatusBar#requestWindowMagnificationConnection(boolean)} is called.
  */
 @SysUISingleton
-public class WindowMagnification implements CoreStartable, WindowMagnifierCallback,
-        CommandQueue.Callbacks {
+public class WindowMagnification implements CoreStartable, CommandQueue.Callbacks {
     private static final String TAG = "WindowMagnification";
 
     private final ModeSwitchesController mModeSwitchesController;
@@ -113,11 +114,45 @@
     @VisibleForTesting
     DisplayIdIndexSupplier<WindowMagnificationController> mMagnificationControllerSupplier;
 
+    private static class SettingsSupplier extends
+            DisplayIdIndexSupplier<MagnificationSettingsController> {
+
+        private final Context mContext;
+        private final MagnificationSettingsController.Callback mSettingsControllerCallback;
+        private final SecureSettings mSecureSettings;
+
+        SettingsSupplier(Context context,
+                MagnificationSettingsController.Callback settingsControllerCallback,
+                DisplayManager displayManager,
+                SecureSettings secureSettings) {
+            super(displayManager);
+            mContext = context;
+            mSettingsControllerCallback = settingsControllerCallback;
+            mSecureSettings = secureSettings;
+        }
+
+        @Override
+        protected MagnificationSettingsController createInstance(Display display) {
+            final Context windowContext = mContext.createWindowContext(display,
+                    TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, /* options */ null);
+            windowContext.setTheme(com.android.systemui.R.style.Theme_SystemUI);
+            return new MagnificationSettingsController(
+                    windowContext,
+                    new SfVsyncFrameCallbackProvider(),
+                    mSettingsControllerCallback,
+                    mSecureSettings);
+        }
+    }
+
+    @VisibleForTesting
+    DisplayIdIndexSupplier<MagnificationSettingsController> mMagnificationSettingsSupplier;
+
     @Inject
     public WindowMagnification(Context context, @Main Handler mainHandler,
             CommandQueue commandQueue, ModeSwitchesController modeSwitchesController,
             SysUiState sysUiState, OverviewProxyService overviewProxyService,
-            SecureSettings secureSettings, DisplayTracker displayTracker) {
+            SecureSettings secureSettings, DisplayTracker displayTracker,
+            DisplayManager displayManager) {
         mContext = context;
         mHandler = mainHandler;
         mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
@@ -127,8 +162,16 @@
         mOverviewProxyService = overviewProxyService;
         mDisplayTracker = displayTracker;
         mMagnificationControllerSupplier = new ControllerSupplier(context,
-                mHandler, this, context.getSystemService(DisplayManager.class), sysUiState,
-                secureSettings);
+                mHandler, mWindowMagnifierCallback,
+                displayManager, sysUiState, secureSettings);
+        mMagnificationSettingsSupplier = new SettingsSupplier(context,
+                mMagnificationSettingsControllerCallback, displayManager, secureSettings);
+
+        mModeSwitchesController.setClickListenerDelegate(
+                displayId -> mHandler.post(() -> {
+                    showMagnificationSettingsPanel(displayId,
+                            ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+                }));
     }
 
     @Override
@@ -209,45 +252,181 @@
         }
     }
 
-    @Override
-    public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) {
-        if (mWindowMagnificationConnectionImpl != null) {
-            mWindowMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame);
+    @MainThread
+    void showMagnificationSettingsPanel(int displayId, int mode) {
+        final MagnificationSettingsController magnificationSettingsController =
+                mMagnificationSettingsSupplier.get(displayId);
+        if (magnificationSettingsController != null) {
+            magnificationSettingsController.showMagnificationSettings(mode);
         }
     }
 
-    @Override
-    public void onSourceBoundsChanged(int displayId, Rect sourceBounds) {
-        if (mWindowMagnificationConnectionImpl != null) {
-            mWindowMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds);
+    @MainThread
+    void hideMagnificationSettingsPanel(int displayId) {
+        final MagnificationSettingsController magnificationSettingsController =
+                mMagnificationSettingsSupplier.get(displayId);
+        if (magnificationSettingsController != null) {
+            magnificationSettingsController.closeMagnificationSettings();
         }
     }
 
-    @Override
-    public void onPerformScaleAction(int displayId, float scale) {
-        if (mWindowMagnificationConnectionImpl != null) {
-            mWindowMagnificationConnectionImpl.onPerformScaleAction(displayId, scale);
+    boolean isMagnificationSettingsPanelShowing(int displayId) {
+        final MagnificationSettingsController magnificationSettingsController =
+                mMagnificationSettingsSupplier.get(displayId);
+        if (magnificationSettingsController != null) {
+            return magnificationSettingsController.isMagnificationSettingsShowing();
+        }
+        return false;
+    }
+
+    @MainThread
+    void showMagnificationButton(int displayId, int magnificationMode) {
+        // not to show mode switch button if settings panel is already showing to
+        // prevent settings panel be covered by the button.
+        if (isMagnificationSettingsPanelShowing(displayId)) {
+            return;
+        }
+        mModeSwitchesController.showButton(displayId, magnificationMode);
+    }
+
+    @MainThread
+    void removeMagnificationButton(int displayId) {
+        mModeSwitchesController.removeButton(displayId);
+    }
+
+    @VisibleForTesting
+    final WindowMagnifierCallback mWindowMagnifierCallback = new WindowMagnifierCallback() {
+        @Override
+        public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) {
+            if (mWindowMagnificationConnectionImpl != null) {
+                mWindowMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame);
+            }
+        }
+
+        @Override
+        public void onSourceBoundsChanged(int displayId, Rect sourceBounds) {
+            if (mWindowMagnificationConnectionImpl != null) {
+                mWindowMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds);
+            }
+        }
+
+        @Override
+        public void onPerformScaleAction(int displayId, float scale) {
+            if (mWindowMagnificationConnectionImpl != null) {
+                mWindowMagnificationConnectionImpl.onPerformScaleAction(displayId, scale);
+            }
+        }
+
+        @Override
+        public void onAccessibilityActionPerformed(int displayId) {
+            if (mWindowMagnificationConnectionImpl != null) {
+                mWindowMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId);
+            }
+        }
+
+        @Override
+        public void onMove(int displayId) {
+            if (mWindowMagnificationConnectionImpl != null) {
+                mWindowMagnificationConnectionImpl.onMove(displayId);
+            }
+        }
+
+        @Override
+        public void onClickSettingsButton(int displayId) {
+            mHandler.post(() -> {
+                showMagnificationSettingsPanel(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+            });
+        }
+    };
+
+    @VisibleForTesting
+    final MagnificationSettingsController.Callback mMagnificationSettingsControllerCallback =
+            new MagnificationSettingsController.Callback() {
+        @Override
+        public void onSetMagnifierSize(int displayId, int index) {
+            mHandler.post(() -> onSetMagnifierSizeInternal(displayId, index));
+        }
+
+        @Override
+        public void onSetDiagonalScrolling(int displayId, boolean enable) {
+            mHandler.post(() -> onSetDiagonalScrollingInternal(displayId, enable));
+        }
+
+        @Override
+        public void onEditMagnifierSizeMode(int displayId, boolean enable) {
+            mHandler.post(() -> onEditMagnifierSizeModeInternal(displayId, enable));
+        }
+
+        @Override
+        public void onMagnifierScale(int displayId, float scale) {
+            if (mWindowMagnificationConnectionImpl != null) {
+                mWindowMagnificationConnectionImpl.onPerformScaleAction(displayId, scale);
+            }
+        }
+
+        @Override
+        public void onModeSwitch(int displayId, int newMode) {
+            mHandler.post(() -> onModeSwitchInternal(displayId, newMode));
+        }
+
+        @Override
+        public void onSettingsPanelVisibilityChanged(int displayId, boolean shown) {
+            mHandler.post(() -> onSettingsPanelVisibilityChangedInternal(displayId, shown));
+        }
+    };
+
+    @MainThread
+    private void onSetMagnifierSizeInternal(int displayId, int index) {
+        final WindowMagnificationController windowMagnificationController =
+                mMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            windowMagnificationController.changeMagnificationSize(index);
         }
     }
 
-    @Override
-    public void onAccessibilityActionPerformed(int displayId) {
-        if (mWindowMagnificationConnectionImpl != null) {
-            mWindowMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId);
+    @MainThread
+    private void onSetDiagonalScrollingInternal(int displayId, boolean enable) {
+        final WindowMagnificationController windowMagnificationController =
+                mMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            windowMagnificationController.setDiagonalScrolling(enable);
         }
     }
 
-    @Override
-    public void onMove(int displayId) {
-        if (mWindowMagnificationConnectionImpl != null) {
-            mWindowMagnificationConnectionImpl.onMove(displayId);
+    @MainThread
+    private void onEditMagnifierSizeModeInternal(int displayId, boolean enable) {
+        final WindowMagnificationController windowMagnificationController =
+                mMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null && windowMagnificationController.isActivated()) {
+            windowMagnificationController.setEditMagnifierSizeMode(enable);
         }
     }
 
-    @Override
-    public void onModeSwitch(int displayId, int newMode) {
-        if (mWindowMagnificationConnectionImpl != null) {
-            mWindowMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode);
+    @MainThread
+    private void onModeSwitchInternal(int displayId, int newMode) {
+        final WindowMagnificationController windowMagnificationController =
+                mMagnificationControllerSupplier.get(displayId);
+        final boolean isWindowMagnifierActivated = windowMagnificationController.isActivated();
+        final boolean isSwitchToWindowMode = (newMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        final boolean changed = isSwitchToWindowMode ^ isWindowMagnifierActivated;
+        if (changed) {
+            final MagnificationSettingsController magnificationSettingsController =
+                    mMagnificationSettingsSupplier.get(displayId);
+            if (magnificationSettingsController != null) {
+                magnificationSettingsController.closeMagnificationSettings();
+            }
+            if (mWindowMagnificationConnectionImpl != null) {
+                mWindowMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode);
+            }
+        }
+    }
+
+    @MainThread
+    private void onSettingsPanelVisibilityChangedInternal(int displayId, boolean shown) {
+        final WindowMagnificationController windowMagnificationController =
+                mMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null && windowMagnificationController.isActivated()) {
+            windowMagnificationController.updateDragHandleResourcesIfNeeded(shown);
         }
     }
 
@@ -270,17 +449,14 @@
     private void setWindowMagnificationConnection() {
         if (mWindowMagnificationConnectionImpl == null) {
             mWindowMagnificationConnectionImpl = new WindowMagnificationConnectionImpl(this,
-                    mHandler, mModeSwitchesController);
+                    mHandler);
         }
-        mModeSwitchesController.setSwitchListenerDelegate(
-                mWindowMagnificationConnectionImpl::onChangeMagnificationMode);
         mAccessibilityManager.setWindowMagnificationConnection(
                 mWindowMagnificationConnectionImpl);
     }
 
     private void clearWindowMagnificationConnection() {
         mAccessibilityManager.setWindowMagnificationConnection(null);
-        mModeSwitchesController.setSwitchListenerDelegate(null);
         //TODO: destroy controllers.
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
index aa684fa..c081893 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
@@ -39,13 +39,11 @@
     private IWindowMagnificationConnectionCallback mConnectionCallback;
     private final WindowMagnification mWindowMagnification;
     private final Handler mHandler;
-    private final ModeSwitchesController mModeSwitchesController;
 
     WindowMagnificationConnectionImpl(@NonNull WindowMagnification windowMagnification,
-            @Main Handler mainHandler, ModeSwitchesController modeSwitchesController) {
+            @Main Handler mainHandler) {
         mWindowMagnification = windowMagnification;
         mHandler = mainHandler;
-        mModeSwitchesController = modeSwitchesController;
     }
 
     @Override
@@ -86,13 +84,18 @@
     @Override
     public void showMagnificationButton(int displayId, int magnificationMode) {
         mHandler.post(
-                () -> mModeSwitchesController.showButton(displayId, magnificationMode));
+                () -> mWindowMagnification.showMagnificationButton(displayId, magnificationMode));
     }
 
     @Override
     public void removeMagnificationButton(int displayId) {
         mHandler.post(
-                () -> mModeSwitchesController.removeButton(displayId));
+                () -> mWindowMagnification.removeMagnificationButton(displayId));
+    }
+
+    @Override
+    public void removeMagnificationSettingsPanel(int display) {
+        mHandler.post(() -> mWindowMagnification.hideMagnificationSettingsPanel(display));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 57c9918..a67f706 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -51,6 +51,7 @@
 import android.util.Log;
 import android.util.Range;
 import android.util.Size;
+import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.Choreographer;
 import android.view.Display;
@@ -103,7 +104,7 @@
     private static final Range<Float> A11Y_ACTION_SCALE_RANGE = new Range<>(1.0f, 8.0f);
     private static final float A11Y_CHANGE_SCALE_DIFFERENCE = 1.0f;
     private static final float ANIMATION_BOUNCE_EFFECT_SCALE = 1.05f;
-    private static final float[] MAGNIFICATION_SCALE_OPTIONS = {1.0f, 1.4f, 1.8f, 2.5f};
+    private final SparseArray<Float> mMagnificationSizeScaleOptions = new SparseArray<>();
 
     private final Context mContext;
     private final Resources mResources;
@@ -210,9 +211,6 @@
     private boolean mOverlapWithGestureInsets;
     private boolean mIsDragging;
 
-    // Window Magnification Setting view
-    private WindowMagnificationSettings mWindowMagnificationSettings;
-
     private static final int MAX_HORIZONTAL_MOVE_ANGLE = 50;
     private static final int HORIZONTAL = 1;
     private static final int VERTICAL = 0;
@@ -261,6 +259,7 @@
                 mResources.getInteger(R.integer.magnification_default_scale),
                 UserHandle.USER_CURRENT);
 
+        setupMagnificationSizeScaleOptions();
 
         mBounceEffectDuration = mResources.getInteger(
                 com.android.internal.R.integer.config_shortAnimTime);
@@ -279,10 +278,6 @@
         mGestureDetector =
                 new MagnificationGestureDetector(mContext, handler, this);
 
-        mWindowMagnificationSettings =
-                new WindowMagnificationSettings(mContext, mWindowMagnificationSettingsCallback,
-                        mSfVsyncFrameProvider, secureSettings);
-
         // Initialize listeners.
         mMirrorViewRunnable = () -> {
             if (mMirrorView != null) {
@@ -311,7 +306,7 @@
 
         mMirrorViewGeometryVsyncCallback =
                 l -> {
-                    if (isWindowVisible() && mMirrorSurface != null && calculateSourceBounds(
+                    if (isActivated() && mMirrorSurface != null && calculateSourceBounds(
                             mMagnificationFrame, mScale)) {
                         // The final destination for the magnification surface should be at 0,0
                         // since the ViewRootImpl's position will change
@@ -328,13 +323,20 @@
                     }
                 };
         mUpdateStateDescriptionRunnable = () -> {
-            if (isWindowVisible()) {
+            if (isActivated()) {
                 mMirrorView.setStateDescription(formatStateDescription(mScale));
             }
         };
         mWindowInsetChangeRunnable = this::onWindowInsetChanged;
     }
 
+    private void setupMagnificationSizeScaleOptions() {
+        mMagnificationSizeScaleOptions.clear();
+        mMagnificationSizeScaleOptions.put(MagnificationSize.SMALL, 1.4f);
+        mMagnificationSizeScaleOptions.put(MagnificationSize.MEDIUM, 1.8f);
+        mMagnificationSizeScaleOptions.put(MagnificationSize.LARGE, 2.5f);
+    }
+
     private void updateDimensions() {
         mMirrorSurfaceMargin = mResources.getDimensionPixelSize(
                 R.dimen.magnification_mirror_surface_margin);
@@ -368,25 +370,27 @@
         return false;
     }
 
-    @VisibleForTesting
     void changeMagnificationSize(@MagnificationSize int index) {
+        if (!mMagnificationSizeScaleOptions.contains(index)) {
+            return;
+        }
+        final float scale = mMagnificationSizeScaleOptions.get(index, 1.0f);
         final int initSize = Math.min(mWindowBounds.width(), mWindowBounds.height()) / 3;
-        int size = (int) (initSize * MAGNIFICATION_SCALE_OPTIONS[index]);
+        int size = (int) (initSize * scale);
         setWindowSize(size, size);
     }
 
-    @VisibleForTesting
     void setEditMagnifierSizeMode(boolean enable) {
         mEditSizeEnable = enable;
         applyResourcesValues();
 
-        if (isWindowVisible()) {
+        if (isActivated()) {
             updateDimensions();
             applyTapExcludeRegion();
         }
     }
 
-    private void setDiagonalScrolling(boolean enable) {
+    void setDiagonalScrolling(boolean enable) {
         mAllowDiagonalScrolling = enable;
     }
 
@@ -403,22 +407,14 @@
         mAnimationController.deleteWindowMagnification(animationCallback);
     }
 
-    void deleteWindowMagnification() {
-        deleteWindowMagnification(/* closeSettingPanel= */ true);
-    }
-
     /**
      * Deletes the magnification window.
      */
-    void deleteWindowMagnification(boolean closeSettingPanel) {
-        if (!isWindowVisible()) {
+    void deleteWindowMagnification() {
+        if (!isActivated()) {
             return;
         }
 
-        if (closeSettingPanel) {
-            closeMagnificationSettings();
-        }
-
         if (mMirrorSurface != null) {
             mTransaction.remove(mMirrorSurface).apply();
             mMirrorSurface = null;
@@ -453,7 +449,6 @@
         final int configDiff = newConfig.diff(mConfiguration);
         mConfiguration.setTo(newConfig);
         onConfigurationChanged(configDiff);
-        mWindowMagnificationSettings.onConfigurationChanged(configDiff);
     }
 
     @Override
@@ -494,8 +489,8 @@
 
         // Recreate the window again to correct the window appearance due to density or
         // window size changed not caused by rotation.
-        if (isWindowVisible() && reCreateWindow) {
-            deleteWindowMagnification(/* closeSettingPanel= */ false);
+        if (isActivated() && reCreateWindow) {
+            deleteWindowMagnification();
             enableWindowMagnificationInternal(Float.NaN, Float.NaN, Float.NaN);
         }
     }
@@ -532,7 +527,7 @@
     }
 
     private void updateAccessibilityWindowTitleIfNeeded() {
-        if (!isWindowVisible()) return;
+        if (!isActivated()) return;
         LayoutParams params = (LayoutParams) mMirrorView.getLayoutParams();
         params.accessibilityTitle = getAccessibilityWindowTitle();
         mWm.updateViewLayout(mMirrorView, params);
@@ -703,23 +698,6 @@
         }
     }
 
-    private void showMagnificationSettings() {
-        if (mWindowMagnificationSettings != null) {
-            mWindowMagnificationSettings.showSettingPanel();
-        }
-    }
-
-    private void closeMagnificationSettings() {
-        if (mWindowMagnificationSettings != null) {
-            mWindowMagnificationSettings.hideSettingPanel();
-        }
-    }
-
-    @VisibleForTesting
-    WindowMagnificationSettings getMagnificationSettings() {
-        return mWindowMagnificationSettings;
-    }
-
     /**
      * Sets the window size with given width and height in pixels without changing the
      * window center. The width or the height will be clamped in the range
@@ -845,7 +823,7 @@
      * {@link #mMagnificationFrame}.
      */
     private void updateMirrorViewLayout(boolean computeWindowSize) {
-        if (!isWindowVisible()) {
+        if (!isActivated()) {
             return;
         }
         final int maxMirrorViewX = mWindowBounds.width() - mMirrorView.getWidth();
@@ -1018,7 +996,7 @@
     }
 
     private void updateSysUIState(boolean force) {
-        final boolean overlap = isWindowVisible() && mSystemGestureTop > 0
+        final boolean overlap = isActivated() && mSystemGestureTop > 0
                 && mMirrorViewBounds.bottom > mSystemGestureTop;
         if (force || overlap != mOverlapWithGestureInsets) {
             mOverlapWithGestureInsets = overlap;
@@ -1113,7 +1091,7 @@
             deleteWindowMagnification();
             return;
         }
-        if (!isWindowVisible()) {
+        if (!isActivated()) {
             onConfigurationChanged(mResources.getConfiguration());
             mContext.registerComponentCallbacks(this);
         }
@@ -1138,7 +1116,7 @@
 
         calculateMagnificationFrameBoundary();
         updateMagnificationFramePosition((int) offsetX, (int) offsetY);
-        if (!isWindowVisible()) {
+        if (!isActivated()) {
             createMirrorWindow();
             showControls();
             applyResourcesValues();
@@ -1147,13 +1125,19 @@
         }
     }
 
+    // The magnifier is activated when the window is visible,
+    // and the window is visible when it is existed.
+    boolean isActivated() {
+        return mMirrorView != null;
+    }
+
     /**
      * Sets the scale of the magnified region if it's visible.
      *
      * @param scale the target scale, or {@link Float#NaN} to leave unchanged
      */
     void setScale(float scale) {
-        if (mAnimationController.isAnimating() || !isWindowVisible() || mScale == scale) {
+        if (mAnimationController.isAnimating() || !isActivated() || mScale == scale) {
             return;
         }
 
@@ -1216,7 +1200,7 @@
      * @return {@link Float#NaN} if the window is invisible.
      */
     float getScale() {
-        return isWindowVisible() ? mScale : Float.NaN;
+        return isActivated() ? mScale : Float.NaN;
     }
 
     /**
@@ -1225,7 +1209,7 @@
      * @return the X coordinate. {@link Float#NaN} if the window is invisible.
      */
     float getCenterX() {
-        return isWindowVisible() ? mMagnificationFrame.exactCenterX() : Float.NaN;
+        return isActivated() ? mMagnificationFrame.exactCenterX() : Float.NaN;
     }
 
     /**
@@ -1234,12 +1218,7 @@
      * @return the Y coordinate. {@link Float#NaN} if the window is invisible.
      */
     float getCenterY() {
-        return isWindowVisible() ? mMagnificationFrame.exactCenterY() : Float.NaN;
-    }
-
-    //The window is visible when it is existed.
-    private boolean isWindowVisible() {
-        return mMirrorView != null;
+        return isActivated() ? mMagnificationFrame.exactCenterY() : Float.NaN;
     }
 
     private CharSequence formatStateDescription(float scale) {
@@ -1273,7 +1252,7 @@
     private void handleSingleTap(View view) {
         int id = view.getId();
         if (id == R.id.drag_handle) {
-            showMagnificationSettings();
+            mWindowMagnifierCallback.onClickSettingsButton(mDisplayId);
         } else if (id == R.id.close_button) {
             setEditMagnifierSizeMode(false);
         } else {
@@ -1379,40 +1358,6 @@
                 == Configuration.SCREENLAYOUT_LAYOUTDIR_RTL;
     }
 
-    private WindowMagnificationSettingsCallback mWindowMagnificationSettingsCallback =
-            new WindowMagnificationSettingsCallback() {
-        @Override
-        public void onSetDiagonalScrolling(boolean enable) {
-            setDiagonalScrolling(enable);
-        }
-
-        @Override
-        public void onModeSwitch(int newMode) {
-            mWindowMagnifierCallback.onModeSwitch(mDisplayId, newMode);
-        }
-
-        @Override
-        public void onSetMagnifierSize(@MagnificationSize int index) {
-            changeMagnificationSize(index);
-        }
-
-        @Override
-        public void onEditMagnifierSizeMode(boolean enable) {
-            setEditMagnifierSizeMode(enable);
-        }
-
-        @Override
-        public void onMagnifierScale(float scale) {
-            mWindowMagnifierCallback.onPerformScaleAction(mDisplayId,
-                    A11Y_ACTION_SCALE_RANGE.clamp(scale));
-        }
-
-        @Override
-        public void onSettingsPanelVisibilityChanged(boolean shown) {
-            updateDragHandleResourcesIfNeeded(/* settingsPanelIsShown= */ shown);
-        }
-    };
-
     @Override
     public boolean onStart(float x, float y) {
         mIsDragging = true;
@@ -1449,7 +1394,11 @@
         }
     }
 
-    private void updateDragHandleResourcesIfNeeded(boolean settingsPanelIsShown) {
+    void updateDragHandleResourcesIfNeeded(boolean settingsPanelIsShown) {
+        if (!isActivated()) {
+            return;
+        }
+
         mDragView.setBackground(mContext.getResources().getDrawable(settingsPanelIsShown
                 ? R.drawable.accessibility_window_magnification_drag_handle_background_change
                 : R.drawable.accessibility_window_magnification_drag_handle_background));
@@ -1476,11 +1425,11 @@
         pw.println("      mOverlapWithGestureInsets:" + mOverlapWithGestureInsets);
         pw.println("      mScale:" + mScale);
         pw.println("      mWindowBounds:" + mWindowBounds);
-        pw.println("      mMirrorViewBounds:" + (isWindowVisible() ? mMirrorViewBounds : "empty"));
+        pw.println("      mMirrorViewBounds:" + (isActivated() ? mMirrorViewBounds : "empty"));
         pw.println("      mMagnificationFrameBoundary:"
-                + (isWindowVisible() ? mMagnificationFrameBoundary : "empty"));
+                + (isActivated() ? mMagnificationFrameBoundary : "empty"));
         pw.println("      mMagnificationFrame:"
-                + (isWindowVisible() ? mMagnificationFrame : "empty"));
+                + (isActivated() ? mMagnificationFrame : "empty"));
         pw.println("      mSourceBounds:"
                 + (mSourceBounds.isEmpty() ? "empty" : mSourceBounds));
         pw.println("      mSystemGestureTop:" + mSystemGestureTop);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index d9f5544..71c5f24 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -17,6 +17,8 @@
 package com.android.systemui.accessibility;
 
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
 import android.annotation.IntDef;
@@ -82,6 +84,7 @@
     private boolean mSingleTapDetected = false;
 
     private SeekBarWithIconButtonsView mZoomSeekbar;
+    private LinearLayout mAllowDiagonalScrollingView;
     private Switch mAllowDiagonalScrollingSwitch;
     private LinearLayout mPanelView;
     private LinearLayout mSettingView;
@@ -91,19 +94,23 @@
     private ImageButton mLargeButton;
     private Button mDoneButton;
     private Button mEditButton;
-    private ImageButton mChangeModeButton;
+    private ImageButton mFullScreenButton;
     private int mLastSelectedButtonIndex = MagnificationSize.NONE;
     private boolean mAllowDiagonalScrolling = false;
     private static final float A11Y_CHANGE_SCALE_DIFFERENCE = 1.0f;
     private static final float A11Y_SCALE_MIN_VALUE = 1.0f;
     private WindowMagnificationSettingsCallback mCallback;
 
+    // the magnification mode that triggers showing the panel
+    private int mTriggeringMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
+
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
             MagnificationSize.NONE,
             MagnificationSize.SMALL,
             MagnificationSize.MEDIUM,
             MagnificationSize.LARGE,
+            MagnificationSize.FULLSCREEN
     })
     /** Denotes the Magnification size type. */
     public @interface MagnificationSize {
@@ -111,6 +118,7 @@
         int SMALL = 1;
         int MEDIUM = 2;
         int LARGE = 3;
+        int FULLSCREEN = 4;
     }
 
     @VisibleForTesting
@@ -162,39 +170,11 @@
         }
     }
 
-    private CharSequence formatContentDescription(int viewId) {
-        if (viewId == R.id.magnifier_small_button) {
-            return mContext.getResources().getString(
-                    R.string.accessibility_magnification_small);
-        } else if (viewId == R.id.magnifier_medium_button) {
-            return mContext.getResources().getString(
-                    R.string.accessibility_magnification_medium);
-        } else if (viewId == R.id.magnifier_large_button) {
-            return mContext.getResources().getString(
-                    R.string.accessibility_magnification_large);
-        } else if (viewId == R.id.magnifier_done_button) {
-            return mContext.getResources().getString(
-                    R.string.accessibility_magnification_done);
-        } else if (viewId == R.id.magnifier_edit_button) {
-            return mContext.getResources().getString(
-                    R.string.accessibility_resize);
-        } else {
-            return mContext.getResources().getString(
-                    R.string.magnification_mode_switch_description);
-        }
-    }
-
-    private final AccessibilityDelegate mButtonDelegate = new AccessibilityDelegate() {
+    private final AccessibilityDelegate mPanelDelegate = new AccessibilityDelegate() {
         @Override
         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
             super.onInitializeAccessibilityNodeInfo(host, info);
 
-            info.setContentDescription(formatContentDescription(host.getId()));
-            final AccessibilityAction clickAction = new AccessibilityAction(
-                    AccessibilityAction.ACTION_CLICK.getId(), mContext.getResources().getString(
-                    R.string.magnification_mode_switch_click_label));
-            info.addAction(clickAction);
-            info.setClickable(true);
             info.addAction(new AccessibilityAction(R.id.accessibility_action_move_up,
                     mContext.getString(R.string.accessibility_control_move_up)));
             info.addAction(new AccessibilityAction(R.id.accessibility_action_move_down,
@@ -247,13 +227,12 @@
                 setMagnifierSize(MagnificationSize.MEDIUM);
             } else if (id == R.id.magnifier_large_button) {
                 setMagnifierSize(MagnificationSize.LARGE);
+            } else if (id == R.id.magnifier_full_button) {
+                setMagnifierSize(MagnificationSize.FULLSCREEN);
             } else if (id == R.id.magnifier_edit_button) {
                 editMagnifierSizeMode(true);
             } else if (id == R.id.magnifier_done_button) {
                 hideSettingPanel();
-            } else if (id == R.id.magnifier_full_button) {
-                hideSettingPanel();
-                toggleMagnificationMode();
             }
         }
     };
@@ -278,7 +257,7 @@
     @Override
     public boolean onFinish(float xOffset, float yOffset) {
         if (!mSingleTapDetected) {
-            showSettingPanel();
+            showSettingPanel(mTriggeringMode);
         }
         mSingleTapDetected = false;
         return true;
@@ -318,27 +297,43 @@
         mCallback.onSettingsPanelVisibilityChanged(/* shown= */ false);
     }
 
-    public void showSettingPanel() {
-        showSettingPanel(true);
+    /**
+     * Shows magnification settings panel. The panel ui would be various for
+     * different magnification mode.
+     *
+     * @param mode      The magnification mode
+     * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
+     * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
+     */
+    public void showSettingPanel(int mode) {
+        showSettingPanel(mode, true);
+    }
+
+    public boolean isSettingPanelShowing() {
+        return mIsVisible;
     }
 
     public void setScaleSeekbar(float scale) {
         setSeekbarProgress(scale);
     }
 
-    private void toggleMagnificationMode() {
-        mCallback.onModeSwitch(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+    private void transitToMagnificationMode(int mode) {
+        mCallback.onModeSwitch(mode);
     }
 
     /**
-     * Shows magnification panel for set window magnification.
+     * Shows magnification panel for set magnification.
      * When the panel is going to be visible by calling this method, the layout position can be
      * reset depending on the flag.
      *
+     * @param mode The magnification mode
      * @param resetPosition if the button position needs be reset
      */
-    private void showSettingPanel(boolean resetPosition) {
+    private void showSettingPanel(int mode, boolean resetPosition) {
         if (!mIsVisible) {
+            updateUIControlsIfNeed(mode);
+            mTriggeringMode = mode;
+
             if (resetPosition) {
                 mDraggableWindowBounds.set(getDraggableWindowBounds());
                 mParams.x = mDraggableWindowBounds.right;
@@ -355,6 +350,37 @@
         mContext.registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
     }
 
+    private void updateUIControlsIfNeed(int mode) {
+        if (mode == mTriggeringMode) {
+            return;
+        }
+
+        int selectedButtonIndex = mLastSelectedButtonIndex;
+        switch (mode) {
+            case ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN:
+                // set the edit button visibility to View.INVISIBLE to keep the height, to prevent
+                // the size title from too close to the size buttons
+                mEditButton.setVisibility(View.INVISIBLE);
+                mAllowDiagonalScrollingView.setVisibility(View.GONE);
+                // force the fullscreen button showing
+                selectedButtonIndex = MagnificationSize.FULLSCREEN;
+                break;
+
+            case ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
+                mEditButton.setVisibility(View.VISIBLE);
+                mAllowDiagonalScrollingView.setVisibility(View.VISIBLE);
+                if (selectedButtonIndex == MagnificationSize.FULLSCREEN) {
+                    selectedButtonIndex = MagnificationSize.NONE;
+                }
+                break;
+
+            default:
+                break;
+        }
+
+        updateSelectedButton(selectedButtonIndex);
+    }
+
     private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -378,13 +404,15 @@
         mSettingView.setFocusableInTouchMode(true);
         mSettingView.setOnTouchListener(this::onTouch);
 
+        mSettingView.setAccessibilityDelegate(mPanelDelegate);
+
         mPanelView = mSettingView.findViewById(R.id.magnifier_panel_view);
         mSmallButton = mSettingView.findViewById(R.id.magnifier_small_button);
         mMediumButton = mSettingView.findViewById(R.id.magnifier_medium_button);
         mLargeButton = mSettingView.findViewById(R.id.magnifier_large_button);
         mDoneButton = mSettingView.findViewById(R.id.magnifier_done_button);
         mEditButton = mSettingView.findViewById(R.id.magnifier_edit_button);
-        mChangeModeButton = mSettingView.findViewById(R.id.magnifier_full_button);
+        mFullScreenButton = mSettingView.findViewById(R.id.magnifier_full_button);
 
         mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_slider);
         float scale = mSecureSettings.getFloatForUser(
@@ -393,6 +421,8 @@
         setSeekbarProgress(scale);
         mZoomSeekbar.setOnSeekBarChangeListener(new ZoomSeekbarChangeListener());
 
+        mAllowDiagonalScrollingView =
+                (LinearLayout) mSettingView.findViewById(R.id.magnifier_horizontal_lock_view);
         mAllowDiagonalScrollingSwitch =
                 (Switch) mSettingView.findViewById(R.id.magnifier_horizontal_lock_switch);
         mAllowDiagonalScrollingSwitch.setChecked(mAllowDiagonalScrolling);
@@ -400,22 +430,11 @@
             toggleDiagonalScrolling();
         });
 
-        mSmallButton.setAccessibilityDelegate(mButtonDelegate);
         mSmallButton.setOnClickListener(mButtonClickListener);
-
-        mMediumButton.setAccessibilityDelegate(mButtonDelegate);
         mMediumButton.setOnClickListener(mButtonClickListener);
-
-        mLargeButton.setAccessibilityDelegate(mButtonDelegate);
         mLargeButton.setOnClickListener(mButtonClickListener);
-
-        mDoneButton.setAccessibilityDelegate(mButtonDelegate);
         mDoneButton.setOnClickListener(mButtonClickListener);
-
-        mChangeModeButton.setAccessibilityDelegate(mButtonDelegate);
-        mChangeModeButton.setOnClickListener(mButtonClickListener);
-
-        mEditButton.setAccessibilityDelegate(mButtonDelegate);
+        mFullScreenButton.setOnClickListener(mButtonClickListener);
         mEditButton.setOnClickListener(mButtonClickListener);
 
         mSettingView.setOnApplyWindowInsetsListener((v, insets) -> {
@@ -446,7 +465,7 @@
             hideSettingPanel(/* resetPosition= */ false);
             inflateView();
             if (showSettingPanelAfterThemeChange) {
-                showSettingPanel(/* resetPosition= */ false);
+                showSettingPanel(mTriggeringMode, /* resetPosition= */ false);
             }
             return;
         }
@@ -501,7 +520,18 @@
     }
 
     private void setMagnifierSize(@MagnificationSize int index) {
-        mCallback.onSetMagnifierSize(index);
+        if (index == MagnificationSize.FULLSCREEN) {
+            // transit to fullscreen magnifier if needed
+            transitToMagnificationMode(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+        } else if (index != MagnificationSize.NONE) {
+            // update the window magnifier size
+            mCallback.onSetMagnifierSize(index);
+            // transit to window magnifier if needed
+            transitToMagnificationMode(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        } else {
+            return;
+        }
+
         updateSelectedButton(index);
     }
 
@@ -573,6 +603,8 @@
             mMediumButton.setSelected(false);
         } else if (mLastSelectedButtonIndex == MagnificationSize.LARGE) {
             mLargeButton.setSelected(false);
+        } else if (mLastSelectedButtonIndex == MagnificationSize.FULLSCREEN) {
+            mFullScreenButton.setSelected(false);
         }
 
         // Set the state for selected button
@@ -582,6 +614,8 @@
             mMediumButton.setSelected(true);
         } else if (index == MagnificationSize.LARGE) {
             mLargeButton.setSelected(true);
+        } else if (index == MagnificationSize.FULLSCREEN) {
+            mFullScreenButton.setSelected(true);
         }
 
         mLastSelectedButtonIndex = index;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java
index 1d83340..3dbff5d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettingsCallback.java
@@ -29,7 +29,8 @@
      *
      * @param index Magnification size index.
      * 0 : MagnificationSize.NONE, 1 : MagnificationSize.SMALL,
-     * 2 : MagnificationSize.MEDIUM, 3: MagnificationSize.LARGE
+     * 2 : MagnificationSize.MEDIUM, 3: MagnificationSize.LARGE,
+     * 4 : MagnificationSize.FULLSCREEN
      */
     void onSetMagnifierSize(@MagnificationSize int index);
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
index 19caaf4..e18161d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
@@ -62,10 +62,9 @@
     void onMove(int displayId);
 
     /**
-     * Called when magnification mode changed.
+     * Called when magnification settings button clicked.
      *
      * @param displayId The logical display id.
-     * @param newMode Magnification mode.
      */
-    void onModeSwitch(int displayId, int newMode);
+    void onClickSettingsButton(int displayId);
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
index 213ce9e..eff8c01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.accessibility;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
@@ -68,6 +69,8 @@
     @Mock
     private WindowMagnificationController mWindowMagnificationController;
     @Mock
+    private MagnificationSettingsController mMagnificationSettingsController;
+    @Mock
     private ModeSwitchesController mModeSwitchesController;
     @Mock
     private SysUiState mSysUiState;
@@ -94,9 +97,11 @@
         mWindowMagnification = new WindowMagnification(getContext(),
                 getContext().getMainThreadHandler(), mCommandQueue,
                 mModeSwitchesController, mSysUiState, mOverviewProxyService, mSecureSettings,
-                mDisplayTracker);
+                mDisplayTracker, getContext().getSystemService(DisplayManager.class));
         mWindowMagnification.mMagnificationControllerSupplier = new FakeControllerSupplier(
                 mContext.getSystemService(DisplayManager.class));
+        mWindowMagnification.mMagnificationSettingsSupplier = new FakeSettingsSupplier(
+                mContext.getSystemService(DisplayManager.class));
 
         mWindowMagnification.requestWindowMagnificationConnection(true);
         assertNotNull(mIWindowMagnificationConnection);
@@ -151,6 +156,9 @@
 
     @Test
     public void showMagnificationButton() throws RemoteException {
+        // magnification settings panel should not be showing
+        assertFalse(mWindowMagnification.isMagnificationSettingsPanelShowing(TEST_DISPLAY));
+
         mIWindowMagnificationConnection.showMagnificationButton(TEST_DISPLAY,
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
         waitForIdleSync();
@@ -167,6 +175,14 @@
         verify(mModeSwitchesController).removeButton(TEST_DISPLAY);
     }
 
+    @Test
+    public void removeMagnificationSettingsPanel() throws RemoteException {
+        mIWindowMagnificationConnection.removeMagnificationSettingsPanel(TEST_DISPLAY);
+        waitForIdleSync();
+
+        verify(mMagnificationSettingsController).closeMagnificationSettings();
+    }
+
     private class FakeControllerSupplier extends
             DisplayIdIndexSupplier<WindowMagnificationController> {
 
@@ -179,5 +195,18 @@
             return mWindowMagnificationController;
         }
     }
+
+    private class FakeSettingsSupplier extends
+            DisplayIdIndexSupplier<MagnificationSettingsController> {
+
+        FakeSettingsSupplier(DisplayManager displayManager) {
+            super(displayManager);
+        }
+
+        @Override
+        protected MagnificationSettingsController createInstance(Display display) {
+            return mMagnificationSettingsController;
+        }
+    }
 }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index 00cb491..79dc057 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -17,7 +17,6 @@
 package com.android.systemui.accessibility;
 
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
-import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
 import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_MOVE;
@@ -45,6 +44,7 @@
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -57,7 +57,6 @@
 import android.os.SystemClock;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
-import android.util.SparseIntArray;
 import android.view.Choreographer;
 import android.view.MotionEvent;
 import android.view.View;
@@ -100,7 +99,8 @@
     private AccessibilityManager mAccessibilityManager;
     @Mock
     private SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
-    private SwitchListenerStub mSwitchListener;
+    @Mock
+    private MagnificationModeSwitch.ClickListener mClickListener;
     private TestableWindowManager mWindowManager;
     private ViewPropertyAnimator mViewPropertyAnimator;
     private MagnificationModeSwitch mMagnificationModeSwitch;
@@ -113,7 +113,6 @@
         MockitoAnnotations.initMocks(this);
         mContext = Mockito.spy(getContext());
         final WindowManager wm = mContext.getSystemService(WindowManager.class);
-        mSwitchListener = new SwitchListenerStub();
         mWindowManager = spy(new TestableWindowManager(wm));
         mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
         mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager);
@@ -132,7 +131,7 @@
         }).when(mSfVsyncFrameProvider).postFrameCallback(
                 any(Choreographer.FrameCallback.class));
         mMagnificationModeSwitch = new MagnificationModeSwitch(mContext, mSpyImageView,
-                mSfVsyncFrameProvider, mSwitchListener);
+                mSfVsyncFrameProvider, mClickListener);
         assertNotNull(mTouchListener);
     }
 
@@ -286,7 +285,7 @@
     }
 
     @Test
-    public void performSingleTap_fullscreenMode_removeViewAndChangeSettingsValue() {
+    public void performSingleTap_fullscreenMode_callbackTriggered() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
         resetAndStubMockImageViewAndAnimator();
 
@@ -298,7 +297,7 @@
         mTouchListener.onTouch(mSpyImageView,
                 obtainMotionEvent(downTime, downTime, ACTION_UP, 100, 100));
 
-        verifyTapAction(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        verify(mClickListener).onClick(eq(mContext.getDisplayId()));
     }
 
     @Test
@@ -347,7 +346,7 @@
         mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
                 downTime, downTime, ACTION_UP, 100 + offset, 100));
 
-        assertModeUnchanged();
+        verify(mClickListener, never()).onClick(anyInt());
         assertShowFadingAnimation(FADE_OUT_ALPHA);
     }
 
@@ -363,7 +362,7 @@
         mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
                 downTime, downTime, ACTION_CANCEL, 100, 100));
 
-        assertModeUnchanged();
+        verify(mClickListener, never()).onClick(anyInt());
         assertShowFadingAnimation(FADE_OUT_ALPHA);
     }
 
@@ -383,7 +382,7 @@
         mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
                 downTime, downTime, ACTION_CANCEL, 100 + offset, 100));
 
-        assertModeUnchanged();
+        verify(mClickListener, never()).onClick(anyInt());
         assertShowFadingAnimation(FADE_OUT_ALPHA);
     }
 
@@ -401,7 +400,7 @@
         assertThat(nodeInfo.getActionList(),
                 hasItems(new AccessibilityNodeInfo.AccessibilityAction(
                         ACTION_CLICK.getId(), mContext.getResources().getString(
-                        R.string.magnification_mode_switch_click_label))));
+                        R.string.magnification_open_settings_click_label))));
         assertThat(nodeInfo.getActionList(),
                 hasItems(new AccessibilityNodeInfo.AccessibilityAction(
                         R.id.accessibility_action_move_up, mContext.getResources().getString(
@@ -421,14 +420,14 @@
     }
 
     @Test
-    public void performClickA11yActions_showWindowModeButton_verifyTapAction() {
+    public void performClickA11yActions_showWindowModeButton_callbackTriggered() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
         resetAndStubMockImageViewAndAnimator();
 
         mSpyImageView.performAccessibilityAction(
                 ACTION_CLICK.getId(), null);
 
-        verifyTapAction(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        verify(mClickListener).onClick(mContext.getDisplayId());
     }
 
     @Test
@@ -534,11 +533,6 @@
         assertEquals(expectedY, mWindowManager.getLayoutParamsFromAttachedView().y);
     }
 
-    private void assertModeUnchanged() {
-        assertEquals(SwitchListenerStub.MODE_INVALID,
-                mSwitchListener.getChangedMode(mContext.getDisplayId()));
-    }
-
     private void assertShowFadingAnimation(float alpha) {
         final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
         if (alpha == FADE_IN_ALPHA) { // Fade-in
@@ -588,20 +582,6 @@
         doNothing().when(mViewPropertyAnimator).start();
     }
 
-    /**
-     * Verifies the tap behaviour including the image of the button and the magnification mode.
-     *
-     * @param expectedMode the expected mode after tapping
-     */
-    private void verifyTapAction(int expectedMode) {
-        verify(mViewPropertyAnimator).cancel();
-        verify(mSpyImageView).setImageResource(
-                getIconResId(expectedMode));
-        verify(mWindowManager).removeView(mSpyImageView);
-        final int changedMode = mSwitchListener.getChangedMode(mContext.getDisplayId());
-        assertEquals(expectedMode, changedMode);
-    }
-
     private MotionEvent obtainMotionEvent(long downTime, long eventTime, int action, float x,
             float y) {
         return mMotionEventHelper.obtainMotionEvent(downTime, eventTime, action, x, y);
@@ -624,20 +604,4 @@
         assertEquals(expectedX, layoutParams.x);
         assertEquals(expectedY, layoutParams.y);
     }
-
-    private static class SwitchListenerStub implements MagnificationModeSwitch.SwitchListener {
-
-        private static final int MODE_INVALID = -1;
-
-        private final SparseIntArray mModes = new SparseIntArray();
-
-        @Override
-        public void onSwitch(int displayId, int magnificationMode) {
-            mModes.put(displayId, magnificationMode);
-        }
-
-        int getChangedMode(int displayId) {
-            return mModes.get(displayId, MODE_INVALID);
-        }
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
new file mode 100644
index 0000000..30cbc52
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility;
+
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.content.pm.ActivityInfo;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.accessibility.WindowMagnificationSettings.MagnificationSize;
+import com.android.systemui.util.settings.SecureSettings;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+/** Tests the MagnificationSettingsController. */
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class MagnificationSettingsControllerTest extends SysuiTestCase {
+
+    private MagnificationSettingsController mMagnificationSettingsController;
+    @Mock
+    private MagnificationSettingsController.Callback mMagnificationSettingControllerCallback;
+
+    @Mock
+    private WindowMagnificationSettings mWindowMagnificationSettings;
+
+    @Mock
+    private SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
+    @Mock
+    private SecureSettings mSecureSettings;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mMagnificationSettingsController = new MagnificationSettingsController(
+                mContext, mSfVsyncFrameProvider,
+                mMagnificationSettingControllerCallback, mSecureSettings,
+                mWindowMagnificationSettings);
+    }
+
+    @After
+    public void tearDown() {
+        mMagnificationSettingsController.closeMagnificationSettings();
+    }
+
+    @Test
+    public void testShowSettingsPanel() {
+        final int mode = ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
+        mMagnificationSettingsController.showMagnificationSettings(mode);
+
+        verify(mWindowMagnificationSettings).showSettingPanel(eq(mode));
+    }
+
+    @Test
+    public void testHideSettingsPanel() {
+        mMagnificationSettingsController.closeMagnificationSettings();
+
+        verify(mWindowMagnificationSettings).hideSettingPanel();
+    }
+
+    @Test
+    public void testOnConfigurationChanged_notifySettingsPanel() {
+        mMagnificationSettingsController.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
+
+        verify(mWindowMagnificationSettings).onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
+    }
+
+    @Test
+    public void testPanelOnSetDiagonalScrolling_delegateToCallback() {
+        final boolean enable = true;
+        mMagnificationSettingsController.mWindowMagnificationSettingsCallback
+                .onSetDiagonalScrolling(enable);
+
+        verify(mMagnificationSettingControllerCallback).onSetDiagonalScrolling(
+                eq(mContext.getDisplayId()), eq(enable));
+    }
+
+    @Test
+    public void testPanelOnModeSwitch_delegateToCallback() {
+        final int newMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+        mMagnificationSettingsController.mWindowMagnificationSettingsCallback
+                .onModeSwitch(newMode);
+
+        verify(mMagnificationSettingControllerCallback).onModeSwitch(
+                eq(mContext.getDisplayId()), eq(newMode));
+    }
+
+    @Test
+    public void testPanelOnSettingsPanelVisibilityChanged_delegateToCallback() {
+        final boolean shown = true;
+        mMagnificationSettingsController.mWindowMagnificationSettingsCallback
+                .onSettingsPanelVisibilityChanged(shown);
+
+        verify(mMagnificationSettingControllerCallback).onSettingsPanelVisibilityChanged(
+                eq(mContext.getDisplayId()), eq(shown));
+    }
+
+    @Test
+    public void testPanelOnSetMagnifierSize_delegateToCallback() {
+        final @MagnificationSize int index = MagnificationSize.SMALL;
+        mMagnificationSettingsController.mWindowMagnificationSettingsCallback
+                .onSetMagnifierSize(index);
+
+        verify(mMagnificationSettingControllerCallback).onSetMagnifierSize(
+                eq(mContext.getDisplayId()), eq(index));
+    }
+
+    @Test
+    public void testPanelOnEditMagnifierSizeMode_delegateToCallback() {
+        final boolean enable = true;
+        mMagnificationSettingsController.mWindowMagnificationSettingsCallback
+                .onEditMagnifierSizeMode(enable);
+
+        verify(mMagnificationSettingControllerCallback).onEditMagnifierSizeMode(
+                eq(mContext.getDisplayId()), eq(enable));
+    }
+
+    @Test
+    public void testPanelOnMagnifierScale_delegateToCallback() {
+        final float scale = 3.0f;
+        mMagnificationSettingsController.mWindowMagnificationSettingsCallback
+                .onMagnifierScale(scale);
+
+        verify(mMagnificationSettingControllerCallback).onMagnifierScale(
+                eq(mContext.getDisplayId()), eq(scale));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
index 82ae6ff..3c97423 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
@@ -49,7 +49,7 @@
     private ModeSwitchesController mModeSwitchesController;
     private View mSpyView;
     @Mock
-    private MagnificationModeSwitch.SwitchListener mListener;
+    private MagnificationModeSwitch.ClickListener mListener;
 
 
     @Before
@@ -57,7 +57,7 @@
         MockitoAnnotations.initMocks(this);
         mSupplier = new FakeSwitchSupplier(mContext.getSystemService(DisplayManager.class));
         mModeSwitchesController = new ModeSwitchesController(mSupplier);
-        mModeSwitchesController.setSwitchListenerDelegate(mListener);
+        mModeSwitchesController.setClickListenerDelegate(mListener);
         mModeSwitch = Mockito.spy(new MagnificationModeSwitch(mContext, mModeSwitchesController));
         mSpyView = Mockito.spy(new View(mContext));
     }
@@ -101,8 +101,7 @@
 
         mModeSwitch.onSingleTap(mSpyView);
 
-        verify(mListener).onSwitch(mContext.getDisplayId(),
-                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        verify(mListener).onClick(mContext.getDisplayId());
     }
 
     private class FakeSwitchSupplier extends DisplayIdIndexSupplier<MagnificationModeSwitch> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index de152e4..b5e0df5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -790,7 +790,7 @@
         //  should move with both offsetX and offsetY without regrading offsetY/offsetX
         mInstrumentation.runOnMainSync(
                 () -> {
-                    mController.getMagnificationSettings().setDiagonalScrolling(true);
+                    mController.setDiagonalScrolling(true);
                     mController.moveWindowMagnifier(offsetX, offsetY);
                 });
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 6e4a20a..0978c82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -640,6 +640,10 @@
         assertTrue(
                 mirrorView.performAccessibilityAction(R.id.accessibility_action_move_left, null));
         verify(mWindowMagnifierCallback, times(4)).onMove(eq(displayId));
+
+        assertTrue(mirrorView.performAccessibilityAction(
+                AccessibilityAction.ACTION_CLICK.getId(), null));
+        verify(mWindowMagnifierCallback).onClickSettingsButton(eq(displayId));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
index 47c9191..c08b5b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.accessibility;
 
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static junit.framework.Assert.assertEquals;
@@ -34,7 +37,9 @@
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
+import android.widget.Button;
 import android.widget.CompoundButton;
+import android.widget.LinearLayout;
 
 import androidx.test.filters.SmallTest;
 
@@ -97,7 +102,7 @@
 
     @Test
     public void showSettingPanel_hasAccessibilityWindowTitle() {
-        mWindowMagnificationSettings.showSettingPanel();
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
 
         final WindowManager.LayoutParams layoutPrams =
                 mWindowManager.getLayoutParamsFromAttachedView();
@@ -108,51 +113,77 @@
     }
 
     @Test
-    public void performClick_smallSizeButton_changeMagnifierSizeSmall() {
-        // Open view
-        mWindowMagnificationSettings.showSettingPanel();
+    public void showSettingPanel_windowMode_showEditButtonAndDiagonalView() {
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
 
-        verifyOnSetMagnifierSize(R.id.magnifier_small_button, MAGNIFICATION_SIZE_SMALL);
+        final Button editButton = getInternalView(R.id.magnifier_edit_button);
+        assertEquals(editButton.getVisibility(), View.VISIBLE);
+
+        final LinearLayout diagonalView = getInternalView(R.id.magnifier_horizontal_lock_view);
+        assertEquals(diagonalView.getVisibility(), View.VISIBLE);
     }
 
     @Test
-    public void performClick_mediumSizeButton_changeMagnifierSizeMedium() {
-        // Open view
-        mWindowMagnificationSettings.showSettingPanel();
+    public void showSettingPanel_fullScreenMode_hideEditButtonAndDiagonalView() {
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
 
-        verifyOnSetMagnifierSize(R.id.magnifier_medium_button, MAGNIFICATION_SIZE_MEDIUM);
+        final Button editButton = getInternalView(R.id.magnifier_edit_button);
+        assertEquals(editButton.getVisibility(), View.INVISIBLE);
+
+        final LinearLayout diagonalView = getInternalView(R.id.magnifier_horizontal_lock_view);
+        assertEquals(diagonalView.getVisibility(), View.GONE);
     }
 
     @Test
-    public void performClick_largeSizeButton_changeMagnifierSizeLarge() {
+    public void performClick_smallSizeButton_changeMagnifierSizeSmallAndSwitchToWindowMode() {
         // Open view
-        mWindowMagnificationSettings.showSettingPanel();
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
 
-        verifyOnSetMagnifierSize(R.id.magnifier_large_button, MAGNIFICATION_SIZE_LARGE);
+        verifyOnSetMagnifierSizeAndOnModeSwitch(
+                R.id.magnifier_small_button, MAGNIFICATION_SIZE_SMALL);
     }
 
-    private void verifyOnSetMagnifierSize(@IdRes int viewId, int expectedSizeIndex) {
+    @Test
+    public void performClick_mediumSizeButton_changeMagnifierSizeMediumAndSwitchToWindowMode() {
+        // Open view
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+        verifyOnSetMagnifierSizeAndOnModeSwitch(
+                R.id.magnifier_medium_button, MAGNIFICATION_SIZE_MEDIUM);
+    }
+
+    @Test
+    public void performClick_largeSizeButton_changeMagnifierSizeLargeAndSwitchToWindowMode() {
+        // Open view
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+        verifyOnSetMagnifierSizeAndOnModeSwitch(
+                R.id.magnifier_large_button, MAGNIFICATION_SIZE_LARGE);
+    }
+
+    private void verifyOnSetMagnifierSizeAndOnModeSwitch(@IdRes int viewId, int expectedSizeIndex) {
         View changeSizeButton = getInternalView(viewId);
 
         // Perform click
         changeSizeButton.performClick();
 
         verify(mWindowMagnificationSettingsCallback).onSetMagnifierSize(expectedSizeIndex);
+        verify(mWindowMagnificationSettingsCallback)
+                .onModeSwitch(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
     }
 
 
     @Test
-    public void performClick_fullScreenModeButton_setEditMagnifierSizeMode() {
+    public void performClick_fullScreenModeButton_switchToFullScreenMode() {
         View fullScreenModeButton = getInternalView(R.id.magnifier_full_button);
         getInternalView(R.id.magnifier_panel_view);
 
         // Open view
-        mWindowMagnificationSettings.showSettingPanel();
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
 
         // Perform click
         fullScreenModeButton.performClick();
 
-        verify(mWindowManager).removeView(mSettingView);
         verify(mWindowMagnificationSettingsCallback)
                 .onModeSwitch(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
     }
@@ -162,7 +193,7 @@
         View editButton = getInternalView(R.id.magnifier_edit_button);
 
         // Open view
-        mWindowMagnificationSettings.showSettingPanel();
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
 
         // Perform click
         editButton.performClick();
@@ -178,7 +209,7 @@
         final boolean currentCheckedState = diagonalScrollingSwitch.isChecked();
 
         // Open view
-        mWindowMagnificationSettings.showSettingPanel();
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
 
         // Perform click
         diagonalScrollingSwitch.performClick();
@@ -189,7 +220,7 @@
     @Test
     public void onConfigurationChanged_selectedButtonIsStillSelected() {
         // Open view
-        mWindowMagnificationSettings.showSettingPanel();
+        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
         View magnifierMediumButton = getInternalView(R.id.magnifier_medium_button);
         magnifierMediumButton.performClick();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
index 583f2db..239b5bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
@@ -16,16 +16,21 @@
 
 package com.android.systemui.accessibility;
 
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
+
+import static com.android.systemui.accessibility.WindowMagnificationSettings.MagnificationSize;
 import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.ArgumentMatchers.notNull;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -80,6 +85,11 @@
     private OverviewProxyListener mOverviewProxyListener;
     private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
 
+    @Mock
+    private WindowMagnificationController mWindowMagnificationController;
+    @Mock
+    private MagnificationSettingsController mMagnificationSettingsController;
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -96,7 +106,12 @@
         mCommandQueue = new CommandQueue(getContext(), mDisplayTracker);
         mWindowMagnification = new WindowMagnification(getContext(),
                 getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController,
-                mSysUiState, mOverviewProxyService, mSecureSettings, mDisplayTracker);
+                mSysUiState, mOverviewProxyService, mSecureSettings, mDisplayTracker,
+                getContext().getSystemService(DisplayManager.class));
+        mWindowMagnification.mMagnificationControllerSupplier = new FakeControllerSupplier(
+                mContext.getSystemService(DisplayManager.class), mWindowMagnificationController);
+        mWindowMagnification.mMagnificationSettingsSupplier = new FakeSettingsSupplier(
+                mContext.getSystemService(DisplayManager.class), mMagnificationSettingsController);
         mWindowMagnification.start();
 
         final ArgumentCaptor<OverviewProxyListener> listenerArgumentCaptor =
@@ -112,13 +127,11 @@
 
         verify(mAccessibilityManager).setWindowMagnificationConnection(any(
                 IWindowMagnificationConnection.class));
-        verify(mModeSwitchesController).setSwitchListenerDelegate(notNull());
 
         mCommandQueue.requestWindowMagnificationConnection(false);
         waitForIdleSync();
 
         verify(mAccessibilityManager).setWindowMagnificationConnection(isNull());
-        verify(mModeSwitchesController).setSwitchListenerDelegate(isNull());
     }
 
     @Test
@@ -127,7 +140,8 @@
         mCommandQueue.requestWindowMagnificationConnection(true);
         waitForIdleSync();
 
-        mWindowMagnification.onWindowMagnifierBoundsChanged(TEST_DISPLAY, testBounds);
+        mWindowMagnification.mWindowMagnifierCallback
+                .onWindowMagnifierBoundsChanged(TEST_DISPLAY, testBounds);
 
         verify(mConnectionCallback).onWindowMagnifierBoundsChanged(TEST_DISPLAY, testBounds);
     }
@@ -138,7 +152,8 @@
         mCommandQueue.requestWindowMagnificationConnection(true);
         waitForIdleSync();
 
-        mWindowMagnification.onPerformScaleAction(TEST_DISPLAY, newScale);
+        mWindowMagnification.mWindowMagnifierCallback
+                .onPerformScaleAction(TEST_DISPLAY, newScale);
 
         verify(mConnectionCallback).onPerformScaleAction(TEST_DISPLAY, newScale);
     }
@@ -148,7 +163,8 @@
         mCommandQueue.requestWindowMagnificationConnection(true);
         waitForIdleSync();
 
-        mWindowMagnification.onAccessibilityActionPerformed(TEST_DISPLAY);
+        mWindowMagnification.mWindowMagnifierCallback
+                .onAccessibilityActionPerformed(TEST_DISPLAY);
 
         verify(mConnectionCallback).onAccessibilityActionPerformed(TEST_DISPLAY);
     }
@@ -158,21 +174,101 @@
         mCommandQueue.requestWindowMagnificationConnection(true);
         waitForIdleSync();
 
-        mWindowMagnification.onMove(TEST_DISPLAY);
+        mWindowMagnification.mWindowMagnifierCallback.onMove(TEST_DISPLAY);
 
         verify(mConnectionCallback).onMove(TEST_DISPLAY);
     }
 
     @Test
-    public void onModeSwitch_enabled_notifyCallback() throws RemoteException {
-        final int magnificationModeFullScreen = 1;
+    public void onClickSettingsButton_enabled_showPanelForWindowMode() {
+        mWindowMagnification.mWindowMagnifierCallback.onClickSettingsButton(TEST_DISPLAY);
+        waitForIdleSync();
+
+        verify(mMagnificationSettingsController).showMagnificationSettings(
+                eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
+    }
+
+    @Test
+    public void onSetMagnifierSize_delegateToMagnifier() {
+        final @MagnificationSize int index = MagnificationSize.SMALL;
+        mWindowMagnification.mMagnificationSettingsControllerCallback.onSetMagnifierSize(
+                TEST_DISPLAY, index);
+        waitForIdleSync();
+
+        verify(mWindowMagnificationController).changeMagnificationSize(eq(index));
+    }
+
+    @Test
+    public void onSetDiagonalScrolling_delegateToMagnifier() {
+        mWindowMagnification.mMagnificationSettingsControllerCallback.onSetDiagonalScrolling(
+                TEST_DISPLAY, /* enable= */ true);
+        waitForIdleSync();
+
+        verify(mWindowMagnificationController).setDiagonalScrolling(eq(true));
+    }
+
+    @Test
+    public void onEditMagnifierSizeMode_windowActivated_delegateToMagnifier() {
+        when(mWindowMagnificationController.isActivated()).thenReturn(true);
+        mWindowMagnification.mMagnificationSettingsControllerCallback.onEditMagnifierSizeMode(
+                TEST_DISPLAY, /* enable= */ true);
+        waitForIdleSync();
+
+        verify(mWindowMagnificationController).setEditMagnifierSizeMode(eq(true));
+    }
+
+    @Test
+    public void onMagnifierScale_notifyCallback() throws RemoteException {
+        mCommandQueue.requestWindowMagnificationConnection(true);
+        waitForIdleSync();
+        final float scale = 3.0f;
+        mWindowMagnification.mMagnificationSettingsControllerCallback.onMagnifierScale(
+                TEST_DISPLAY, scale);
+
+        verify(mConnectionCallback).onPerformScaleAction(eq(TEST_DISPLAY), eq(scale));
+    }
+
+    @Test
+    public void onModeSwitch_windowEnabledAndSwitchToFullscreen_hidePanelAndNotifyCallback()
+            throws RemoteException {
+        when(mWindowMagnificationController.isActivated()).thenReturn(true);
         mCommandQueue.requestWindowMagnificationConnection(true);
         waitForIdleSync();
 
-        mWindowMagnification.onModeSwitch(TEST_DISPLAY, magnificationModeFullScreen);
+        mWindowMagnification.mMagnificationSettingsControllerCallback.onModeSwitch(
+                TEST_DISPLAY, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+        waitForIdleSync();
 
-        verify(mConnectionCallback).onChangeMagnificationMode(TEST_DISPLAY,
-                magnificationModeFullScreen);
+        verify(mMagnificationSettingsController).closeMagnificationSettings();
+        verify(mConnectionCallback).onChangeMagnificationMode(eq(TEST_DISPLAY),
+                eq(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN));
+    }
+
+    @Test
+    public void onModeSwitch_switchToSameMode_doNothing()
+            throws RemoteException {
+        when(mWindowMagnificationController.isActivated()).thenReturn(true);
+        mCommandQueue.requestWindowMagnificationConnection(true);
+        waitForIdleSync();
+
+        mWindowMagnification.mMagnificationSettingsControllerCallback.onModeSwitch(
+                TEST_DISPLAY, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        waitForIdleSync();
+
+        verify(mMagnificationSettingsController, never()).closeMagnificationSettings();
+        verify(mConnectionCallback, never()).onChangeMagnificationMode(eq(TEST_DISPLAY),
+                /* magnificationMode = */ anyInt());
+    }
+
+    @Test
+    public void onSettingsPanelVisibilityChanged_windowActivated_delegateToMagnifier() {
+        when(mWindowMagnificationController.isActivated()).thenReturn(true);
+        final boolean shown = false;
+        mWindowMagnification.mMagnificationSettingsControllerCallback
+                .onSettingsPanelVisibilityChanged(TEST_DISPLAY, shown);
+        waitForIdleSync();
+
+        verify(mWindowMagnificationController).updateDragHandleResourcesIfNeeded(eq(shown));
     }
 
     @Test
@@ -211,4 +307,21 @@
             return mController;
         }
     }
+
+    private static class FakeSettingsSupplier extends
+            DisplayIdIndexSupplier<MagnificationSettingsController> {
+
+        private final MagnificationSettingsController mController;
+
+        FakeSettingsSupplier(DisplayManager displayManager,
+                MagnificationSettingsController controller) {
+            super(displayManager);
+            mController = controller;
+        }
+
+        @Override
+        protected MagnificationSettingsController createInstance(Display display) {
+            return mController;
+        }
+    }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index 4753a54..22e742b 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -167,13 +167,19 @@
 
     @Override
     public void onPerformScaleAction(int displayId, float scale) {
-        getWindowMagnificationMgr().setScale(displayId, scale);
-        getWindowMagnificationMgr().persistScale(displayId);
+        if (getFullScreenMagnificationController().isActivated(displayId)) {
+            getFullScreenMagnificationController().setScaleAndCenter(displayId, scale,
+                    Float.NaN, Float.NaN, false, MAGNIFICATION_GESTURE_HANDLER_ID);
+            getFullScreenMagnificationController().persistScale(displayId);
+        } else if (getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId)) {
+            getWindowMagnificationMgr().setScale(displayId, scale);
+            getWindowMagnificationMgr().persistScale(displayId);
+        }
     }
 
     @Override
     public void onAccessibilityActionPerformed(int displayId) {
-        updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        updateMagnificationUIControls(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
     }
 
     @Override
@@ -190,21 +196,22 @@
         if (mMagnificationCapabilities != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) {
             return;
         }
-        if (isActivated(displayId, mode)) {
-            getWindowMagnificationMgr().showMagnificationButton(displayId, mode);
-        }
+        updateMagnificationUIControls(displayId, mode);
     }
 
-    private void updateMagnificationButton(int displayId, int mode) {
+    private void updateMagnificationUIControls(int displayId, int mode) {
         final boolean isActivated = isActivated(displayId, mode);
-        final boolean showButton;
+        final boolean showUIControls;
         synchronized (mLock) {
-            showButton = isActivated && mMagnificationCapabilities
+            showUIControls = isActivated && mMagnificationCapabilities
                     == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
         }
-        if (showButton) {
+        if (showUIControls) {
+            // we only need to show magnification button, the settings panel showing should be
+            // triggered only on sysui side.
             getWindowMagnificationMgr().showMagnificationButton(displayId, mode);
         } else {
+            getWindowMagnificationMgr().removeMagnificationSettingsPanel(displayId);
             getWindowMagnificationMgr().removeMagnificationButton(displayId);
         }
     }
@@ -427,7 +434,7 @@
     public void onRequestMagnificationSpec(int displayId, int serviceId) {
         final WindowMagnificationManager windowMagnificationManager;
         synchronized (mLock) {
-            updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+            updateMagnificationUIControls(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
             windowMagnificationManager = mWindowMagnificationMgr;
         }
         if (windowMagnificationManager != null) {
@@ -456,7 +463,7 @@
             }
             logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, duration);
         }
-        updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        updateMagnificationUIControls(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
     }
 
     @Override
@@ -554,7 +561,7 @@
             }
             logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, duration);
         }
-        updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+        updateMagnificationUIControls(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
     }
 
     private void disableWindowMagnificationIfNeeded(int displayId) {
@@ -872,7 +879,7 @@
                         mAms.notifyMagnificationChanged(mDisplayId, region, configBuilder.build());
                     }
                 }
-                updateMagnificationButton(mDisplayId, mTargetMode);
+                updateMagnificationUIControls(mDisplayId, mTargetMode);
                 if (mTransitionCallBack != null) {
                     mTransitionCallBack.onResult(mDisplayId, success);
                 }
@@ -900,7 +907,7 @@
                 setExpiredAndRemoveFromListLocked();
                 setTransitionState(mDisplayId, null);
                 applyMagnificationModeLocked(mCurrentMode);
-                updateMagnificationButton(mDisplayId, mCurrentMode);
+                updateMagnificationUIControls(mDisplayId, mCurrentMode);
                 if (mTransitionCallBack != null) {
                     mTransitionCallBack.onResult(mDisplayId, true);
                 }
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java
index 041eece..1202cfa 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java
@@ -185,6 +185,22 @@
         return true;
     }
 
+    boolean removeMagnificationSettingsPanel(int displayId) {
+        if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
+            mTrace.logTrace(TAG + ".removeMagnificationSettingsPanel",
+                    FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "displayId=" + displayId);
+        }
+        try {
+            mConnection.removeMagnificationSettingsPanel(displayId);
+        } catch (RemoteException e) {
+            if (DBG) {
+                Slog.e(TAG, "Error calling removeMagnificationSettingsPanel()", e);
+            }
+            return false;
+        }
+        return true;
+    }
+
     boolean setConnectionCallback(IWindowMagnificationConnectionCallback connectionCallback) {
         if (mTrace.isA11yTracingEnabledForTypes(
                 FLAGS_WINDOW_MAGNIFICATION_CONNECTION
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
index d9391f4..ce18b2c 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
@@ -779,8 +779,10 @@
      * @return {@code true} if the event was handled, {@code false} otherwise
      */
     public boolean showMagnificationButton(int displayId, int magnificationMode) {
-        return mConnectionWrapper != null && mConnectionWrapper.showMagnificationButton(
-                displayId, magnificationMode);
+        synchronized (mLock) {
+            return mConnectionWrapper != null
+                    && mConnectionWrapper.showMagnificationButton(displayId, magnificationMode);
+        }
     }
 
     /**
@@ -790,8 +792,23 @@
      * @return {@code true} if the event was handled, {@code false} otherwise
      */
     public boolean removeMagnificationButton(int displayId) {
-        return mConnectionWrapper != null && mConnectionWrapper.removeMagnificationButton(
-                displayId);
+        synchronized (mLock) {
+            return mConnectionWrapper != null
+                    && mConnectionWrapper.removeMagnificationButton(displayId);
+        }
+    }
+
+    /**
+     * Requests System UI remove magnification settings panel on the specified display.
+     *
+     * @param displayId The logical display id.
+     * @return {@code true} if the event was handled, {@code false} otherwise
+     */
+    public boolean removeMagnificationSettingsPanel(int displayId) {
+        synchronized (mLock) {
+            return mConnectionWrapper != null
+                    && mConnectionWrapper.removeMagnificationSettingsPanel(displayId);
+        }
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index bbcb376..913d8c1 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -559,7 +559,21 @@
     }
 
     @Test
-    public void onPerformScaleAction_magnifierEnabled_handleScaleChange() throws RemoteException {
+    public void onPerformScaleAction_fullScreenMagnifierEnabled_handleScaleChange()
+            throws RemoteException {
+        final float newScale = 4.0f;
+        setMagnificationEnabled(MODE_FULLSCREEN);
+
+        mMagnificationController.onPerformScaleAction(TEST_DISPLAY, newScale);
+
+        verify(mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY), eq(newScale),
+                anyFloat(), anyFloat(), anyBoolean(), anyInt());
+        verify(mScreenMagnificationController).persistScale(eq(TEST_DISPLAY));
+    }
+
+    @Test
+    public void onPerformScaleAction_windowMagnifierEnabled_handleScaleChange()
+            throws RemoteException {
         final float newScale = 4.0f;
         setMagnificationEnabled(MODE_WINDOW);
 
@@ -1035,6 +1049,25 @@
     }
 
     @Test
+    public void disableWindowMode_windowEnabled_removeMagnificationSettingsPanel()
+            throws RemoteException {
+        setMagnificationEnabled(MODE_WINDOW);
+
+        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+
+        verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+    }
+
+    @Test
+    public void onFullScreenDeactivated_fullScreenEnabled_removeMagnificationSettingsPanel()
+            throws RemoteException {
+        setMagnificationEnabled(MODE_FULLSCREEN);
+        mScreenMagnificationController.reset(TEST_DISPLAY, /* animate= */ true);
+
+        verify(mWindowMagnificationManager).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+    }
+
+    @Test
     public void imeWindowStateShown_windowMagnifying_logWindowMode() {
         MagnificationController spyController = spy(mMagnificationController);
         spyController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java
index 4b77764..2357e65 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java
@@ -116,6 +116,12 @@
     }
 
     @Test
+    public void removeMagnificationSettingsPanel() throws RemoteException {
+        mConnectionWrapper.removeMagnificationSettingsPanel(TEST_DISPLAY);
+        verify(mConnection).removeMagnificationSettingsPanel(eq(TEST_DISPLAY));
+    }
+
+    @Test
     public void setMirrorWindowCallback() throws RemoteException {
         mConnectionWrapper.setConnectionCallback(mCallback);
         verify(mConnection).setConnectionCallback(mCallback);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
index d841dfc..b0fd649 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
@@ -537,6 +537,15 @@
     }
 
     @Test
+    public void removeMagnificationSettingsPanel_hasConnection_invokeConnectionMethod()
+            throws RemoteException {
+        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+
+        mWindowMagnificationManager.removeMagnificationSettingsPanel(TEST_DISPLAY);
+        verify(mMockConnection.getConnection()).removeMagnificationSettingsPanel(TEST_DISPLAY);
+    }
+
+    @Test
     public void pointersInWindow_magnifierEnabled_returnCorrectValue() throws RemoteException {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);