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

Commit 479d1df9 authored by Maryam Dehaini's avatar Maryam Dehaini
Browse files

Hide caption when task is in immersive mode

Adds DesktopModeOnInsetsChangedListener which listens for inset changes
and checks to see if the status bar inset has disappeared, signifying
that the task is in immersive mode. If so, the caption will become
invisible. When the status bar inset reappears, we know we have exited
immersive mode and make the caption visible again.

Test: Open Youtube and expand window to fullscreen. The window
decoration should disappear. When we exit fullscreen, window decoration
should reappear.
Bug: 286344314

Change-Id: If913a81e94404c21b544d6e6bba6c35ab2906d8d
parent f2a089d3
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -203,6 +203,7 @@ public abstract class WMShellModule {
            ShellTaskOrganizer taskOrganizer,
            ShellTaskOrganizer taskOrganizer,
            DisplayController displayController,
            DisplayController displayController,
            ShellController shellController,
            ShellController shellController,
            DisplayInsetsController displayInsetsController,
            SyncTransactionQueue syncQueue,
            SyncTransactionQueue syncQueue,
            Transitions transitions,
            Transitions transitions,
            Optional<DesktopTasksController> desktopTasksController,
            Optional<DesktopTasksController> desktopTasksController,
@@ -218,6 +219,7 @@ public abstract class WMShellModule {
                    taskOrganizer,
                    taskOrganizer,
                    displayController,
                    displayController,
                    shellController,
                    shellController,
                    displayInsetsController,
                    syncQueue,
                    syncQueue,
                    transitions,
                    transitions,
                    desktopTasksController,
                    desktopTasksController,
+5 −0
Original line number Original line Diff line number Diff line
@@ -231,4 +231,9 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
    int getCaptionHeightId(@WindowingMode int windowingMode) {
    int getCaptionHeightId(@WindowingMode int windowingMode) {
        return R.dimen.freeform_decor_caption_height;
        return R.dimen.freeform_decor_caption_height;
    }
    }

    @Override
    int getCaptionViewId() {
        return R.id.caption;
    }
}
}
+43 −2
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.WindowInsets.Type.statusBars;


import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
@@ -50,6 +51,8 @@ import android.view.InputChannel;
import android.view.InputEvent;
import android.view.InputEvent;
import android.view.InputEventReceiver;
import android.view.InputEventReceiver;
import android.view.InputMonitor;
import android.view.InputMonitor;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.MotionEvent;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceControl.Transaction;
@@ -67,6 +70,7 @@ import com.android.wm.shell.R;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
@@ -131,6 +135,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
    private final DesktopModeKeyguardChangeListener mDesktopModeKeyguardChangeListener =
    private final DesktopModeKeyguardChangeListener mDesktopModeKeyguardChangeListener =
            new DesktopModeKeyguardChangeListener();
            new DesktopModeKeyguardChangeListener();
    private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
    private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
    private final DisplayInsetsController mDisplayInsetsController;
    private boolean mInImmersiveMode;


    public DesktopModeWindowDecorViewModel(
    public DesktopModeWindowDecorViewModel(
            Context context,
            Context context,
@@ -141,6 +147,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            ShellTaskOrganizer taskOrganizer,
            ShellTaskOrganizer taskOrganizer,
            DisplayController displayController,
            DisplayController displayController,
            ShellController shellController,
            ShellController shellController,
            DisplayInsetsController displayInsetsController,
            SyncTransactionQueue syncQueue,
            SyncTransactionQueue syncQueue,
            Transitions transitions,
            Transitions transitions,
            Optional<DesktopTasksController> desktopTasksController,
            Optional<DesktopTasksController> desktopTasksController,
@@ -156,6 +163,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                taskOrganizer,
                taskOrganizer,
                displayController,
                displayController,
                shellController,
                shellController,
                displayInsetsController,
                syncQueue,
                syncQueue,
                transitions,
                transitions,
                desktopTasksController,
                desktopTasksController,
@@ -176,6 +184,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            ShellTaskOrganizer taskOrganizer,
            ShellTaskOrganizer taskOrganizer,
            DisplayController displayController,
            DisplayController displayController,
            ShellController shellController,
            ShellController shellController,
            DisplayInsetsController displayInsetsController,
            SyncTransactionQueue syncQueue,
            SyncTransactionQueue syncQueue,
            Transitions transitions,
            Transitions transitions,
            Optional<DesktopTasksController> desktopTasksController,
            Optional<DesktopTasksController> desktopTasksController,
@@ -191,6 +200,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        mTaskOrganizer = taskOrganizer;
        mTaskOrganizer = taskOrganizer;
        mShellController = shellController;
        mShellController = shellController;
        mDisplayController = displayController;
        mDisplayController = displayController;
        mDisplayInsetsController = displayInsetsController;
        mSyncQueue = syncQueue;
        mSyncQueue = syncQueue;
        mTransitions = transitions;
        mTransitions = transitions;
        mDesktopTasksController = desktopTasksController;
        mDesktopTasksController = desktopTasksController;
@@ -213,6 +223,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            }
            }
        });
        });
        mShellCommandHandler.addDumpCallback(this::dump, this);
        mShellCommandHandler.addDumpCallback(this::dump, this);
        mDisplayInsetsController.addInsetsChangedListener(mContext.getDisplayId(),
                new DesktopModeOnInsetsChangedListener());
    }
    }


    @Override
    @Override
@@ -655,9 +667,9 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
    private void handleReceivedMotionEvent(MotionEvent ev, InputMonitor inputMonitor) {
    private void handleReceivedMotionEvent(MotionEvent ev, InputMonitor inputMonitor) {
        final DesktopModeWindowDecoration relevantDecor = getRelevantWindowDecor(ev);
        final DesktopModeWindowDecoration relevantDecor = getRelevantWindowDecor(ev);
        if (DesktopModeStatus.isEnabled()) {
        if (DesktopModeStatus.isEnabled()) {
            if (relevantDecor == null
            if (!mInImmersiveMode && (relevantDecor == null
                    || relevantDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM
                    || relevantDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM
                    || mTransitionDragActive) {
                    || mTransitionDragActive)) {
                handleCaptionThroughStatusBar(ev, relevantDecor);
                handleCaptionThroughStatusBar(ev, relevantDecor);
            }
            }
        }
        }
@@ -1051,6 +1063,35 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            return mIsKeyguardVisible && mIsKeyguardOccluded;
            return mIsKeyguardVisible && mIsKeyguardOccluded;
        }
        }
    }
    }

    @VisibleForTesting
    class DesktopModeOnInsetsChangedListener implements
            DisplayInsetsController.OnInsetsChangedListener {
        @Override
        public void insetsChanged(InsetsState insetsState) {
            for (int i = 0; i < insetsState.sourceSize(); i++) {
                final InsetsSource source = insetsState.sourceAt(i);
                if (source.getType() != statusBars()) {
                    continue;
                }

                final DesktopModeWindowDecoration decor = getFocusedDecor();
                if (decor == null) {
                    return;
                }
                // If status bar inset is visible, top task is not in immersive mode
                final boolean inImmersiveMode = !source.isVisible();
                // Calls WindowDecoration#relayout if decoration visibility needs to be updated
                if (inImmersiveMode != mInImmersiveMode) {
                    decor.relayout(decor.mTaskInfo);
                    mInImmersiveMode = inImmersiveMode;
                }

                return;
            }
        }
    }

}
}


+5 −0
Original line number Original line Diff line number Diff line
@@ -638,6 +638,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        return loadDimensionPixelSize(mContext.getResources(), getCaptionHeightId(windowingMode));
        return loadDimensionPixelSize(mContext.getResources(), getCaptionHeightId(windowingMode));
    }
    }


    @Override
    int getCaptionViewId() {
        return R.id.desktop_mode_caption;
    }

    /**
    /**
     * Add transition to mTransitionsPausingRelayout
     * Add transition to mTransitionsPausingRelayout
     */
     */
+53 −7
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.wm.shell.windowdecor;


import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowInsets.Type.statusBars;


import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.WindowConfiguration.WindowingMode;
import android.app.WindowConfiguration.WindowingMode;
@@ -30,6 +31,8 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Binder;
import android.view.Display;
import android.view.Display;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.SurfaceControlViewHost;
@@ -119,6 +122,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
    private WindowlessWindowManager mCaptionWindowManager;
    private WindowlessWindowManager mCaptionWindowManager;
    private SurfaceControlViewHost mViewHost;
    private SurfaceControlViewHost mViewHost;
    private Configuration mWindowDecorConfig;
    private Configuration mWindowDecorConfig;
    private boolean mIsCaptionVisible;


    private final Binder mOwner = new Binder();
    private final Binder mOwner = new Binder();
    private final Rect mCaptionInsetsRect = new Rect();
    private final Rect mCaptionInsetsRect = new Rect();
@@ -225,6 +229,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
                    .inflate(params.mLayoutResId, null);
                    .inflate(params.mLayoutResId, null);
        }
        }


        updateCaptionVisibility(outResult.mRootView, mTaskInfo.displayId);

        final Resources resources = mDecorWindowContext.getResources();
        final Resources resources = mDecorWindowContext.getResources();
        final Configuration taskConfig = mTaskInfo.getConfiguration();
        final Configuration taskConfig = mTaskInfo.getConfiguration();
        final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
        final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
@@ -272,12 +278,20 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>


            // Caption insets
            // Caption insets
            mCaptionInsetsRect.set(taskBounds);
            mCaptionInsetsRect.set(taskBounds);
            mCaptionInsetsRect.bottom = mCaptionInsetsRect.top + captionHeight + params.mCaptionY;
            if (mIsCaptionVisible) {
                mCaptionInsetsRect.bottom =
                        mCaptionInsetsRect.top + captionHeight + params.mCaptionY;
                wct.addInsetsSource(mTaskInfo.token,
                wct.addInsetsSource(mTaskInfo.token,
                        mOwner, 0 /* index */, WindowInsets.Type.captionBar(), mCaptionInsetsRect);
                        mOwner, 0 /* index */, WindowInsets.Type.captionBar(), mCaptionInsetsRect);
                wct.addInsetsSource(mTaskInfo.token,
                wct.addInsetsSource(mTaskInfo.token,
                        mOwner, 0 /* index */, WindowInsets.Type.mandatorySystemGestures(),
                        mOwner, 0 /* index */, WindowInsets.Type.mandatorySystemGestures(),
                        mCaptionInsetsRect);
                        mCaptionInsetsRect);
            } else {
                wct.removeInsetsSource(mTaskInfo.token, mOwner, 0 /* index */,
                        WindowInsets.Type.captionBar());
                wct.removeInsetsSource(mTaskInfo.token, mOwner, 0 /* index */,
                        WindowInsets.Type.mandatorySystemGestures());
            }
        } else {
        } else {
            startT.hide(mCaptionContainerSurface);
            startT.hide(mCaptionContainerSurface);
        }
        }
@@ -348,10 +362,41 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        }
        }
    }
    }


    /**
     * Checks if task has entered/exited immersive mode and requires a change in caption visibility.
     */
    private void updateCaptionVisibility(View rootView, int displayId) {
        final InsetsState insetsState = mDisplayController.getInsetsState(displayId);
        for (int i = 0; i < insetsState.sourceSize(); i++) {
            final InsetsSource source = insetsState.sourceAt(i);
            if (source.getType() != statusBars()) {
                continue;
            }

            mIsCaptionVisible = source.isVisible();
            setCaptionVisibility(rootView, mIsCaptionVisible);

            return;
        }
    }

    private void setCaptionVisibility(View rootView, boolean visible) {
        if (rootView == null) {
            return;
        }
        final int v = visible ? View.VISIBLE : View.GONE;
        final View captionView = rootView.findViewById(getCaptionViewId());
        captionView.setVisibility(v);
    }

    int getCaptionHeightId(@WindowingMode int windowingMode) {
    int getCaptionHeightId(@WindowingMode int windowingMode) {
        return Resources.ID_NULL;
        return Resources.ID_NULL;
    }
    }


    int getCaptionViewId() {
        return Resources.ID_NULL;
    }

    /**
    /**
     * Obtains the {@link Display} instance for the display ID in {@link #mTaskInfo} if it exists or
     * Obtains the {@link Display} instance for the display ID in {@link #mTaskInfo} if it exists or
     * registers {@link #mOnDisplaysChangedListener} if it doesn't.
     * registers {@link #mOnDisplaysChangedListener} if it doesn't.
@@ -466,7 +511,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
     */
     */
    public void addCaptionInset(WindowContainerTransaction wct) {
    public void addCaptionInset(WindowContainerTransaction wct) {
        final int captionHeightId = getCaptionHeightId(mTaskInfo.getWindowingMode());
        final int captionHeightId = getCaptionHeightId(mTaskInfo.getWindowingMode());
        if (!ViewRootImpl.CAPTION_ON_SHELL || captionHeightId == Resources.ID_NULL) {
        if (!ViewRootImpl.CAPTION_ON_SHELL || captionHeightId == Resources.ID_NULL
                || !mIsCaptionVisible) {
            return;
            return;
        }
        }


Loading