Add caption inset when moving to desktop

When we transition to desktop using the caption handle, the
configuration changes trigger WindowDecoration#relayout to run and a
redraw. WindowDecoration#relayout adds the caption insets source using
another WindowContainerTransaction, but, the insets are sometimes not
added before the redraw occurs and apps do not listen to inset changes
to trigger a redraw, so, the insets are not added until another
configuration change triggers a redraw.

In the long run, we need to have apps listen for inset changes and
redraw accordingly. In the meantime, this change adds the caption insets in the same WCT that applies to changes to transition into desktop mode.

Test: Repeatedly transition into desktop mode using the caption handle
and make sure the caption inset is there (top of app is visible) + run
atest DesktopTasksControllerTest

Change-Id: I16260aa21374fee751f03fe4492f91640179a7ad
This commit is contained in:
Maryam Dehaini
2023-05-30 13:40:46 -07:00
parent 19445b0b21
commit 537a7b6556
5 changed files with 51 additions and 8 deletions

View File

@@ -164,21 +164,28 @@ class DesktopTasksController(
}
/** Move a task with given `taskId` to desktop */
fun moveToDesktop(taskId: Int) {
shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> moveToDesktop(task) }
fun moveToDesktop(taskId: Int, wct: WindowContainerTransaction = WindowContainerTransaction()) {
shellTaskOrganizer.getRunningTaskInfo(taskId)?.let {
task -> moveToDesktop(task, wct)
}
}
/** Move a task to desktop */
fun moveToDesktop(task: RunningTaskInfo) {
/**
* Move a task to desktop
*/
fun moveToDesktop(
task: RunningTaskInfo,
wct: WindowContainerTransaction = WindowContainerTransaction()
) {
KtProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: moveToDesktop taskId=%d",
task.taskId
)
val wct = WindowContainerTransaction()
// Bring other apps to front first
bringDesktopAppsToFront(task.displayId, wct)
addMoveToDesktopChanges(wct, task.token)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */)
} else {

View File

@@ -113,7 +113,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
mRelayoutParams.reset();
mRelayoutParams.mRunningTaskInfo = taskInfo;
mRelayoutParams.mLayoutResId = R.layout.caption_window_decor;
mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height;
mRelayoutParams.mCaptionHeightId = getCaptionHeightId();
mRelayoutParams.mShadowRadiusId = shadowRadiusID;
mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
@@ -221,4 +221,9 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
closeDragResizeListener();
super.close();
}
@Override
int getCaptionHeightId() {
return R.dimen.freeform_decor_caption_height;
}
}

View File

@@ -53,6 +53,7 @@ import android.view.View;
import android.view.WindowManager;
import android.window.TransitionInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -323,7 +324,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
} else if (id == R.id.desktop_button) {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
mDesktopTasksController.ifPresent(c -> c.moveToDesktop(mTaskId));
if (mDesktopTasksController.isPresent()) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
// App sometimes draws before the insets from WindowDecoration#relayout have
// been added, so they must be added here
mWindowDecorByTaskId.get(mTaskId).addCaptionInset(wct);
mDesktopTasksController.get().moveToDesktop(mTaskId, wct);
}
decoration.closeHandleMenu();
} else if (id == R.id.fullscreen_button) {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false));

View File

@@ -178,7 +178,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mRelayoutParams.reset();
mRelayoutParams.mRunningTaskInfo = taskInfo;
mRelayoutParams.mLayoutResId = windowDecorLayoutId;
mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height;
mRelayoutParams.mCaptionHeightId = getCaptionHeightId();
mRelayoutParams.mShadowRadiusId = shadowRadiusID;
mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
@@ -479,6 +479,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
}
}
@Override
int getCaptionHeightId() {
return R.dimen.freeform_decor_caption_height;
}
/**
* Add transition to mTransitionsPausingRelayout
*/

View File

@@ -304,6 +304,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
}
}
int getCaptionHeightId() {
return Resources.ID_NULL;
}
/**
* Obtains the {@link Display} instance for the display ID in {@link #mTaskInfo} if it exists or
* registers {@link #mOnDisplaysChangedListener} if it doesn't.
@@ -418,6 +422,21 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mSurfaceControlTransactionSupplier);
}
/**
* Adds caption inset source to a WCT
*/
public void addCaptionInset(WindowContainerTransaction wct) {
final int captionHeightId = getCaptionHeightId();
if (!ViewRootImpl.CAPTION_ON_SHELL || captionHeightId == Resources.ID_NULL) {
return;
}
final int captionHeight = loadDimensionPixelSize(mContext.getResources(), captionHeightId);
final Rect captionInsets = new Rect(0, 0, 0, captionHeight);
wct.addInsetsSource(mTaskInfo.token, mOwner, 0 /* index */, WindowInsets.Type.captionBar(),
captionInsets);
}
static class RelayoutParams {
RunningTaskInfo mRunningTaskInfo;
int mLayoutResId;