From 3e966e2996bddb573b9749ed2597d636bdba05c6 Mon Sep 17 00:00:00 2001 From: Vadim Caen Date: Fri, 25 Feb 2022 15:14:24 +0100 Subject: [PATCH] Fix Activity leaking form OnBackInvokedCallbackWrapper - The callback was not removed on the server in the clear() method since mWindow and mWindowSession fields were cleared before - The wrapper class was not static, risking to leak it's outer class and its field. Test: com.android.launcher3.ui.widget.RequestPinItemTest#testPinWidgetWithConfig Fixes: 220385755 Change-Id: I3e5a81bf48c2272b1cb2b5a9f2ba940d0f794a6f --- .../window/WindowOnBackInvokedDispatcher.java | 74 +++++++++---------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java index 0503c406c2871..94e5ea960f4fe 100644 --- a/core/java/android/window/WindowOnBackInvokedDispatcher.java +++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java @@ -76,9 +76,9 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { /** Detaches the dispatcher instance from its window. */ public void detachFromWindow() { + clear(); mWindow = null; mWindowSession = null; - clear(); } // TODO: Take an Executor for the callback to run on. @@ -165,50 +165,13 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { } else { int priority = mAllCallbacks.get(callback); mWindowSession.setOnBackInvokedCallback( - mWindow, new OnBackInvokedCallbackWrapper(callback, priority), priority); + mWindow, new OnBackInvokedCallbackWrapper(callback), priority); } } catch (RemoteException e) { Log.e(TAG, "Failed to set OnBackInvokedCallback to WM. Error: " + e); } } - private class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub { - private final OnBackInvokedCallback mCallback; - private final @Priority int mPriority; - - OnBackInvokedCallbackWrapper( - @NonNull OnBackInvokedCallback callback, @Priority int priority) { - mCallback = callback; - mPriority = priority; - } - - @NonNull - public OnBackInvokedCallback getCallback() { - return mCallback; - } - - @Override - public void onBackStarted() throws RemoteException { - Handler.getMain().post(() -> mCallback.onBackStarted()); - } - - @Override - public void onBackProgressed(BackEvent backEvent) - throws RemoteException { - Handler.getMain().post(() -> mCallback.onBackProgressed(backEvent)); - } - - @Override - public void onBackCancelled() throws RemoteException { - Handler.getMain().post(() -> mCallback.onBackCancelled()); - } - - @Override - public void onBackInvoked() throws RemoteException { - Handler.getMain().post(() -> mCallback.onBackInvoked()); - } - } - @Override public OnBackInvokedCallback getTopCallback() { if (mAllCallbacks.isEmpty()) { @@ -223,6 +186,39 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { return null; } + private static class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub { + private final OnBackInvokedCallback mCallback; + + OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback) { + mCallback = callback; + } + + @NonNull + public OnBackInvokedCallback getCallback() { + return mCallback; + } + + @Override + public void onBackStarted() { + Handler.getMain().post(() -> mCallback.onBackStarted()); + } + + @Override + public void onBackProgressed(BackEvent backEvent) { + Handler.getMain().post(() -> mCallback.onBackProgressed(backEvent)); + } + + @Override + public void onBackCancelled() { + Handler.getMain().post(() -> mCallback.onBackCancelled()); + } + + @Override + public void onBackInvoked() throws RemoteException { + Handler.getMain().post(() -> mCallback.onBackInvoked()); + } + } + /** * Returns if the legacy back behavior should be used. *