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

Commit f310ef21 authored by Jainam Shah's avatar Jainam Shah Committed by Android (Google) Code Review
Browse files

Merge "Fix caption bar inset sync issue" into main

parents 726a703c 7280cfcf
Loading
Loading
Loading
Loading
+35 −3
Original line number Diff line number Diff line
@@ -16,13 +16,17 @@
package com.android.wm.shell.windowdecor;

import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
import android.content.Context;
import android.hardware.input.InputManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
import android.view.InputDevice;
import android.view.InsetsState;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.SurfaceControl;
@@ -33,6 +37,7 @@ import android.window.WindowContainerTransaction;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
@@ -49,7 +54,8 @@ import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSuppl
 * Works with decorations that extend {@link CarWindowDecoration}.
 */
public abstract class CarWindowDecorViewModel
        implements WindowDecorViewModel, FocusTransitionListener {
        implements WindowDecorViewModel, FocusTransitionListener,
        DisplayInsetsController.OnInsetsChangedListener {
    private static final String TAG = "CarWindowDecorViewModel";

    private final ShellTaskOrganizer mTaskOrganizer;
@@ -57,31 +63,37 @@ public abstract class CarWindowDecorViewModel
    private final @ShellBackgroundThread ShellExecutor mBgExecutor;
    private final ShellExecutor mMainExecutor;
    private final DisplayController mDisplayController;
    private final DisplayInsetsController mDisplayInsetsController;
    private final FocusTransitionObserver mFocusTransitionObserver;
    private final SyncTransactionQueue mSyncQueue;
    private final SparseArray<CarWindowDecoration> mWindowDecorByTaskId = new SparseArray<>();
    private final WindowDecorViewHostSupplier<WindowDecorViewHost> mWindowDecorViewHostSupplier;
    private final IActivityTaskManager mActivityTaskManager;

    public CarWindowDecorViewModel(
            Context context,
            @ShellMainThread ShellExecutor mainExecutor,
            @ShellBackgroundThread ShellExecutor bgExecutor,
            @ShellMainThread ShellExecutor shellExecutor,
            ShellInit shellInit,
            ShellTaskOrganizer taskOrganizer,
            DisplayController displayController,
            DisplayInsetsController displayInsetsController,
            SyncTransactionQueue syncQueue,
            FocusTransitionObserver focusTransitionObserver,
            WindowDecorViewHostSupplier<WindowDecorViewHost> windowDecorViewHostSupplier) {
        mContext = context;
        mMainExecutor = shellExecutor;
        mMainExecutor = mainExecutor;
        mBgExecutor = bgExecutor;
        mTaskOrganizer = taskOrganizer;
        mDisplayController = displayController;
        mDisplayInsetsController = displayInsetsController;
        mFocusTransitionObserver = focusTransitionObserver;
        mSyncQueue = syncQueue;
        mWindowDecorViewHostSupplier = windowDecorViewHostSupplier;
        mActivityTaskManager = ActivityTaskManager.getService();

        shellInit.addInitCallback(this::onInit, this);
        displayInsetsController.addGlobalInsetsChangedListener(this);
    }

    private void onInit() {
@@ -187,6 +199,26 @@ public abstract class CarWindowDecorViewModel
        decoration.close();
    }

    @Override
    public void insetsChanged(int displayId, InsetsState insetsState) {
        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        try {
            mActivityTaskManager.getTasks(/* maxNum= */ Integer.MAX_VALUE,
                            /* filterOnlyVisibleRecents= */ false, /* keepIntentExtra= */ false,
                            displayId)
                    .stream().filter(taskInfo -> taskInfo.isVisible && taskInfo.isRunning)
                    .forEach(taskInfo -> {
                        final CarWindowDecoration decoration = mWindowDecorByTaskId.get(
                                taskInfo.taskId);
                        if (decoration != null) {
                            decoration.relayout(taskInfo, t, t);
                        }
                    });
        } catch (RemoteException e) {
            Log.e(TAG, "Cannot update decoration on inset change on displayId: " + displayId);
        }
    }

    /**
     * @return {@code true} if the task/activity associated with {@code taskInfo} should show
     * window decoration.
+14 −14
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.view.WindowInsets;
import android.window.WindowContainerTransaction;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -47,6 +46,7 @@ public class CarWindowDecoration extends WindowDecoration<WindowDecorLinearLayou
    private WindowDecorLinearLayout mRootView;
    private @ShellBackgroundThread final ShellExecutor mBgExecutor;
    private final View.OnClickListener mClickListener;
    private final RelayoutParams mRelayoutParams = new RelayoutParams();
    private final RelayoutResult<WindowDecorLinearLayout> mResult = new RelayoutResult<>();

    CarWindowDecoration(
@@ -75,7 +75,8 @@ public class CarWindowDecoration extends WindowDecoration<WindowDecorLinearLayou
    @SuppressLint("MissingPermission")
    void relayout(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT) {
        relayout(taskInfo, startT, finishT, /* isCaptionVisible= */ true);
        relayout(taskInfo, startT, finishT,
                /* isCaptionVisible= */ mRelayoutParams.mIsCaptionVisible);
    }

    @SuppressLint("MissingPermission")
@@ -84,12 +85,9 @@ public class CarWindowDecoration extends WindowDecoration<WindowDecorLinearLayou
            boolean isCaptionVisible) {
        final WindowContainerTransaction wct = new WindowContainerTransaction();

        RelayoutParams relayoutParams = new RelayoutParams();
        updateRelayoutParams(mRelayoutParams, taskInfo, isCaptionVisible);

        updateRelayoutParams(relayoutParams, taskInfo,
                mDisplayController.getInsetsState(taskInfo.displayId), isCaptionVisible);

        relayout(relayoutParams, startT, finishT, wct, mRootView, mResult);
        relayout(mRelayoutParams, startT, finishT, wct, mRootView, mResult);
        // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
        mBgExecutor.execute(() -> mTaskOrganizer.applyTransaction(wct));

@@ -118,7 +116,6 @@ public class CarWindowDecoration extends WindowDecoration<WindowDecorLinearLayou
    private void updateRelayoutParams(
            RelayoutParams relayoutParams,
            ActivityManager.RunningTaskInfo taskInfo,
            @Nullable InsetsState displayInsetsState,
            boolean isCaptionVisible) {
        relayoutParams.reset();
        relayoutParams.mRunningTaskInfo = taskInfo;
@@ -127,16 +124,19 @@ public class CarWindowDecoration extends WindowDecoration<WindowDecorLinearLayou
        relayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height;
        relayoutParams.mIsCaptionVisible =
                isCaptionVisible && mIsStatusBarVisible && !mIsKeyguardVisibleAndOccluded;
        if (displayInsetsState != null) {
            relayoutParams.mCaptionTopPadding = getTopPadding(
                    taskInfo.getConfiguration().windowConfiguration.getBounds(),
                    displayInsetsState);
        }
        relayoutParams.mCaptionTopPadding = getTopPadding(taskInfo, relayoutParams);

        relayoutParams.mInsetSourceFlags |= FLAG_FORCE_CONSUMING_OPAQUE_CAPTION_BAR;
        relayoutParams.mApplyStartTransactionOnDraw = true;
    }

    private static int getTopPadding(Rect taskBounds, @NonNull InsetsState insetsState) {
    private int getTopPadding(ActivityManager.RunningTaskInfo taskInfo,
            RelayoutParams relayoutParams) {
        Rect taskBounds = taskInfo.getConfiguration().windowConfiguration.getBounds();
        InsetsState insetsState = mDisplayController.getInsetsState(taskInfo.displayId);
        if (insetsState == null) {
            return relayoutParams.mCaptionTopPadding;
        }
        Insets systemDecor = insetsState.calculateInsets(taskBounds,
                WindowInsets.Type.systemBars() & ~WindowInsets.Type.captionBar(),
                false /* ignoreVisibility */);