From a2173652a04eaff9692e340075b8a925b8d699ad Mon Sep 17 00:00:00 2001 From: Vadim Caen Date: Mon, 7 Mar 2022 12:43:50 +0100 Subject: [PATCH] Migrate PopupWindow to use OnBackInvokedDispatcher Bug: 219968356 Test: In BackTestApp, show popup window and swipe back to close it. Test: CTS: android.widget.cts.BackInvokedOnWidgetsTest#popupWindowDismissedOnBackGesture Change-Id: Ic22c12e2ed9f1c961f6e0abfdaf3d2a9a7bd2934 --- core/java/android/widget/PopupWindow.java | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index decd9a547edb6..c1ec168af1452 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -56,6 +56,9 @@ import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.WindowManagerGlobal; +import android.window.OnBackInvokedCallback; +import android.window.OnBackInvokedDispatcher; +import android.window.WindowOnBackInvokedDispatcher; import com.android.internal.R; @@ -277,6 +280,8 @@ public class PopupWindow { private boolean mPopupViewInitialLayoutDirectionInherited; + private OnBackInvokedCallback mBackCallback; + /** *

Create a new empty, non focusable popup window of dimension (0,0).

* @@ -2028,6 +2033,8 @@ public class PopupWindow { final PopupDecorView decorView = mDecorView; final View contentView = mContentView; + unregisterBackCallback(decorView.findOnBackInvokedDispatcher()); + final ViewGroup contentHolder; final ViewParent contentParent = contentView.getParent(); if (contentParent instanceof ViewGroup) { @@ -2082,6 +2089,15 @@ public class PopupWindow { } } + private void unregisterBackCallback(@Nullable OnBackInvokedDispatcher onBackInvokedDispatcher) { + OnBackInvokedCallback backCallback = mBackCallback; + mBackCallback = null; + if (onBackInvokedDispatcher != null && backCallback != null) { + onBackInvokedDispatcher.unregisterOnBackInvokedCallback( + backCallback); + } + } + /** * Returns the window-relative epicenter bounds to be used by enter and * exit transitions. @@ -2725,6 +2741,30 @@ public class PopupWindow { } } } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (!WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) { + return; + } + + OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher(); + if (dispatcher == null) { + return; + } + + mBackCallback = PopupWindow.this::dismiss; + + dispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT, + mBackCallback); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + unregisterBackCallback(findOnBackInvokedDispatcher()); + } } private class PopupBackgroundView extends FrameLayout {