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
This commit is contained in:
Vadim Caen
2022-02-25 15:14:24 +01:00
parent e4590dbf5d
commit 3e966e2996

View File

@@ -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.
*