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

Commit 4ad54910 authored by chaviw's avatar chaviw
Browse files

Notify WM that app is delayed closing due to the possibility of PIP.

WM determines the IME target after it sets up all the app transitions
and handles visiblity. In most cases, this is fine since everything is
set up properly at once. However, in cases where the app can enter PIP,
the transition to close the app is delayed in case the app decides to
enter PIP. In this case AM needs to notify WM of this information so it
can properly calculate the IME target when the app transitions aren't
fully set up.

The specific usecase is the following:
1. App with the ability to enter PIP is open with IME
2. Home is pressed.
3. Launcher is brought to the front, previous app is not yet hidden
since the close is delayed.
4. IME is recalculated and doesn't see any closing app. IME is
targeted to launcher.
5. Prevous app is ready to close.

By this point, the IME was already incorrectly targeting launcher, which
causes the flicker since IME will get set relative to launcher.

Test: Open Chrome with IME. Press home. No flicker.
Change-Id: Ie3553b0a01ad567d8b34c3453ad838b88684e79d
Fixes: 80352830
parent e3348a25
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -777,6 +777,13 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
        }
    }

    /**
     * See {@link AppWindowContainerController#setWillCloseOrEnterPip(boolean)}
     */
    void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
        getWindowContainerController().setWillCloseOrEnterPip(willCloseOrEnterPip);
    }

    static class Token extends IApplicationToken.Stub {
        private final WeakReference<ActivityRecord> weakActivity;
        private final String name;
+6 −2
Original line number Diff line number Diff line
@@ -134,7 +134,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionSession;
import android.util.ArraySet;
@@ -1557,6 +1556,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);

        if (prev != null) {
            prev.setWillCloseOrEnterPip(false);
            final boolean wasStopping = prev.isState(STOPPING);
            prev.setState(PAUSED, "completePausedLocked");
            if (prev.finishing) {
@@ -2411,11 +2411,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);

        boolean lastResumedCanPip = false;
        ActivityRecord lastResumed = null;
        final ActivityStack lastFocusedStack = mStackSupervisor.getLastStack();
        if (lastFocusedStack != null && lastFocusedStack != this) {
            // So, why aren't we using prev here??? See the param comment on the method. prev doesn't
            // represent the last resumed activity. However, the last focus stack does if it isn't null.
            final ActivityRecord lastResumed = lastFocusedStack.mResumedActivity;
            lastResumed = lastFocusedStack.mResumedActivity;
            if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) {
                // The user isn't leaving if this stack is the multi-window mode and the last
                // focused stack should still be visible.
@@ -2450,6 +2451,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                mService.updateLruProcessLocked(next.app, true, null);
            }
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            if (lastResumed != null) {
                lastResumed.setWillCloseOrEnterPip(true);
            }
            return true;
        } else if (mResumedActivity == next && next.isState(RESUMED)
                && mStackSupervisor.allResumedActivitiesComplete()) {
+15 −0
Original line number Diff line number Diff line
@@ -753,6 +753,21 @@ public class AppWindowContainerController
        return mListener != null && mListener.keyDispatchingTimedOut(reason, windowPid);
    }

    /**
     * Notifies AWT that this app is waiting to pause in order to determine if it will enter PIP.
     * This information helps AWT know that the app is in the process of pausing before it gets the
     * signal on the WM side.
     */
    public void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
        synchronized (mWindowMap) {
            if (mContainer == null) {
                return;
            }

            mContainer.setWillCloseOrEnterPip(willCloseOrEnterPip);
        }
    }

    @Override
    public String toString() {
        return "AppWindowContainerController{"
+25 −2
Original line number Diff line number Diff line
@@ -32,12 +32,11 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;

import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static android.view.WindowManager.TRANSIT_UNSET;
import static com.android.server.wm.AppTransition.isKeyguardGoingAwayTransit;

import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
@@ -257,6 +256,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
    private RemoteAnimationDefinition mRemoteAnimationDefinition;
    private AnimatingAppWindowTokenRegistry mAnimatingAppWindowTokenRegistry;

    /**
     * A flag to determine if this AWT is in the process of closing or entering PIP. This is needed
     * to help AWT know that the app is in the process of closing but hasn't yet started closing on
     * the WM side.
     */
    private boolean mWillCloseOrEnterPip;

    AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
            DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
            boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
@@ -2235,4 +2241,21 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
    boolean isLetterboxOverlappingWith(Rect rect) {
        return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
    }

    /**
     * Sets if this AWT is in the process of closing or entering PIP.
     * {@link #mWillCloseOrEnterPip}}
     */
    void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
        mWillCloseOrEnterPip = willCloseOrEnterPip;
    }

    /**
     * Returns whether this AWT is considered closing. Conditions are either
     * 1. Is this app animating and was requested to be hidden
     * 2. App is delayed closing since it might enter PIP.
     */
    boolean isClosingOrEnteringPip() {
        return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
    }
}
+1 −4
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.AppOpsManager.OP_TOAST_WINDOW;
import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -2737,8 +2735,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    }

    boolean isClosing() {
        return mAnimatingExit || (mAppToken != null && mAppToken.isAnimating()
                && mAppToken.hiddenRequested);
        return mAnimatingExit || (mAppToken != null && mAppToken.isClosingOrEnteringPip());
    }

    void addWinAnimatorToList(ArrayList<WindowStateAnimator> animators) {
+1 −1

File changed.

Contains only whitespace changes.

Loading