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

Commit 3ea9673b authored by Jerry Chang's avatar Jerry Chang Committed by Android (Google) Code Review
Browse files

Merge "Make stage split divider non-interactive while showing IME" into sc-dev

parents 0b905b1e d3310973
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import androidx.annotation.Nullable;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.split.SplitLayout;

@@ -57,12 +58,14 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan
    private final AppPairsController mController;
    private final SyncTransactionQueue mSyncQueue;
    private final DisplayController mDisplayController;
    private final DisplayImeController mDisplayImeController;
    private SplitLayout mSplitLayout;

    AppPair(AppPairsController controller) {
        mController = controller;
        mSyncQueue = controller.getSyncTransactionQueue();
        mDisplayController = controller.getDisplayController();
        mDisplayImeController = controller.getDisplayImeController();
    }

    int getRootTaskId() {
@@ -97,7 +100,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan
        mSplitLayout = new SplitLayout(TAG + "SplitDivider",
                mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
                mRootTaskInfo.configuration, this /* layoutChangeListener */,
                b -> b.setParent(mRootTaskLeash));
                b -> b.setParent(mRootTaskLeash), mDisplayImeController);

        final WindowContainerToken token1 = task1.token;
        final WindowContainerToken token2 = task2.token;
+12 −6
Original line number Diff line number Diff line
@@ -23,17 +23,16 @@ import android.util.Slog;
import android.util.SparseArray;

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

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;

import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

/**
 * Class manages app-pairs multitasking mode and implements the main interface {@link AppPairs}.
@@ -50,12 +49,15 @@ public class AppPairsController {
    // Active app-pairs mapped by root task id key.
    private final SparseArray<AppPair> mActiveAppPairs = new SparseArray<>();
    private final DisplayController mDisplayController;
    private final DisplayImeController mDisplayImeController;

    public AppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
                DisplayController displayController, ShellExecutor mainExecutor) {
            DisplayController displayController, ShellExecutor mainExecutor,
            DisplayImeController displayImeController) {
        mTaskOrganizer = organizer;
        mSyncQueue = syncQueue;
        mDisplayController = displayController;
        mDisplayImeController = displayImeController;
        mMainExecutor = mainExecutor;
    }

@@ -130,18 +132,22 @@ public class AppPairsController {
        }
    }

    public ShellTaskOrganizer getTaskOrganizer() {
    ShellTaskOrganizer getTaskOrganizer() {
        return mTaskOrganizer;
    }

    public SyncTransactionQueue getSyncTransactionQueue() {
    SyncTransactionQueue getSyncTransactionQueue() {
        return mSyncQueue;
    }

    public DisplayController getDisplayController() {
    DisplayController getDisplayController() {
        return mDisplayController;
    }

    DisplayImeController getDisplayImeController() {
        return mDisplayImeController;
    }

    public void dump(@NonNull PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
        final String childPrefix = innerPrefix + "  ";
+20 −3
Original line number Diff line number Diff line
@@ -36,11 +36,13 @@ import androidx.annotation.Nullable;
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.DisplayImeController;

/**
 * Stack divider for app pair.
 * Divider for multi window splits.
 */
public class DividerView extends FrameLayout implements View.OnTouchListener {
public class DividerView extends FrameLayout implements View.OnTouchListener,
        DisplayImeController.ImePositionProcessor {
    public static final long TOUCH_ANIMATION_DURATION = 150;
    public static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;

@@ -56,6 +58,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
    private boolean mMoving;
    private int mStartPos;
    private GestureDetector mDoubleTapDetector;
    private boolean mInteractive;

    public DividerView(@NonNull Context context) {
        super(context);
@@ -91,12 +94,19 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
        mTouchElevation = getResources().getDimensionPixelSize(
                R.dimen.docked_stack_divider_lift_elevation);
        mDoubleTapDetector = new GestureDetector(getContext(), new DoubleTapListener());
        mInteractive = true;
        setOnTouchListener(this);
    }

    @Override
    public void onImeVisibilityChanged(int displayId, boolean isShowing) {
        if (displayId != getDisplay().getDisplayId()) return;
        setInteractive(!isShowing);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (mSplitLayout == null) {
        if (mSplitLayout == null || !mInteractive) {
            return false;
        }

@@ -202,6 +212,13 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
        mViewHost.relayout(lp);
    }

    private void setInteractive(boolean interactive) {
        if (interactive == mInteractive) return;
        mInteractive = interactive;
        releaseTouching();
        mHandle.setVisibility(mInteractive ? View.VISIBLE : View.INVISIBLE);
    }

    private boolean isLandscape() {
        return getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE;
    }
+5 −2
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import androidx.annotation.Nullable;

import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.DisplayImeController;

/**
 * Records and handles layout of splits. Helps to calculate proper bounds when configuration or
@@ -59,11 +60,13 @@ public class SplitLayout {

    public SplitLayout(String windowName, Context context, Configuration configuration,
            LayoutChangeListener layoutChangeListener,
            SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks) {
            SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks,
            DisplayImeController displayImeController) {
        mContext = context.createConfigurationContext(configuration);
        mLayoutChangeListener = layoutChangeListener;
        mSplitWindowManager = new SplitWindowManager(
                windowName, mContext, configuration, parentContainerCallbacks);
                windowName, mContext, configuration, parentContainerCallbacks,
                displayImeController);

        mDividerWindowWidth = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.docked_stack_divider_thickness);
+21 −8
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.view.WindowlessWindowManager;
import androidx.annotation.Nullable;

import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayImeController;

/**
 * Holds view hierarchy of a root surface and helps to inflate {@link DividerView} for a split.
@@ -53,23 +54,27 @@ import com.android.wm.shell.R;
public final class SplitWindowManager extends WindowlessWindowManager {
    private static final String TAG = SplitWindowManager.class.getSimpleName();

    private final String mWindowName;
    private final DisplayImeController mDisplayImeController;
    private final ParentContainerCallbacks mParentContainerCallbacks;
    private Context mContext;
    private SurfaceControlViewHost mViewHost;
    private SurfaceControl mLeash;
    private boolean mResizingSplits;
    private final String mWindowName;
    private DividerView mDividerView;

    public interface ParentContainerCallbacks {
        void attachToParentSurface(SurfaceControl.Builder b);
    }

    public SplitWindowManager(String windowName, Context context, Configuration config,
            ParentContainerCallbacks parentContainerCallbacks) {
            ParentContainerCallbacks parentContainerCallbacks,
            DisplayImeController displayImeController) {
        super(config, null /* rootSurface */, null /* hostInputToken */);
        mContext = context.createConfigurationContext(config);
        mParentContainerCallbacks = parentContainerCallbacks;
        mWindowName = windowName;
        mDisplayImeController = displayImeController;
    }

    @Override
@@ -103,14 +108,16 @@ public final class SplitWindowManager extends WindowlessWindowManager {

    /** Inflates {@link DividerView} on to the root surface. */
    void init(SplitLayout splitLayout) {
        if (mViewHost == null) {
            mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
        if (mDividerView != null || mViewHost != null) {
            throw new UnsupportedOperationException(
                    "Try to inflate divider view again without release first");
        }

        final Rect dividerBounds = splitLayout.getDividerBounds();
        final DividerView dividerView = (DividerView) LayoutInflater.from(mContext)
        mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
        mDividerView = (DividerView) LayoutInflater.from(mContext)
                .inflate(R.layout.split_divider, null /* root */);

        final Rect dividerBounds = splitLayout.getDividerBounds();
        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                dividerBounds.width(), dividerBounds.height(), TYPE_DOCK_DIVIDER,
                FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_WATCH_OUTSIDE_TOUCH
@@ -119,8 +126,9 @@ public final class SplitWindowManager extends WindowlessWindowManager {
        lp.token = new Binder();
        lp.setTitle(mWindowName);
        lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
        mViewHost.setView(dividerView, lp);
        dividerView.setup(splitLayout, mViewHost);
        mViewHost.setView(mDividerView, lp);
        mDividerView.setup(splitLayout, mViewHost);
        mDisplayImeController.addPositionProcessor(mDividerView);
    }

    /**
@@ -128,6 +136,11 @@ public final class SplitWindowManager extends WindowlessWindowManager {
     * hierarchy.
     */
    void release() {
        if (mDividerView != null) {
            mDisplayImeController.removePositionProcessor(mDividerView);
            mDividerView = null;
        }

        if (mViewHost != null){
            mViewHost.release();
            mViewHost = null;
Loading