Adds a method to TaskView to allow clients to set caption insets
Some users of TaskView (bubbles) need to be able to add a caption
bar to TaskView to allow users to manipulate the bubble window or
access a menu.
This CL exposes a method on TaskView to set a rect that represents
the insets for that caption bar. This rect is automatically excluded
as a touchable area so that TaskView doesn't steal touches from it.
Test: manual - locally use new setCaptionInsets method on a TaskView
=> observe that content is inset & touchable
Test: atest TaskViewTest
Bug: 284205099
Change-Id: Ia71f56920bb85b6e0e7164c92273caf4d480916a
This commit is contained in:
@@ -26,6 +26,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.view.SurfaceControl;
|
||||
@@ -69,8 +70,10 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
private final Rect mTmpRect = new Rect();
|
||||
private final Rect mTmpRootRect = new Rect();
|
||||
private final int[] mTmpLocation = new int[2];
|
||||
private final Rect mBoundsOnScreen = new Rect();
|
||||
private final TaskViewTaskController mTaskViewTaskController;
|
||||
private Region mObscuredTouchRegion;
|
||||
private Insets mCaptionInsets;
|
||||
|
||||
public TaskView(Context context, TaskViewTaskController taskViewTaskController) {
|
||||
super(context, null, 0, 0, true /* disableBackgroundLayer */);
|
||||
@@ -168,6 +171,25 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
mObscuredTouchRegion = obscuredRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a region of the task to inset to allow for a caption bar. Currently only top insets
|
||||
* are supported.
|
||||
* <p>
|
||||
* This region will be factored in as an area of taskview that is not touchable activity
|
||||
* content (i.e. you don't need to additionally set {@link #setObscuredTouchRect(Rect)} for
|
||||
* the caption area).
|
||||
*
|
||||
* @param captionInsets the insets to apply to task view.
|
||||
*/
|
||||
public void setCaptionInsets(Insets captionInsets) {
|
||||
mCaptionInsets = captionInsets;
|
||||
if (captionInsets == null) {
|
||||
// If captions are null we can set them now; otherwise they'll get set in
|
||||
// onComputeInternalInsets.
|
||||
mTaskViewTaskController.setCaptionInsets(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when view position or size has changed. Do not call when animating.
|
||||
*/
|
||||
@@ -230,6 +252,15 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
getLocationInWindow(mTmpLocation);
|
||||
mTmpRect.set(mTmpLocation[0], mTmpLocation[1],
|
||||
mTmpLocation[0] + getWidth(), mTmpLocation[1] + getHeight());
|
||||
if (mCaptionInsets != null) {
|
||||
mTmpRect.inset(mCaptionInsets);
|
||||
getBoundsOnScreen(mBoundsOnScreen);
|
||||
mTaskViewTaskController.setCaptionInsets(new Rect(
|
||||
mBoundsOnScreen.left,
|
||||
mBoundsOnScreen.top,
|
||||
mBoundsOnScreen.right + getWidth(),
|
||||
mBoundsOnScreen.top + mCaptionInsets.top));
|
||||
}
|
||||
inoutInfo.touchableRegion.op(mTmpRect, Region.Op.DIFFERENCE);
|
||||
|
||||
if (mObscuredTouchRegion != null) {
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.os.Binder;
|
||||
import android.util.CloseGuard;
|
||||
import android.util.Slog;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowInsets;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.window.WindowContainerTransaction;
|
||||
|
||||
@@ -82,6 +83,10 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
|
||||
private TaskView.Listener mListener;
|
||||
private Executor mListenerExecutor;
|
||||
|
||||
/** Used to inset the activity content to allow space for a caption bar. */
|
||||
private final Binder mCaptionInsetsOwner = new Binder();
|
||||
private Rect mCaptionInsets;
|
||||
|
||||
public TaskViewTaskController(Context context, ShellTaskOrganizer organizer,
|
||||
TaskViewTransitions taskViewTransitions, SyncTransactionQueue syncQueue) {
|
||||
mContext = context;
|
||||
@@ -436,6 +441,32 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
|
||||
mTaskViewTransitions.closeTaskView(wct, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a region of the task to inset to allow for a caption bar.
|
||||
*
|
||||
* @param captionInsets the rect for the insets in screen coordinates.
|
||||
*/
|
||||
void setCaptionInsets(Rect captionInsets) {
|
||||
if (mCaptionInsets != null && mCaptionInsets.equals(captionInsets)) {
|
||||
return;
|
||||
}
|
||||
mCaptionInsets = captionInsets;
|
||||
applyCaptionInsetsIfNeeded();
|
||||
}
|
||||
|
||||
void applyCaptionInsetsIfNeeded() {
|
||||
if (mTaskToken == null) return;
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
if (mCaptionInsets != null) {
|
||||
wct.addInsetsSource(mTaskToken, mCaptionInsetsOwner, 0,
|
||||
WindowInsets.Type.captionBar(), mCaptionInsets);
|
||||
} else {
|
||||
wct.removeInsetsSource(mTaskToken, mCaptionInsetsOwner, 0,
|
||||
WindowInsets.Type.captionBar());
|
||||
}
|
||||
mTaskOrganizer.applyTransaction(wct);
|
||||
}
|
||||
|
||||
/** Should be called when the client surface is destroyed. */
|
||||
public void surfaceDestroyed() {
|
||||
mSurfaceCreated = false;
|
||||
@@ -564,6 +595,7 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
|
||||
mTaskViewTransitions.updateBoundsState(this, boundsOnScreen);
|
||||
mTaskViewTransitions.updateVisibilityState(this, true /* visible */);
|
||||
wct.setBounds(mTaskToken, boundsOnScreen);
|
||||
applyCaptionInsetsIfNeeded();
|
||||
} else {
|
||||
// The surface has already been destroyed before the task has appeared,
|
||||
// so go ahead and hide the task entirely
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.app.ActivityManager;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
@@ -563,4 +564,47 @@ public class TaskViewTest extends ShellTestCase {
|
||||
mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash);
|
||||
verify(mTaskViewTaskController, never()).cleanUpPendingTask();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCaptionInsets_noTaskInitially() {
|
||||
assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
|
||||
|
||||
Rect insets = new Rect(0, 400, 0, 0);
|
||||
mTaskView.setCaptionInsets(Insets.of(insets));
|
||||
mTaskView.onComputeInternalInsets(new ViewTreeObserver.InternalInsetsInfo());
|
||||
|
||||
verify(mTaskViewTaskController).applyCaptionInsetsIfNeeded();
|
||||
verify(mOrganizer, never()).applyTransaction(any());
|
||||
|
||||
mTaskView.surfaceCreated(mock(SurfaceHolder.class));
|
||||
reset(mOrganizer);
|
||||
reset(mTaskViewTaskController);
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
mTaskViewTaskController.prepareOpenAnimation(true /* newTask */,
|
||||
new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo,
|
||||
mLeash, wct);
|
||||
mTaskView.onComputeInternalInsets(new ViewTreeObserver.InternalInsetsInfo());
|
||||
|
||||
verify(mTaskViewTaskController).applyCaptionInsetsIfNeeded();
|
||||
verify(mOrganizer).applyTransaction(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCaptionInsets_withTask() {
|
||||
assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
|
||||
|
||||
mTaskView.surfaceCreated(mock(SurfaceHolder.class));
|
||||
WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
mTaskViewTaskController.prepareOpenAnimation(true /* newTask */,
|
||||
new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo,
|
||||
mLeash, wct);
|
||||
reset(mTaskViewTaskController);
|
||||
reset(mOrganizer);
|
||||
|
||||
Rect insets = new Rect(0, 400, 0, 0);
|
||||
mTaskView.setCaptionInsets(Insets.of(insets));
|
||||
mTaskView.onComputeInternalInsets(new ViewTreeObserver.InternalInsetsInfo());
|
||||
verify(mTaskViewTaskController).applyCaptionInsetsIfNeeded();
|
||||
verify(mOrganizer).applyTransaction(any());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user