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

Commit b83940c9 authored by Yunfan Chen's avatar Yunfan Chen
Browse files

Add the IME insets to virtual display for bubble

This patch will add a fake IME window to virtual display when IME is
showing and covering a bubble window. Without the fake window, the
bubble will not receive the correct IME insets.

To do that, this patch:
1. Added an interface in ActivityView to get VirtualDisplay when needed,
   in order to create the display context.
2. Modify the visibility update. When the target is not a client
   controlled target, we ignore the client visibility. We also call
   visibility update when the control target updated.
3. With the modified infra, add the window with correct param and
   context.

Bug: 150780413
Test: atest WmTests:DisplayPolicyLayoutTests
Test: atest InsetsStateTest
Test: atest InsetsPolicyTest
Test: go/wm-smoke
Test: See reproduce steps in the bug

Change-Id: I52691b5c7f81261de580bb4fc762e88486e78141
parent cf9ab7aa
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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.
+5 −3
Original line number Diff line number Diff line
@@ -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.
     *
+8 −0
Original line number Diff line number Diff line
@@ -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.
+69 −9
Original line number Diff line number Diff line
@@ -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
@@ -316,11 +329,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));
            }
@@ -364,18 +374,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;
    }
@@ -569,4 +622,11 @@ public class BubbleExpandedView extends LinearLayout {
        }
        return INVALID_DISPLAY;
    }

    private VirtualDisplay getVirtualDisplay() {
        if (usingActivityView()) {
            return mActivityView.getVirtualDisplay();
        }
        return null;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -5538,6 +5538,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                Slog.w(TAG, "Failed to deliver showInsets", e);
            }
        }

        @Override
        public boolean isClientControlled() {
            return false;
        }
    }

    /**
Loading