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

Commit 26c8c42b authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Also freeze configuration when freezing bounds

We also need to freeze the override configuration so we don't report
the new configuration too early, which leads to bugs.

Bug: 27915587
Change-Id: Idffadbb02ab0311796caa760ae1f467fd2d17768
parent b35301e4
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import static android.view.PointerIcon.STYLE_VERTICAL_DOUBLE_ARROW;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
import android.app.ActivityManager.StackId;
import android.content.Context;
+14 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import com.android.server.wm.WindowManagerService.H;

import android.annotation.NonNull;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Message;
import android.os.RemoteException;
@@ -133,6 +134,7 @@ class AppWindowToken extends WindowToken {
    int mPendingRelaunchCount;

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

    AppWindowToken(WindowManagerService _service, IApplicationToken _token,
            boolean _voiceInteraction) {
@@ -675,6 +677,16 @@ class AppWindowToken extends WindowToken {
     */
    private void freezeBounds() {
        mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));

        if (mTask.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
            // We didn't call prepareFreezingBounds on the task, so use the current value.
            final Configuration config = new Configuration(service.mCurConfiguration);
            config.updateFrom(mTask.mOverrideConfig);
            mFrozenMergedConfig.offer(config);
        } else {
            mFrozenMergedConfig.offer(new Configuration(mTask.mPreparedFrozenMergedConfig));
        }
        mTask.mPreparedFrozenMergedConfig.setToDefaults();
    }

    /**
@@ -682,6 +694,7 @@ class AppWindowToken extends WindowToken {
     */
    private void unfreezeBounds() {
        mFrozenBounds.remove();
        mFrozenMergedConfig.remove();
        for (int i = windows.size() - 1; i >= 0; i--) {
            final WindowState win = windows.get(i);
            if (!win.mHasSurface) {
@@ -747,6 +760,7 @@ class AppWindowToken extends WindowToken {
        }
        if (!mFrozenBounds.isEmpty()) {
            pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
            pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
        }
        if (mPendingRelaunchCount != 0) {
            pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
+4 −1
Original line number Diff line number Diff line
@@ -62,6 +62,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();
    final Configuration mPreparedFrozenMergedConfig = new Configuration();

    private Rect mPreScrollBounds = new Rect();
    private boolean mScrollValid;
@@ -77,7 +78,7 @@ class Task implements DimLayer.DimLayerUser {

    // Contains configurations settings that are different from the global configuration due to
    // stack specific operations. E.g. {@link #setBounds}.
    Configuration mOverrideConfig;
    Configuration mOverrideConfig = Configuration.EMPTY;

    // For comparison with DisplayContent bounds.
    private Rect mTmpRect = new Rect();
@@ -320,6 +321,8 @@ class Task implements DimLayer.DimLayerUser {
     */
    void prepareFreezingBounds() {
        mPreparedFrozenBounds.set(mBounds);
        mPreparedFrozenMergedConfig.setTo(mService.mCurConfiguration);
        mPreparedFrozenMergedConfig.updateFrom(mOverrideConfig);
    }

    /**
+11 −0
Original line number Diff line number Diff line
@@ -3737,6 +3737,7 @@ public class WindowManagerService extends IWindowManager.Stub
            if (!configChanged) {
                return null;
            }
            prepareFreezingAllTaskBounds();
            mCurConfiguration = new Configuration(config);
            return onConfigurationChanged();
        }
@@ -3752,6 +3753,16 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    private void prepareFreezingAllTaskBounds() {
        for (int i = mDisplayContents.size() - 1; i >= 0; i--) {
            ArrayList<TaskStack> stacks = mDisplayContents.valueAt(i).getStacks();
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final TaskStack stack = stacks.get(stackNdx);
                stack.prepareFreezingTaskBounds();
            }
        }

    }
    private int[] onConfigurationChanged() {
        mPolicy.onConfigurationChanged();

+27 −30
Original line number Diff line number Diff line
@@ -190,8 +190,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {

    int mLayoutSeq = -1;

    private Configuration mConfiguration = Configuration.EMPTY;
    private Configuration mOverrideConfig = Configuration.EMPTY;
    private final Configuration mTmpConfig = new Configuration();
    // Represents the changes from our override configuration applied
    // to the global configuration. This is the only form of configuration
    // which is suitable for delivery to the client.
@@ -1417,13 +1416,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {
    }

    boolean isConfigChanged() {
        final Task task = getTask();
        final Configuration overrideConfig =
                (task != null) ? task.mOverrideConfig : Configuration.EMPTY;
        final Configuration serviceConfig = mService.mCurConfiguration;
        boolean configChanged =
                (mConfiguration != serviceConfig && mConfiguration.diff(serviceConfig) != 0)
                || (mOverrideConfig != overrideConfig && !mOverrideConfig.equals(overrideConfig));
        getMergedConfig(mTmpConfig);

        // If the merged configuration is still empty, it means that we haven't issues the
        // configuration to the client yet and we need to return true so the configuration updates.
        boolean configChanged = mMergedConfiguration.equals(Configuration.EMPTY)
                || mTmpConfig.diff(mMergedConfiguration) != 0;

        if ((mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
            // Retain configuration changed status until resetConfiguration called.
@@ -1457,18 +1455,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
        }
    }

    private void setConfiguration(
            final Configuration newConfig, final Configuration newOverrideConfig) {
        mConfiguration = newConfig;
        mOverrideConfig = newOverrideConfig;
        mConfigHasChanged = false;

        mMergedConfiguration.setTo(newConfig);
        if (newOverrideConfig != null && newOverrideConfig != Configuration.EMPTY) {
            mMergedConfiguration.updateFrom(newOverrideConfig);
        }
    }

    void setHasSurface(boolean hasSurface) {
        mHasSurface = hasSurface;
    }
@@ -2266,18 +2252,32 @@ final class WindowState implements WindowManagerPolicy.WindowState {
     * @return A configuration suitable for sending to the client.
     */
    private Configuration updateConfiguration() {
        final Task task = getTask();
        final Configuration overrideConfig =
            (task != null) ? task.mOverrideConfig : Configuration.EMPTY;
        final boolean configChanged = isConfigChanged();
        getMergedConfig(mMergedConfiguration);
        mConfigHasChanged = false;
        if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) {
            Slog.i(TAG, "Sending new config to window " + this + ": " +
                    " / config=" + mService.mCurConfiguration + " overrideConfig=" + overrideConfig);
                    " / mergedConfig=" + mMergedConfiguration);
        }
        setConfiguration(mService.mCurConfiguration, overrideConfig);
        return mMergedConfiguration;
    }

    private void getMergedConfig(Configuration outConfig) {
        if (mAppToken != null && mAppToken.mFrozenMergedConfig.size() > 0) {
            outConfig.setTo(mAppToken.mFrozenMergedConfig.peek());
            return;
        }
        final Task task = getTask();
        final Configuration overrideConfig = task != null
                ? task.mOverrideConfig
                : Configuration.EMPTY;
        final Configuration serviceConfig = mService.mCurConfiguration;
        outConfig.setTo(serviceConfig);
        if (overrideConfig != Configuration.EMPTY) {
            outConfig.updateFrom(overrideConfig);
        }
    }

    void reportResized() {
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag());
        try {
@@ -2572,10 +2572,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
                getTouchableRegion(region);
                pw.print(prefix); pw.print("touchable region="); pw.println(region);
            }
            pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
            if (mOverrideConfig != Configuration.EMPTY) {
                pw.print(prefix); pw.print("mOverrideConfig="); pw.println(mOverrideConfig);
            }
            pw.print(prefix); pw.print("mMergedConfiguration="); pw.println(mMergedConfiguration);
        }
        pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
                pw.print(" mShownPosition="); mShownPosition.printShortString(pw);