Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27d450af authored by Shan Huang's avatar Shan Huang Committed by Android (Google) Code Review
Browse files

Merge "Avoid leaking Activity from OnBackInvokedCallback."

parents 2c37d7a5 b5336601
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -2696,6 +2696,7 @@ public class Activity extends ContextThemeWrapper
        }
        }
        if (mDefaultBackCallback != null) {
        if (mDefaultBackCallback != null) {
            getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mDefaultBackCallback);
            getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mDefaultBackCallback);
            mDefaultBackCallback = null;
        }
        }
        if (mCallbacksController != null) {
        if (mCallbacksController != null) {
            mCallbacksController.clearCallbacks();
            mCallbacksController.clearCallbacks();
+1 −0
Original line number Original line Diff line number Diff line
@@ -465,6 +465,7 @@ public class Dialog implements DialogInterface, Window.Callback,
                }
                }
            };
            };
            getOnBackInvokedDispatcher().registerSystemOnBackInvokedCallback(mDefaultBackCallback);
            getOnBackInvokedDispatcher().registerSystemOnBackInvokedCallback(mDefaultBackCallback);
            mDefaultBackCallback = null;
        }
        }
    }
    }


+1 −0
Original line number Original line Diff line number Diff line
@@ -10841,6 +10841,7 @@ public final class ViewRootImpl implements ViewParent,
    private void unregisterCompatOnBackInvokedCallback() {
    private void unregisterCompatOnBackInvokedCallback() {
        if (mCompatOnBackInvokedCallback != null) {
        if (mCompatOnBackInvokedCallback != null) {
            mOnBackInvokedDispatcher.unregisterOnBackInvokedCallback(mCompatOnBackInvokedCallback);
            mOnBackInvokedDispatcher.unregisterOnBackInvokedCallback(mCompatOnBackInvokedCallback);
            mCompatOnBackInvokedCallback = null;
        }
        }
    }
    }


+39 −40
Original line number Original line Diff line number Diff line
@@ -55,10 +55,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
    private static final boolean IS_BACK_PREDICTABILITY_ENABLED = SystemProperties
    private static final boolean IS_BACK_PREDICTABILITY_ENABLED = SystemProperties
            .getInt(BACK_PREDICTABILITY_PROP, 0) > 0;
            .getInt(BACK_PREDICTABILITY_PROP, 0) > 0;


    /** The currently most prioritized callback. */
    @Nullable
    private OnBackInvokedCallbackWrapper mTopCallback;

    /** Convenience hashmap to quickly decide if a callback has been added. */
    /** Convenience hashmap to quickly decide if a callback has been added. */
    private final HashMap<OnBackInvokedCallback, Integer> mAllCallbacks = new HashMap<>();
    private final HashMap<OnBackInvokedCallback, Integer> mAllCallbacks = new HashMap<>();
    /** Holds all callbacks by priorities. */
    /** Holds all callbacks by priorities. */
@@ -72,8 +68,8 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
    public void attachToWindow(@NonNull IWindowSession windowSession, @NonNull IWindow window) {
    public void attachToWindow(@NonNull IWindowSession windowSession, @NonNull IWindow window) {
        mWindowSession = windowSession;
        mWindowSession = windowSession;
        mWindow = window;
        mWindow = window;
        if (mTopCallback != null) {
        if (!mAllCallbacks.isEmpty()) {
            setTopOnBackInvokedCallback(mTopCallback);
            setTopOnBackInvokedCallback(getTopCallback());
        }
        }
    }
    }


@@ -81,6 +77,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
    public void detachFromWindow() {
    public void detachFromWindow() {
        mWindow = null;
        mWindow = null;
        mWindowSession = null;
        mWindowSession = null;
        clear();
    }
    }


    // TODO: Take an Executor for the callback to run on.
    // TODO: Take an Executor for the callback to run on.
@@ -110,11 +107,13 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
            mOnBackInvokedCallbacks.get(prevPriority).remove(callback);
            mOnBackInvokedCallbacks.get(prevPriority).remove(callback);
        }
        }


        OnBackInvokedCallback previousTopCallback = getTopCallback();
        callbacks.add(callback);
        callbacks.add(callback);
        mAllCallbacks.put(callback, priority);
        mAllCallbacks.put(callback, priority);
        if (mTopCallback == null || (mTopCallback.getCallback() != callback
        if (previousTopCallback == null
                && mAllCallbacks.get(mTopCallback.getCallback()) <= priority)) {
                || (previousTopCallback != callback
            setTopOnBackInvokedCallback(new OnBackInvokedCallbackWrapper(callback, priority));
                        && mAllCallbacks.get(previousTopCallback) <= priority)) {
            setTopOnBackInvokedCallback(callback);
        }
        }
    }
    }


@@ -126,11 +125,17 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
            }
            }
            return;
            return;
        }
        }
        OnBackInvokedCallback previousTopCallback = getTopCallback();
        Integer priority = mAllCallbacks.get(callback);
        Integer priority = mAllCallbacks.get(callback);
        mOnBackInvokedCallbacks.get(priority).remove(callback);
        ArrayList<OnBackInvokedCallback> callbacks = mOnBackInvokedCallbacks.get(priority);
        callbacks.remove(callback);
        if (callbacks.isEmpty()) {
            mOnBackInvokedCallbacks.remove(priority);
        }
        mAllCallbacks.remove(callback);
        mAllCallbacks.remove(callback);
        if (mTopCallback != null && mTopCallback.getCallback() == callback) {
        // Re-populate the top callback to WM if the removed callback was previously the top one.
            findAndSetTopOnBackInvokedCallback();
        if (previousTopCallback == callback) {
            setTopOnBackInvokedCallback(getTopCallback());
        }
        }
    }
    }


@@ -141,41 +146,26 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {


    /** Clears all registered callbacks on the instance. */
    /** Clears all registered callbacks on the instance. */
    public void clear() {
    public void clear() {
        mAllCallbacks.clear();
        if (!mAllCallbacks.isEmpty()) {
        mTopCallback = null;
            // Clear binder references in WM.
        mOnBackInvokedCallbacks.clear();
    }

    /**
     * Iterates through all callbacks to find the most prioritized one and pushes it to
     * window manager.
     */
    private void findAndSetTopOnBackInvokedCallback() {
        if (mAllCallbacks.isEmpty()) {
            setTopOnBackInvokedCallback(null);
            setTopOnBackInvokedCallback(null);
            return;
        }
        }

        mAllCallbacks.clear();
        for (Integer priority : mOnBackInvokedCallbacks.descendingKeySet()) {
        mOnBackInvokedCallbacks.clear();
            ArrayList<OnBackInvokedCallback> callbacks = mOnBackInvokedCallbacks.get(priority);
            if (!callbacks.isEmpty()) {
                OnBackInvokedCallbackWrapper callback = new OnBackInvokedCallbackWrapper(
                        callbacks.get(callbacks.size() - 1), priority);
                setTopOnBackInvokedCallback(callback);
                return;
            }
        }
        setTopOnBackInvokedCallback(null);
    }
    }


    // Pushes the top priority callback to window manager.
    private void setTopOnBackInvokedCallback(@Nullable OnBackInvokedCallback callback) {
    private void setTopOnBackInvokedCallback(@Nullable OnBackInvokedCallbackWrapper callback) {
        mTopCallback = callback;
        if (mWindowSession == null || mWindow == null) {
        if (mWindowSession == null || mWindow == null) {
            return;
            return;
        }
        }
        try {
        try {
            mWindowSession.setOnBackInvokedCallback(mWindow, mTopCallback);
            if (callback == null) {
                mWindowSession.setOnBackInvokedCallback(mWindow, null);
            } else {
                int priority = mAllCallbacks.get(callback);
                mWindowSession.setOnBackInvokedCallback(
                        mWindow, new OnBackInvokedCallbackWrapper(callback, priority));
            }
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to set OnBackInvokedCallback to WM. Error: " + e);
            Log.e(TAG, "Failed to set OnBackInvokedCallback to WM. Error: " + e);
        }
        }
@@ -220,7 +210,16 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {


    @Override
    @Override
    public OnBackInvokedCallback getTopCallback() {
    public OnBackInvokedCallback getTopCallback() {
        return mTopCallback == null ? null : mTopCallback.getCallback();
        if (mAllCallbacks.isEmpty()) {
            return null;
        }
        for (Integer priority : mOnBackInvokedCallbacks.descendingKeySet()) {
            ArrayList<OnBackInvokedCallback> callbacks = mOnBackInvokedCallbacks.get(priority);
            if (!callbacks.isEmpty()) {
                return callbacks.get(callbacks.size() - 1);
            }
        }
        return null;
    }
    }


    /**
    /**
+2 −0
Original line number Original line Diff line number Diff line
@@ -2385,6 +2385,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        dc.getDisplayPolicy().removeWindowLw(this);
        dc.getDisplayPolicy().removeWindowLw(this);


        disposeInputChannel();
        disposeInputChannel();
        mOnBackInvokedCallback = null;


        mSession.windowRemovedLocked();
        mSession.windowRemovedLocked();
        try {
        try {
@@ -2438,6 +2439,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP


        try {
        try {
            disposeInputChannel();
            disposeInputChannel();
            mOnBackInvokedCallback = null;


            ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
            ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
                    "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b "
                    "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b "