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

Commit 68245f16 authored by Kazuki Takise's avatar Kazuki Takise Committed by Android (Google) Code Review
Browse files

Merge "Migrate TaskInfo#isFocused to FocusTransitionObserver for windecor" into main

parents f6002bc0 01fff9bf
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -264,7 +264,8 @@ public abstract class WMShellModule {
            Optional<DesktopTasksLimiter> desktopTasksLimiter,
            AppHandleEducationController appHandleEducationController,
            WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
            Optional<DesktopActivityOrientationChangeHandler> desktopActivityOrientationHandler) {
            Optional<DesktopActivityOrientationChangeHandler> desktopActivityOrientationHandler,
            FocusTransitionObserver focusTransitionObserver) {
        if (DesktopModeStatus.canEnterDesktopMode(context)) {
            return new DesktopModeWindowDecorViewModel(
                    context,
@@ -291,7 +292,8 @@ public abstract class WMShellModule {
                    desktopTasksLimiter,
                    appHandleEducationController,
                    windowDecorCaptionHandleRepository,
                    desktopActivityOrientationHandler);
                    desktopActivityOrientationHandler,
                    focusTransitionObserver);
        }
        return new CaptionWindowDecorViewModel(
                context,
@@ -305,7 +307,8 @@ public abstract class WMShellModule {
                displayController,
                rootTaskDisplayAreaOrganizer,
                syncQueue,
                transitions);
                transitions,
                focusTransitionObserver);
    }

    @WMSingleton
+25 −7
Original line number Diff line number Diff line
@@ -58,9 +58,11 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.shared.FocusTransitionListener;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;

@@ -68,7 +70,7 @@ import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
 * View model for the window decoration with a caption and shadows. Works with
 * {@link CaptionWindowDecoration}.
 */
public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusTransitionListener {
    private static final String TAG = "CaptionWindowDecorViewModel";

    private final ShellTaskOrganizer mTaskOrganizer;
@@ -85,6 +87,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
    private final Region mExclusionRegion = Region.obtain();
    private final InputManager mInputManager;
    private TaskOperations mTaskOperations;
    private FocusTransitionObserver mFocusTransitionObserver;

    /**
     * Whether to pilfer the next motion event to send cancellations to the windows below.
@@ -121,7 +124,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
            DisplayController displayController,
            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
            SyncTransactionQueue syncQueue,
            Transitions transitions) {
            Transitions transitions,
            FocusTransitionObserver focusTransitionObserver) {
        mContext = context;
        mMainExecutor = shellExecutor;
        mMainHandler = mainHandler;
@@ -133,6 +137,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
        mSyncQueue = syncQueue;
        mTransitions = transitions;
        mFocusTransitionObserver = focusTransitionObserver;
        if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
            mTaskOperations = new TaskOperations(null, mContext, mSyncQueue);
        }
@@ -148,6 +153,16 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to register window manager callbacks", e);
        }
        mFocusTransitionObserver.setLocalFocusTransitionListener(this, mMainExecutor);
    }

    @Override
    public void onFocusedTaskChanged(int taskId, boolean isFocusedOnDisplay,
            boolean isFocusedGlobally) {
        final WindowDecoration decor = mWindowDecorByTaskId.get(taskId);
        if (decor != null) {
            decor.relayout(decor.mTaskInfo, isFocusedGlobally);
        }
    }

    @Override
@@ -180,7 +195,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
            return;
        }

        decoration.relayout(taskInfo);
        decoration.relayout(taskInfo, decoration.mHasGlobalFocus);
    }

    @Override
@@ -217,7 +232,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
            createWindowDecoration(taskInfo, taskSurface, startT, finishT);
        } else {
            decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
                    false /* setTaskCropAndPosition */);
                    false /* setTaskCropAndPosition */,
                    mFocusTransitionObserver.hasGlobalFocus(taskInfo));
        }
    }

@@ -230,7 +246,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        if (decoration == null) return;

        decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
                false /* setTaskCropAndPosition */);
                false /* setTaskCropAndPosition */,
                mFocusTransitionObserver.hasGlobalFocus(taskInfo));
    }

    @Override
@@ -308,7 +325,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        windowDecoration.setDragPositioningCallback(taskPositioner);
        windowDecoration.setTaskDragResizer(taskPositioner);
        windowDecoration.relayout(taskInfo, startT, finishT,
                false /* applyStartTransactionOnDraw */, false /* setTaskCropAndPosition */);
                false /* applyStartTransactionOnDraw */, false /* setTaskCropAndPosition */,
                mFocusTransitionObserver.hasGlobalFocus(taskInfo));
    }

    private class CaptionTouchEventListener implements
@@ -359,7 +377,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
            }
            if (e.getAction() == MotionEvent.ACTION_DOWN) {
                final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
                if (!taskInfo.isFocused) {
                if (!mFocusTransitionObserver.hasGlobalFocus(taskInfo)) {
                    final WindowContainerTransaction wct = new WindowContainerTransaction();
                    wct.reorder(mTaskToken, true /* onTop */, true /* includingParents */);
                    mSyncQueue.queue(wct);
+8 −6
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
    }

    @Override
    void relayout(RunningTaskInfo taskInfo) {
    void relayout(RunningTaskInfo taskInfo, boolean hasGlobalFocus) {
        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        // The crop and position of the task should only be set when a task is fluid resizing. In
        // all other cases, it is expected that the transition handler positions and crops the task
@@ -185,7 +185,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
        // synced with the buffer transaction (that draws the View). Both will be shown on screen
        // at the same, whereas applying them independently causes flickering. See b/270202228.
        relayout(taskInfo, t, t, true /* applyStartTransactionOnDraw */,
                shouldSetTaskPositionAndCrop);
                shouldSetTaskPositionAndCrop, hasGlobalFocus);
    }

    @VisibleForTesting
@@ -196,12 +196,13 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
            boolean setTaskCropAndPosition,
            boolean isStatusBarVisible,
            boolean isKeyguardVisibleAndOccluded,
            InsetsState displayInsetsState) {
            InsetsState displayInsetsState,
            boolean hasGlobalFocus) {
        relayoutParams.reset();
        relayoutParams.mRunningTaskInfo = taskInfo;
        relayoutParams.mLayoutResId = R.layout.caption_window_decor;
        relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
        relayoutParams.mShadowRadiusId = taskInfo.isFocused
        relayoutParams.mShadowRadiusId = hasGlobalFocus
                ? R.dimen.freeform_decor_shadow_focused_thickness
                : R.dimen.freeform_decor_shadow_unfocused_thickness;
        relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
@@ -233,7 +234,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
    @SuppressLint("MissingPermission")
    void relayout(RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean setTaskCropAndPosition) {
            boolean applyStartTransactionOnDraw, boolean setTaskCropAndPosition,
            boolean hasGlobalFocus) {
        final boolean isFreeform =
                taskInfo.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM;
        final boolean isDragResizeable = ENABLE_WINDOWING_SCALED_RESIZING.isTrue()
@@ -245,7 +247,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL

        updateRelayoutParams(mRelayoutParams, taskInfo, applyStartTransactionOnDraw,
                setTaskCropAndPosition, mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded,
                mDisplayController.getInsetsState(taskInfo.displayId));
                mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus);

        relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
        // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
+32 −11
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ import com.android.wm.shell.desktopmode.DesktopWallpaperActivity;
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
import com.android.wm.shell.desktopmode.education.AppHandleEducationController;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.shared.FocusTransitionListener;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -123,6 +124,7 @@ import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener;
import com.android.wm.shell.windowdecor.extension.InsetsStateKt;
@@ -132,20 +134,21 @@ import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
import kotlin.Pair;
import kotlin.Unit;

import kotlinx.coroutines.ExperimentalCoroutinesApi;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

import kotlinx.coroutines.ExperimentalCoroutinesApi;

/**
 * View model for the window decoration with a caption and shadows. Works with
 * {@link DesktopModeWindowDecoration}.
 */

public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        FocusTransitionListener {
    private static final String TAG = "DesktopModeWindowDecorViewModel";

    private final DesktopModeWindowDecoration.Factory mDesktopModeWindowDecorFactory;
@@ -215,6 +218,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                }
            };
    private final TaskPositionerFactory mTaskPositionerFactory;
    private final FocusTransitionObserver mFocusTransitionObserver;

    public DesktopModeWindowDecorViewModel(
            Context context,
@@ -241,7 +245,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            Optional<DesktopTasksLimiter> desktopTasksLimiter,
            AppHandleEducationController appHandleEducationController,
            WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler) {
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
            FocusTransitionObserver focusTransitionObserver) {
        this(
                context,
                shellExecutor,
@@ -273,7 +278,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                appHandleEducationController,
                windowDecorCaptionHandleRepository,
                activityOrientationChangeHandler,
                new TaskPositionerFactory());
                new TaskPositionerFactory(),
                focusTransitionObserver);
    }

    @VisibleForTesting
@@ -308,7 +314,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            AppHandleEducationController appHandleEducationController,
            WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
            TaskPositionerFactory taskPositionerFactory) {
            TaskPositionerFactory taskPositionerFactory,
            FocusTransitionObserver focusTransitionObserver) {
        mContext = context;
        mMainExecutor = shellExecutor;
        mMainHandler = mainHandler;
@@ -368,6 +375,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            }
        };
        mTaskPositionerFactory = taskPositionerFactory;
        mFocusTransitionObserver = focusTransitionObserver;

        shellInit.addInitCallback(this::onInit, this);
    }
@@ -401,6 +409,16 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                        return Unit.INSTANCE;
                    });
        }
        mFocusTransitionObserver.setLocalFocusTransitionListener(this, mMainExecutor);
    }

    @Override
    public void onFocusedTaskChanged(int taskId, boolean isFocusedOnDisplay,
            boolean isFocusedGlobally) {
        final WindowDecoration decor = mWindowDecorByTaskId.get(taskId);
        if (decor != null) {
            decor.relayout(decor.mTaskInfo, isFocusedGlobally);
        }
    }

    @Override
@@ -447,7 +465,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            removeTaskFromEventReceiver(oldTaskInfo.displayId);
            incrementEventReceiverTasks(taskInfo.displayId);
        }
        decoration.relayout(taskInfo);
        decoration.relayout(taskInfo, decoration.mHasGlobalFocus);
        mActivityOrientationChangeHandler.ifPresent(handler ->
                handler.handleActivityOrientationChange(oldTaskInfo, taskInfo));
    }
@@ -486,7 +504,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            createWindowDecoration(taskInfo, taskSurface, startT, finishT);
        } else {
            decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
                    false /* shouldSetTaskPositionAndCrop */);
                    false /* shouldSetTaskPositionAndCrop */,
                    mFocusTransitionObserver.hasGlobalFocus(taskInfo));
        }
    }

@@ -499,7 +518,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        if (decoration == null) return;

        decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
                false /* shouldSetTaskPositionAndCrop */);
                false /* shouldSetTaskPositionAndCrop */,
                mFocusTransitionObserver.hasGlobalFocus(taskInfo));
    }

    @Override
@@ -891,7 +911,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        }

        private void moveTaskToFront(RunningTaskInfo taskInfo) {
            if (!taskInfo.isFocused) {
            if (!mFocusTransitionObserver.hasGlobalFocus(taskInfo)) {
                mDesktopTasksController.moveTaskToFront(taskInfo);
            }
        }
@@ -1512,7 +1532,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        windowDecoration.setExclusionRegionListener(mExclusionRegionListener);
        windowDecoration.setDragPositioningCallback(taskPositioner);
        windowDecoration.relayout(taskInfo, startT, finishT,
                false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */);
                false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */,
                mFocusTransitionObserver.hasGlobalFocus(taskInfo));
        if (!Flags.enableHandleInputFix()) {
            incrementEventReceiverTasks(taskInfo.displayId);
        }
+27 −17
Original line number Diff line number Diff line
@@ -352,7 +352,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    }

    @Override
    void relayout(ActivityManager.RunningTaskInfo taskInfo) {
    void relayout(ActivityManager.RunningTaskInfo taskInfo, boolean hasGlobalFocus) {
        final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
        // The crop and position of the task should only be set when a task is fluid resizing. In
        // all other cases, it is expected that the transition handler positions and crops the task
@@ -365,7 +365,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        // the View). Both will be shown on screen at the same, whereas applying them independently
        // causes flickering. See b/270202228.
        final boolean applyTransactionOnDraw = taskInfo.isFreeform();
        relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskPositionAndCrop);
        relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskPositionAndCrop,
                hasGlobalFocus);
        if (!applyTransactionOnDraw) {
            t.apply();
        }
@@ -373,18 +374,19 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin

    void relayout(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
            boolean hasGlobalFocus) {
        Trace.beginSection("DesktopModeWindowDecoration#relayout");
        if (taskInfo.isFreeform()) {
            // The Task is in Freeform mode -> show its header in sync since it's an integral part
            // of the window itself - a delayed header might cause bad UX.
            relayoutInSync(taskInfo, startT, finishT, applyStartTransactionOnDraw,
                    shouldSetTaskPositionAndCrop);
                    shouldSetTaskPositionAndCrop, hasGlobalFocus);
        } else {
            // The Task is outside Freeform mode -> allow the handle view to be delayed since the
            // handle is just a small addition to the window.
            relayoutWithDelayedViewHost(taskInfo, startT, finishT, applyStartTransactionOnDraw,
                    shouldSetTaskPositionAndCrop);
                    shouldSetTaskPositionAndCrop, hasGlobalFocus);
        }
        Trace.endSection();
    }
@@ -392,11 +394,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    /** Run the whole relayout phase immediately without delay. */
    private void relayoutInSync(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
            boolean hasGlobalFocus) {
        // Clear the current ViewHost runnable as we will update the ViewHost here
        clearCurrentViewHostRunnable();
        updateRelayoutParamsAndSurfaces(taskInfo, startT, finishT, applyStartTransactionOnDraw,
                shouldSetTaskPositionAndCrop);
                shouldSetTaskPositionAndCrop, hasGlobalFocus);
        if (mResult.mRootView != null) {
            updateViewHost(mRelayoutParams, startT, mResult);
        }
@@ -418,7 +421,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
     */
    private void relayoutWithDelayedViewHost(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
            boolean hasGlobalFocus) {
        if (applyStartTransactionOnDraw) {
            throw new IllegalArgumentException(
                    "We cannot both sync viewhost ondraw and delay viewhost creation.");
@@ -426,7 +430,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        // Clear the current ViewHost runnable as we will update the ViewHost here
        clearCurrentViewHostRunnable();
        updateRelayoutParamsAndSurfaces(taskInfo, startT, finishT,
                false /* applyStartTransactionOnDraw */, shouldSetTaskPositionAndCrop);
                false /* applyStartTransactionOnDraw */, shouldSetTaskPositionAndCrop,
                hasGlobalFocus);
        if (mResult.mRootView == null) {
            // This means something blocks the window decor from showing, e.g. the task is hidden.
            // Nothing is set up in this case including the decoration surface.
@@ -440,7 +445,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    @SuppressLint("MissingPermission")
    private void updateRelayoutParamsAndSurfaces(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
            boolean hasGlobalFocus) {
        Trace.beginSection("DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces");

        if (Flags.enableDesktopWindowingAppToWeb()) {
@@ -459,7 +465,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                .isTaskInFullImmersiveState(taskInfo.taskId);
        updateRelayoutParams(mRelayoutParams, mContext, taskInfo, applyStartTransactionOnDraw,
                shouldSetTaskPositionAndCrop, mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded,
                inFullImmersive, mDisplayController.getInsetsState(taskInfo.displayId));
                inFullImmersive, mDisplayController.getInsetsState(taskInfo.displayId),
                hasGlobalFocus);

        final WindowDecorLinearLayout oldRootView = mResult.mRootView;
        final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
@@ -507,12 +514,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            ));
        } else {
            mWindowDecorViewHolder.bindData(new AppHeaderViewHolder.HeaderData(
                    mTaskInfo, TaskInfoKt.getRequestingImmersive(mTaskInfo), inFullImmersive
                    mTaskInfo, TaskInfoKt.getRequestingImmersive(mTaskInfo), inFullImmersive,
                    hasGlobalFocus
            ));
        }
        Trace.endSection();

        if (!mTaskInfo.isFocused) {
        if (!hasGlobalFocus) {
            closeHandleMenu();
            closeManageWindowsMenu();
            closeMaximizeMenu();
@@ -780,7 +788,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            boolean isStatusBarVisible,
            boolean isKeyguardVisibleAndOccluded,
            boolean inFullImmersiveMode,
            @NonNull InsetsState displayInsetsState) {
            @NonNull InsetsState displayInsetsState,
            boolean hasGlobalFocus) {
        final int captionLayoutId = getDesktopModeWindowDecorLayoutId(taskInfo.getWindowingMode());
        final boolean isAppHeader =
                captionLayoutId == R.layout.desktop_mode_app_header;
@@ -790,6 +799,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        relayoutParams.mLayoutResId = captionLayoutId;
        relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
        relayoutParams.mCaptionWidthId = getCaptionWidthId(relayoutParams.mLayoutResId);
        relayoutParams.mHasGlobalFocus = hasGlobalFocus;

        final boolean showCaption;
        if (Flags.enableFullyImmersiveInDesktop()) {
@@ -865,8 +875,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            relayoutParams.mInputFeatures
                    |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
        }
        if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ taskInfo.isFocused)) {
            relayoutParams.mShadowRadiusId = taskInfo.isFocused
        if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ hasGlobalFocus)) {
            relayoutParams.mShadowRadiusId = hasGlobalFocus
                    ? R.dimen.freeform_decor_shadow_focused_thickness
                    : R.dimen.freeform_decor_shadow_unfocused_thickness;
        }
@@ -1408,7 +1418,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    }

    boolean isFocused() {
        return mTaskInfo.isFocused;
        return mHasGlobalFocus;
    }

    /**
Loading