Merge "Add the IME insets to virtual display for bubble" into rvc-dev am: 75c82108f6
Change-Id: Ic4d3d31a5e332ca31cf85d0da380da9f19961810
This commit is contained in:
@@ -29,6 +29,7 @@ import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.hardware.display.VirtualDisplay;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.AttributeSet;
|
||||
@@ -443,6 +444,14 @@ public class ActivityView extends ViewGroup implements android.window.TaskEmbedd
|
||||
return mTaskEmbedder.getDisplayId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return virtual display.
|
||||
*/
|
||||
public VirtualDisplay getVirtualDisplay() {
|
||||
return mTaskEmbedder.getVirtualDisplay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects a pair of down/up key events with keycode {@link KeyEvent#KEYCODE_BACK} to the
|
||||
* virtual display.
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.ActivityView;
|
||||
import android.app.IActivityTaskManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentName;
|
||||
@@ -36,9 +35,8 @@ import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.os.RemoteException;
|
||||
import android.hardware.display.VirtualDisplay;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.IWindow;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.KeyEvent;
|
||||
@@ -256,6 +254,10 @@ public abstract class TaskEmbedder {
|
||||
return INVALID_DISPLAY;
|
||||
}
|
||||
|
||||
public VirtualDisplay getVirtualDisplay() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set forwarded insets on the task content.
|
||||
*
|
||||
|
||||
@@ -251,6 +251,14 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
|
||||
return INVALID_DISPLAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualDisplay getVirtualDisplay() {
|
||||
if (isInitialized()) {
|
||||
return mVirtualDisplay;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if container is ready to launch and create {@link ActivityOptions} to target the
|
||||
* virtual display.
|
||||
|
||||
@@ -19,9 +19,15 @@ package com.android.systemui.bubbles;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
|
||||
import static android.graphics.PixelFormat.TRANSPARENT;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
import static android.view.InsetsState.ITYPE_IME;
|
||||
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
|
||||
import static android.view.ViewRootImpl.sNewInsetsMode;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
|
||||
|
||||
import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPANDED_VIEW;
|
||||
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
|
||||
@@ -42,9 +48,12 @@ import android.graphics.Insets;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.hardware.display.VirtualDisplay;
|
||||
import android.os.Binder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
@@ -62,6 +71,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
*/
|
||||
public class BubbleExpandedView extends LinearLayout {
|
||||
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleExpandedView" : TAG_BUBBLES;
|
||||
private static final String WINDOW_TITLE = "ImeInsetsWindowWithoutContent";
|
||||
|
||||
private enum ActivityViewStatus {
|
||||
// ActivityView is being initialized, cannot start an activity yet.
|
||||
@@ -107,6 +117,9 @@ public class BubbleExpandedView extends LinearLayout {
|
||||
private WindowManager mWindowManager;
|
||||
|
||||
private BubbleStackView mStackView;
|
||||
private View mVirtualImeView;
|
||||
private WindowManager mVirtualDisplayWindowManager;
|
||||
private boolean mImeShowing = false;
|
||||
|
||||
private ActivityView.StateCallback mStateCallback = new ActivityView.StateCallback() {
|
||||
@Override
|
||||
@@ -317,11 +330,8 @@ public class BubbleExpandedView extends LinearLayout {
|
||||
mKeyboardVisible = false;
|
||||
mNeedsNewHeight = false;
|
||||
if (mActivityView != null) {
|
||||
// TODO: Temporary hack to offset the view until we can properly inset Bubbles again.
|
||||
if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
|
||||
mStackView.animate()
|
||||
.setDuration(100)
|
||||
.translationY(0);
|
||||
setImeWindowToDisplay(0, 0);
|
||||
} else {
|
||||
mActivityView.setForwardedInsets(Insets.of(0, 0, 0, 0));
|
||||
}
|
||||
@@ -365,18 +375,61 @@ public class BubbleExpandedView extends LinearLayout {
|
||||
: 0);
|
||||
final int insetsBottom = Math.max(activityViewBottom - keyboardTop, 0);
|
||||
|
||||
// TODO: Temporary hack to offset the view until we can properly inset Bubbles again.
|
||||
if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
|
||||
mStackView.animate()
|
||||
.setDuration(100)
|
||||
.translationY(-insetsBottom)
|
||||
.withEndAction(() -> mActivityView.onLocationChanged());
|
||||
setImeWindowToDisplay(getWidth(), insetsBottom);
|
||||
} else {
|
||||
mActivityView.setForwardedInsets(Insets.of(0, 0, 0, insetsBottom));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setImeWindowToDisplay(int w, int h) {
|
||||
if (getVirtualDisplayId() == INVALID_DISPLAY) {
|
||||
return;
|
||||
}
|
||||
if (h == 0 || w == 0) {
|
||||
if (mImeShowing) {
|
||||
mVirtualImeView.setVisibility(GONE);
|
||||
mImeShowing = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
final Context virtualDisplayContext = mContext.createDisplayContext(
|
||||
getVirtualDisplay().getDisplay());
|
||||
|
||||
if (mVirtualDisplayWindowManager == null) {
|
||||
mVirtualDisplayWindowManager =
|
||||
(WindowManager) virtualDisplayContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
}
|
||||
if (mVirtualImeView == null) {
|
||||
mVirtualImeView = new View(virtualDisplayContext);
|
||||
mVirtualImeView.setVisibility(VISIBLE);
|
||||
mVirtualDisplayWindowManager.addView(mVirtualImeView,
|
||||
getVirtualImeViewAttrs(w, h));
|
||||
} else {
|
||||
mVirtualDisplayWindowManager.updateViewLayout(mVirtualImeView,
|
||||
getVirtualImeViewAttrs(w, h));
|
||||
mVirtualImeView.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
mImeShowing = true;
|
||||
}
|
||||
|
||||
private WindowManager.LayoutParams getVirtualImeViewAttrs(int w, int h) {
|
||||
// To use TYPE_NAVIGATION_BAR_PANEL instead of TYPE_IME_BAR to bypass the IME window type
|
||||
// token check when adding the window.
|
||||
final WindowManager.LayoutParams attrs =
|
||||
new WindowManager.LayoutParams(w, h, TYPE_NAVIGATION_BAR_PANEL,
|
||||
FLAG_LAYOUT_NO_LIMITS | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE,
|
||||
TRANSPARENT);
|
||||
attrs.gravity = Gravity.BOTTOM;
|
||||
attrs.setTitle(WINDOW_TITLE);
|
||||
attrs.token = new Binder();
|
||||
attrs.providesInsetsTypes = new int[]{ITYPE_IME};
|
||||
attrs.alpha = 0.0f;
|
||||
return attrs;
|
||||
}
|
||||
|
||||
void setStackView(BubbleStackView stackView) {
|
||||
mStackView = stackView;
|
||||
}
|
||||
@@ -570,4 +623,11 @@ public class BubbleExpandedView extends LinearLayout {
|
||||
}
|
||||
return INVALID_DISPLAY;
|
||||
}
|
||||
|
||||
private VirtualDisplay getVirtualDisplay() {
|
||||
if (usingActivityView()) {
|
||||
return mActivityView.getVirtualDisplay();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5640,6 +5640,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
Slog.w(TAG, "Failed to deliver showInsets", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClientControlled() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,4 +61,12 @@ interface InsetsControlTarget {
|
||||
default boolean canShowTransient() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the object controlling the insets is on client.
|
||||
*/
|
||||
default boolean isClientControlled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import android.view.InsetsState;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceControl.Transaction;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.function.TriConsumer;
|
||||
import com.android.server.wm.SurfaceAnimator.AnimationType;
|
||||
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
|
||||
@@ -288,6 +289,7 @@ class InsetsSourceProvider {
|
||||
t.deferTransactionUntil(leash, barrier, frameNumber);
|
||||
}
|
||||
mControlTarget = target;
|
||||
updateVisibility();
|
||||
mControl = new InsetsSourceControl(mSource.getType(), leash,
|
||||
new Point(mWin.getWindowFrames().mFrame.left, mWin.getWindowFrames().mFrame.top));
|
||||
}
|
||||
@@ -330,13 +332,16 @@ class InsetsSourceProvider {
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
private void setServerVisible(boolean serverVisible) {
|
||||
@VisibleForTesting
|
||||
void setServerVisible(boolean serverVisible) {
|
||||
mServerVisible = serverVisible;
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
private void updateVisibility() {
|
||||
mSource.setVisible(mServerVisible && mClientVisible);
|
||||
final boolean isClientControlled = mControlTarget != null
|
||||
&& mControlTarget.isClientControlled();
|
||||
mSource.setVisible(mServerVisible && (!isClientControlled || mClientVisible));
|
||||
}
|
||||
|
||||
InsetsSourceControl getControl(InsetsControlTarget target) {
|
||||
@@ -408,10 +413,10 @@ class InsetsSourceProvider {
|
||||
public void onAnimationCancelled(SurfaceControl animationLeash) {
|
||||
if (mAdapter == this) {
|
||||
mStateController.notifyControlRevoked(mControlTarget, InsetsSourceProvider.this);
|
||||
setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
|
||||
mControl = null;
|
||||
mControlTarget = null;
|
||||
mAdapter = null;
|
||||
setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
|
||||
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(false);
|
||||
addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
|
||||
.getControllableInsetProvider().getSource().setVisible(true);
|
||||
.getControllableInsetProvider().setServerVisible(true);
|
||||
|
||||
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
|
||||
doNothing().when(policy).startAnimation(anyBoolean(), any(), any());
|
||||
|
||||
Reference in New Issue
Block a user