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

Commit 0429f352 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Freeze task bounds when relaunching

To make sure that task is only laid out with the size
that matches the current configuration, we have to "freeze"
the task bounds when we send a configuration change. Without this
change, it could happen that the app already laid out with the new
task bounds, but still had the old configuration, leading to
wrong layouts.

Bug: 26311778
Bug: 25015474

Change-Id: I8d3a3fdf3735f446a4affbbdb4986dafc97623a5
parent fe89d122
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1868,6 +1868,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
                mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
            }
        }

        // We might trigger a configuration change. Save the current task bounds for freezing.
        mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
        stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs,
                mTmpBounds, mTmpInsetBounds);
        stack.setBounds(bounds);
+24 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.server.wm.WindowManagerService.H;

import android.annotation.NonNull;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.os.Message;
import android.os.RemoteException;
import android.util.Slog;
@@ -39,6 +40,7 @@ import android.view.View;
import android.view.WindowManager;

import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;

class AppTokenList extends ArrayList<AppWindowToken> {
@@ -126,6 +128,8 @@ class AppWindowToken extends WindowToken {

    boolean mAlwaysFocusable;

    ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();

    AppWindowToken(WindowManagerService _service, IApplicationToken _token,
            boolean _voiceInteraction) {
        super(_service, _token.asBinder(),
@@ -437,6 +441,23 @@ class AppWindowToken extends WindowToken {
        }
    }

    /**
     * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
     * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
     * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
     * with a queue.
     */
    void freezeBounds() {
        mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));
    }

    /**
     * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
     */
    void unfreezeBounds() {
        mFrozenBounds.remove();
    }

    @Override
    void dump(PrintWriter pw, String prefix) {
        super.dump(pw, prefix);
@@ -483,6 +504,9 @@ class AppWindowToken extends WindowToken {
                    pw.print(" startingDisplayed="); pw.print(startingDisplayed);
                    pw.print(" startingMoved"); pw.println(startingMoved);
        }
        if (!mFrozenBounds.isEmpty()) {
            pw.print(prefix); pw.print("mFrozenBounds="); pw.print(mFrozenBounds);
        }
    }

    @Override
+11 −2
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ class Task implements DimLayer.DimLayerUser {

    // Content limits relative to the DisplayContent this sits in.
    private Rect mBounds = new Rect();
    final Rect mPreparedFrozenBounds = new Rect();

    // Bounds used to calculate the insets.
    private final Rect mTempInsetBounds = new Rect();
@@ -200,8 +201,7 @@ class Task implements DimLayer.DimLayerUser {
    boolean removeAppToken(AppWindowToken wtoken) {
        boolean removed = mAppTokens.remove(wtoken);
        if (mAppTokens.size() == 0) {
            EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId,
                    "removeAppToken: last token");
            EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "removeAppToken: last token");
            if (mDeferRemoval) {
                removeLocked();
            }
@@ -314,6 +314,14 @@ class Task implements DimLayer.DimLayerUser {
        return true;
    }

    /**
     * Prepares the task bounds to be frozen with the current size. See
     * {@link AppWindowToken#freezeBounds}.
     */
    void prepareFreezingBounds() {
        mPreparedFrozenBounds.set(mBounds);
    }

    boolean scrollLocked(Rect bounds) {
        // shift the task bound if it doesn't fully cover the stack area
        mStack.getDimBounds(mTmpRect);
@@ -601,5 +609,6 @@ class Task implements DimLayer.DimLayerUser {
            pw.print(prefix + prefix); pw.print("mBounds="); pw.println(mBounds.toShortString());
            pw.print(prefix + prefix); pw.print("mdr="); pw.println(mDeferRemoval);
            pw.print(prefix + prefix); pw.print("appTokens="); pw.println(mAppTokens);
            pw.print(prefix + prefix); pw.print("mTempInsetBounds="); pw.println(mTempInsetBounds);
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -148,6 +148,13 @@ public class TaskStack implements DimLayer.DimLayerUser {
        return true;
    }

    void prepareFreezingTaskBounds() {
        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
            final Task task = mTasks.get(taskNdx);
            task.prepareFreezingBounds();
        }
    }

    boolean isFullscreenBounds(Rect bounds) {
        if (mDisplayContent == null || bounds == null) {
            return true;
+23 −5
Original line number Diff line number Diff line
@@ -203,7 +203,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
@@ -4843,6 +4842,17 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    public void prepareFreezingTaskBounds(int stackId) {
        synchronized (mWindowMap) {
            final TaskStack stack = mStackIdToStack.get(stackId);
            if (stack == null) {
                throw new IllegalArgumentException("prepareFreezingTaskBounds: stackId " + stackId
                        + " not found.");
            }
            stack.prepareFreezingTaskBounds();
        }
    }

    public void positionTaskInStack(int taskId, int stackId, int position, Rect bounds,
            Configuration config) {
        synchronized (mWindowMap) {
@@ -9472,8 +9482,8 @@ public class WindowManagerService extends IWindowManager.Stub
    public void notifyAppRelaunching(IBinder token) {
        synchronized (mWindowMap) {
            AppWindowToken appWindow = findAppWindowToken(token);
            if (appWindow != null) {
                // TODO: Do something useful
            if (canFreezeBounds(appWindow)) {
                appWindow.freezeBounds();
            }
        }
    }
@@ -9481,10 +9491,18 @@ public class WindowManagerService extends IWindowManager.Stub
    public void notifyAppRelaunchingFinished(IBinder token) {
        synchronized (mWindowMap) {
            AppWindowToken appWindow = findAppWindowToken(token);
            if (appWindow != null) {
                // TODO: Do something useful
            if (canFreezeBounds(appWindow)) {
                appWindow.unfreezeBounds();
            }
        }
    }

    private boolean canFreezeBounds(AppWindowToken appWindow) {

        // For freeform windows, we can't freeze the bounds at the moment because this would make
        // the resizing unresponsive.
        return appWindow != null && appWindow.mTask != null
                && !appWindow.mTask.inFreeformWorkspace();
    }

    void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Loading