Refine FloatingToolbarPopup to allow multiple implementations

This change refined the FloatingToolbarPopup to allow the local and
system implementation. Use the flag to control which implementation
will be used. Use the local implementation as default, we will switch
the system version when it is done and stable.

Bug: 190030331
Bug: 205822301
Test: manual. The toolbar still work after refinement
Test: atest TextViewActivityTest
Test: atest TextViewIntegrationTest
Ignore-AOSP-First: new feature for T.

Change-Id: I191cb02fc4857855f5b63bdab21c014fa0879a0c
diff --git a/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java b/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java
index 60688ea..ba45b85 100644
--- a/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java
+++ b/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java
@@ -20,6 +20,7 @@
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.RemoteException;
+import android.provider.DeviceConfig;
 
 import java.util.Objects;
 
@@ -40,6 +41,11 @@
      */
     public static final String LOG_TAG = "SelectionToolbar";
 
+    /**
+     * Whether system selection toolbar is enabled.
+     */
+    private static final String REMOTE_SELECTION_TOOLBAR_ENABLED =
+            "remote_selection_toolbar_enabled";
 
     @NonNull
     private final Context mContext;
@@ -86,4 +92,21 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    private boolean isRemoteSelectionToolbarEnabled() {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SELECTION_TOOLBAR,
+                REMOTE_SELECTION_TOOLBAR_ENABLED, false);
+    }
+
+    /**
+     * Returns {@code true} if remote render selection toolbar enabled, otherwise
+     * returns {@code false}.
+     */
+    public static boolean isRemoteSelectionToolbarEnabled(Context context) {
+        SelectionToolbarManager manager = context.getSystemService(SelectionToolbarManager.class);
+        if (manager != null) {
+            return manager.isRemoteSelectionToolbarEnabled();
+        }
+        return false;
+    }
 }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 6541b14..ba7a0ef 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -121,7 +121,7 @@
 import com.android.internal.widget.ActionBarContextView;
 import com.android.internal.widget.BackgroundFallback;
 import com.android.internal.widget.DecorCaptionView;
-import com.android.internal.widget.FloatingToolbar;
+import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
 
 import java.util.List;
 import java.util.function.Consumer;
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 36913b7..06e69f2 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -33,7 +33,7 @@
 
 import com.android.internal.R;
 import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.widget.FloatingToolbar;
+import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
 
 import java.util.Arrays;
 import java.util.Objects;
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbar.java
similarity index 88%
rename from core/java/com/android/internal/widget/FloatingToolbar.java
rename to core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbar.java
index a0bf9b5..e75f372 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbar.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.widget;
+package com.android.internal.widget.floatingtoolbar;
 
 import android.annotation.Nullable;
 import android.graphics.Rect;
@@ -50,14 +50,10 @@
     private final FloatingToolbarPopup mPopup;
 
     private final Rect mContentRect = new Rect();
-    private final Rect mPreviousContentRect = new Rect();
 
     private Menu mMenu;
     private MenuItem.OnMenuItemClickListener mMenuItemClickListener = NO_OP_MENUITEM_CLICK_LISTENER;
 
-    private int mSuggestedWidth;
-    private boolean mWidthChanged = true;
-
     private final OnLayoutChangeListener mOrientationChangeHandler = new OnLayoutChangeListener() {
 
         private final Rect mNewRect = new Rect();
@@ -71,7 +67,7 @@
             mNewRect.set(newLeft, newRight, newTop, newBottom);
             mOldRect.set(oldLeft, oldRight, oldTop, oldBottom);
             if (mPopup.isShowing() && !mNewRect.equals(mOldRect)) {
-                mWidthChanged = true;
+                mPopup.setWidthChanged(true);
                 updateLayout();
             }
         }
@@ -114,7 +110,7 @@
         // TODO(b/65172902): Pass context in constructor when DecorView (and other callers)
         // supports multi-display.
         mWindow = Objects.requireNonNull(window);
-        mPopup = new FloatingToolbarPopup(window.getContext(), window.getDecorView());
+        mPopup = FloatingToolbarPopup.createInstance(window.getContext(), window.getDecorView());
     }
 
     /**
@@ -159,11 +155,7 @@
      * toolbar.
      */
     public FloatingToolbar setSuggestedWidth(int suggestedWidth) {
-        // Check if there's been a substantial width spec change.
-        int difference = Math.abs(suggestedWidth - mSuggestedWidth);
-        mWidthChanged = difference > (mSuggestedWidth * 0.2);
-
-        mSuggestedWidth = suggestedWidth;
+        mPopup.setSuggestedWidth(suggestedWidth);
         return this;
     }
 
@@ -232,19 +224,7 @@
     private void doShow() {
         List<MenuItem> menuItems = getVisibleAndEnabledMenuItems(mMenu);
         menuItems.sort(mMenuItemComparator);
-        if (mPopup.isLayoutRequired(menuItems) || mWidthChanged) {
-            mPopup.dismiss();
-            mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth);
-        } else {
-            mPopup.updateMenuItems(menuItems, mMenuItemClickListener);
-        }
-        if (!mPopup.isShowing()) {
-            mPopup.show(mContentRect);
-        } else if (!mPreviousContentRect.equals(mContentRect)) {
-            mPopup.updateCoordinates(mContentRect);
-        }
-        mWidthChanged = false;
-        mPreviousContentRect.set(mContentRect);
+        mPopup.show(menuItems, mMenuItemClickListener, mContentRect);
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java
new file mode 100644
index 0000000..f47700c
--- /dev/null
+++ b/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 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.internal.widget.floatingtoolbar;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.selectiontoolbar.SelectionToolbarManager;
+import android.widget.PopupWindow;
+
+import java.util.List;
+
+/**
+ * A popup window used by the {@link FloatingToolbar} to render menu items.
+ *
+ */
+public interface FloatingToolbarPopup {
+
+    /**
+     * Sets the suggested dp width of this floating toolbar.
+     * The actual width will be about this size but there are no guarantees that it will be exactly
+     * the suggested width.
+     */
+    void setSuggestedWidth(int suggestedWidth);
+
+    /**
+     * Sets if the floating toolbar width changed.
+     */
+    void setWidthChanged(boolean widthChanged);
+
+    /**
+     * Shows this popup at the specified coordinates.
+     * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
+     */
+    void show(List<MenuItem> menuItems, MenuItem.OnMenuItemClickListener menuItemClickListener,
+            Rect contentRect);
+
+    /**
+     * Gets rid of this popup. If the popup isn't currently showing, this will be a no-op.
+     */
+    void dismiss();
+
+    /**
+     * Hides this popup. This is a no-op if this popup is not showing.
+     * Use {@link #isHidden()} to distinguish between a hidden and a dismissed popup.
+     */
+    void hide();
+
+    /**
+     * Returns {@code true} if this popup is currently showing. {@code false} otherwise.
+     */
+    boolean isShowing();
+
+    /**
+     * Returns {@code true} if this popup is currently hidden. {@code false} otherwise.
+     */
+    boolean isHidden();
+
+    /**
+     * Makes this toolbar "outside touchable" and sets the onDismissListener.
+     *
+     * @param outsideTouchable if true, the popup will be made "outside touchable" and
+     *      "non focusable". The reverse will happen if false.
+     * @param onDismiss
+     *
+     * @return true if the "outsideTouchable" setting was modified. Otherwise returns false
+     *
+     * @see PopupWindow#setOutsideTouchable(boolean)
+     * @see PopupWindow#setFocusable(boolean)
+     * @see PopupWindow.OnDismissListener
+     */
+    boolean setOutsideTouchable(boolean outsideTouchable, PopupWindow.OnDismissListener onDismiss);
+
+    /**
+     * Returns {@link RemoteFloatingToolbarPopup} implementation if the system selection toolbar
+     * enabled, otherwise returns {@link LocalFloatingToolbarPopup} implementation.
+     */
+    static FloatingToolbarPopup createInstance(Context context, View parent) {
+        boolean enabled = SelectionToolbarManager.isRemoteSelectionToolbarEnabled(context);
+        return enabled
+                ? new RemoteFloatingToolbarPopup(context, parent)
+                : new LocalFloatingToolbarPopup(context, parent);
+    }
+
+}
diff --git a/core/java/com/android/internal/widget/FloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
similarity index 96%
rename from core/java/com/android/internal/widget/FloatingToolbarPopup.java
rename to core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
index e0388f6..80d8bd7 100644
--- a/core/java/com/android/internal/widget/FloatingToolbarPopup.java
+++ b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.widget;
+package com.android.internal.widget.floatingtoolbar;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -70,13 +70,13 @@
 import java.util.Objects;
 
 /**
- * A popup window used by the floating toolbar.
+ * A popup window used by the floating toolbar to render menu items in the local app process.
  *
  * This class is responsible for the rendering/animation of the floating toolbar.
  * It holds 2 panels (i.e. main panel and overflow panel) and an overflow button
  * to transition between panels.
  */
-public final class FloatingToolbarPopup {
+public final class LocalFloatingToolbarPopup implements FloatingToolbarPopup {
 
     /* Minimum and maximum number of items allowed in the overflow. */
     private static final int MIN_OVERFLOW_SIZE = 2;
@@ -94,7 +94,7 @@
     private final ViewGroup mContentContainer;  // holds all contents.
     private final ViewGroup mMainPanel;  // holds menu items that are initially displayed.
     // holds menu items hidden in the overflow.
-    private final FloatingToolbarPopup.OverflowPanel mOverflowPanel;
+    private final OverflowPanel mOverflowPanel;
     private final ImageButton mOverflowButton;  // opens/closes the overflow.
     /* overflow button drawables. */
     private final Drawable mArrow;
@@ -102,8 +102,7 @@
     private final AnimatedVectorDrawable mToArrow;
     private final AnimatedVectorDrawable mToOverflow;
 
-    private final FloatingToolbarPopup.OverflowPanelViewHelper
-            mOverflowPanelViewHelper;
+    private final OverflowPanelViewHelper mOverflowPanelViewHelper;
 
     /* Animation interpolators. */
     private final Interpolator mLogAccelerateInterpolator;
@@ -138,7 +137,7 @@
     private final int mIconTextSpacing;
 
     /**
-     * @see FloatingToolbarPopup.OverflowPanelViewHelper#preparePopupContent().
+     * @see OverflowPanelViewHelper#preparePopupContent().
      */
     private final Runnable mPreparePopupContentRTLHelper = new Runnable() {
         @Override
@@ -184,16 +183,20 @@
 
     private int mTransitionDurationScale;  // Used to scale the toolbar transition duration.
 
+    private final Rect mPreviousContentRect = new Rect();
+    private int mSuggestedWidth;
+    private boolean mWidthChanged = true;
+
     /**
      * Initializes a new floating toolbar popup.
      *
      * @param parent  A parent view to get the {@link android.view.View#getWindowToken()} token
      *      from.
      */
-    public FloatingToolbarPopup(Context context, View parent) {
+    public LocalFloatingToolbarPopup(Context context, View parent) {
         mParent = Objects.requireNonNull(parent);
         mContext = applyDefaultTheme(context);
-        mContentContainer = createContentContainer(context);
+        mContentContainer = createContentContainer(mContext);
         mPopupWindow = createPopupWindow(mContentContainer);
         mMarginHorizontal = parent.getResources()
                 .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
@@ -205,7 +208,7 @@
                 .getDimensionPixelSize(R.dimen.floating_toolbar_icon_text_spacing);
 
         // Interpolators
-        mLogAccelerateInterpolator = new FloatingToolbarPopup.LogAccelerateInterpolator();
+        mLogAccelerateInterpolator = new LogAccelerateInterpolator();
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
                 mContext, android.R.interpolator.fast_out_slow_in);
         mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(
@@ -231,8 +234,7 @@
         mOverflowButton = createOverflowButton();
         mOverflowButtonSize = measure(mOverflowButton);
         mMainPanel = createMainPanel();
-        mOverflowPanelViewHelper =
-                new FloatingToolbarPopup.OverflowPanelViewHelper(mContext, mIconTextSpacing);
+        mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext, mIconTextSpacing);
         mOverflowPanel = createOverflowPanel();
 
         // Animation. Need views.
@@ -263,19 +265,7 @@
                 });
     }
 
-    /**
-     * Makes this toolbar "outside touchable" and sets the onDismissListener.
-     *
-     * @param outsideTouchable if true, the popup will be made "outside touchable" and
-     *      "non focusable". The reverse will happen if false.
-     * @param onDismiss
-     *
-     * @return true if the "outsideTouchable" setting was modified. Otherwise returns false
-     *
-     * @see PopupWindow#setOutsideTouchable(boolean)
-     * @see PopupWindow#setFocusable(boolean)
-     * @see PopupWindow.OnDismissListener
-     */
+    @Override
     public boolean setOutsideTouchable(
             boolean outsideTouchable, @Nullable PopupWindow.OnDismissListener onDismiss) {
         boolean ret = false;
@@ -293,7 +283,7 @@
      * Lays out buttons for the specified menu items.
      * Requires a subsequent call to {@link FloatingToolbar#show()} to show the items.
      */
-    public void layoutMenuItems(
+    private void layoutMenuItems(
             List<MenuItem> menuItems,
             MenuItem.OnMenuItemClickListener menuItemClickListener,
             int suggestedWidth) {
@@ -314,7 +304,7 @@
      *
      * @see #isLayoutRequired(List<MenuItem>)
      */
-    public void updateMenuItems(
+    private void updateMenuItems(
             List<MenuItem> menuItems, MenuItem.OnMenuItemClickListener menuItemClickListener) {
         mMenuItems.clear();
         for (MenuItem menuItem : menuItems) {
@@ -326,15 +316,42 @@
     /**
      * Returns true if this popup needs a relayout to properly render the specified menu items.
      */
-    public boolean isLayoutRequired(List<MenuItem> menuItems) {
+    private boolean isLayoutRequired(List<MenuItem> menuItems) {
         return !MenuItemRepr.reprEquals(menuItems, mMenuItems.values());
     }
 
-    /**
-     * Shows this popup at the specified coordinates.
-     * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
-     */
-    public void show(Rect contentRectOnScreen) {
+    @Override
+    public void setWidthChanged(boolean widthChanged) {
+        mWidthChanged = widthChanged;
+    }
+
+    @Override
+    public void setSuggestedWidth(int suggestedWidth) {
+        // Check if there's been a substantial width spec change.
+        int difference = Math.abs(suggestedWidth - mSuggestedWidth);
+        mWidthChanged = difference > (mSuggestedWidth * 0.2);
+        mSuggestedWidth = suggestedWidth;
+    }
+
+    @Override
+    public void show(List<MenuItem> menuItems,
+            MenuItem.OnMenuItemClickListener menuItemClickListener, Rect contentRect) {
+        if (isLayoutRequired(menuItems) || mWidthChanged) {
+            dismiss();
+            layoutMenuItems(menuItems, menuItemClickListener, mSuggestedWidth);
+        } else {
+            updateMenuItems(menuItems, menuItemClickListener);
+        }
+        if (!isShowing()) {
+            show(contentRect);
+        } else if (!mPreviousContentRect.equals(contentRect)) {
+            updateCoordinates(contentRect);
+        }
+        mWidthChanged = false;
+        mPreviousContentRect.set(contentRect);
+    }
+
+    private void show(Rect contentRectOnScreen) {
         Objects.requireNonNull(contentRectOnScreen);
 
         if (isShowing()) {
@@ -357,9 +374,7 @@
         runShowAnimation();
     }
 
-    /**
-     * Gets rid of this popup. If the popup isn't currently showing, this will be a no-op.
-     */
+    @Override
     public void dismiss() {
         if (mDismissed) {
             return;
@@ -373,10 +388,7 @@
         setZeroTouchableSurface();
     }
 
-    /**
-     * Hides this popup. This is a no-op if this popup is not showing.
-     * Use {@link #isHidden()} to distinguish between a hidden and a dismissed popup.
-     */
+    @Override
     public void hide() {
         if (!isShowing()) {
             return;
@@ -387,16 +399,12 @@
         setZeroTouchableSurface();
     }
 
-    /**
-     * Returns {@code true} if this popup is currently showing. {@code false} otherwise.
-     */
+    @Override
     public boolean isShowing() {
         return !mDismissed && !mHidden;
     }
 
-    /**
-     * Returns {@code true} if this popup is currently hidden. {@code false} otherwise.
-     */
+    @Override
     public boolean isHidden() {
         return mHidden;
     }
@@ -406,7 +414,7 @@
      * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
      * This is a no-op if this popup is not showing.
      */
-    public void updateCoordinates(Rect contentRectOnScreen) {
+    private void updateCoordinates(Rect contentRectOnScreen) {
         Objects.requireNonNull(contentRectOnScreen);
 
         if (!isShowing() || !mPopupWindow.isShowing()) {
@@ -1206,9 +1214,8 @@
         return overflowButton;
     }
 
-    private FloatingToolbarPopup.OverflowPanel createOverflowPanel() {
-        final FloatingToolbarPopup.OverflowPanel
-                overflowPanel = new FloatingToolbarPopup.OverflowPanel(this);
+    private OverflowPanel createOverflowPanel() {
+        final OverflowPanel overflowPanel = new OverflowPanel(this);
         overflowPanel.setLayoutParams(new ViewGroup.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
         overflowPanel.setDivider(null);
@@ -1307,9 +1314,9 @@
      */
     private static final class OverflowPanel extends ListView {
 
-        private final FloatingToolbarPopup mPopup;
+        private final LocalFloatingToolbarPopup mPopup;
 
-        OverflowPanel(FloatingToolbarPopup popup) {
+        OverflowPanel(LocalFloatingToolbarPopup popup) {
             super(Objects.requireNonNull(popup).mContext);
             this.mPopup = popup;
             setScrollBarDefaultDelayBeforeFade(ViewConfiguration.getScrollDefaultDelay() * 3);
diff --git a/core/java/com/android/internal/widget/floatingtoolbar/OWNERS b/core/java/com/android/internal/widget/floatingtoolbar/OWNERS
new file mode 100644
index 0000000..ed9425c
--- /dev/null
+++ b/core/java/com/android/internal/widget/floatingtoolbar/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/selectiontoolbar/OWNERS
diff --git a/core/java/com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java
new file mode 100644
index 0000000..b3a8128
--- /dev/null
+++ b/core/java/com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021 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.internal.widget.floatingtoolbar;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.selectiontoolbar.SelectionToolbarManager;
+import android.widget.PopupWindow;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A popup window used by the floating toolbar to render menu items in the remote system process.
+ *
+ * It holds 2 panels (i.e. main panel and overflow panel) and an overflow button
+ * to transition between panels.
+ */
+public final class RemoteFloatingToolbarPopup implements FloatingToolbarPopup {
+
+    private final SelectionToolbarManager mSelectionToolbarManager;
+    // Parent for the popup window.
+    private final View mParent;
+
+    public RemoteFloatingToolbarPopup(Context context, View parent) {
+        // TODO: implement it
+        mParent = Objects.requireNonNull(parent);
+        mSelectionToolbarManager = context.getSystemService(SelectionToolbarManager.class);
+    }
+
+    @Override
+    public void show(List<MenuItem> menuItems,
+            MenuItem.OnMenuItemClickListener menuItemClickListener, Rect contentRect) {
+        // TODO: implement it
+    }
+
+    @Override
+    public void hide() {
+        // TODO: implement it
+    }
+
+    @Override
+    public void setSuggestedWidth(int suggestedWidth) {
+        // TODO: implement it
+    }
+
+    @Override
+    public void setWidthChanged(boolean widthChanged) {
+        // no-op
+    }
+
+    @Override
+    public void dismiss() {
+        // TODO: implement it
+    }
+
+    @Override
+    public boolean isHidden() {
+        return false;
+    }
+
+    @Override
+    public boolean isShowing() {
+        return false;
+    }
+
+    @Override
+    public boolean setOutsideTouchable(boolean outsideTouchable,
+            PopupWindow.OnDismissListener onDismiss) {
+        return false;
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
index 9696fdf..4f95cb8 100644
--- a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
+++ b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
@@ -28,7 +28,7 @@
 import static androidx.test.espresso.matcher.ViewMatchers.withTagValue;
 import static androidx.test.espresso.matcher.ViewMatchers.withText;
 
-import static com.android.internal.widget.FloatingToolbarPopup.MenuItemRepr;
+import static com.android.internal.widget.floatingtoolbar.LocalFloatingToolbarPopup.MenuItemRepr;
 
 import static org.hamcrest.Matchers.allOf;
 import static org.hamcrest.Matchers.is;
@@ -42,7 +42,7 @@
 import androidx.test.espresso.ViewAction;
 import androidx.test.espresso.ViewInteraction;
 
-import com.android.internal.widget.FloatingToolbar;
+import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
 
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
index 72f1695..fb0e306 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
@@ -50,7 +50,7 @@
 import android.widget.FrameLayout;
 
 import com.android.internal.view.FloatingActionMode;
-import com.android.internal.widget.FloatingToolbar;
+import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
 import com.android.systemui.R;
 
 /**