Merge "Make stage split divider non-interactive while showing IME" into sc-dev am: 3ea9673b74
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13628027 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I510097cc5a9f4a562eaa9d5b7d2364f727a87d97
This commit is contained in:
@@ -34,6 +34,7 @@ import androidx.annotation.Nullable;
|
|||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
import com.android.wm.shell.common.DisplayController;
|
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.SyncTransactionQueue;
|
||||||
import com.android.wm.shell.common.split.SplitLayout;
|
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 AppPairsController mController;
|
||||||
private final SyncTransactionQueue mSyncQueue;
|
private final SyncTransactionQueue mSyncQueue;
|
||||||
private final DisplayController mDisplayController;
|
private final DisplayController mDisplayController;
|
||||||
|
private final DisplayImeController mDisplayImeController;
|
||||||
private SplitLayout mSplitLayout;
|
private SplitLayout mSplitLayout;
|
||||||
|
|
||||||
AppPair(AppPairsController controller) {
|
AppPair(AppPairsController controller) {
|
||||||
mController = controller;
|
mController = controller;
|
||||||
mSyncQueue = controller.getSyncTransactionQueue();
|
mSyncQueue = controller.getSyncTransactionQueue();
|
||||||
mDisplayController = controller.getDisplayController();
|
mDisplayController = controller.getDisplayController();
|
||||||
|
mDisplayImeController = controller.getDisplayImeController();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getRootTaskId() {
|
int getRootTaskId() {
|
||||||
@@ -97,7 +100,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan
|
|||||||
mSplitLayout = new SplitLayout(TAG + "SplitDivider",
|
mSplitLayout = new SplitLayout(TAG + "SplitDivider",
|
||||||
mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
|
mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
|
||||||
mRootTaskInfo.configuration, this /* layoutChangeListener */,
|
mRootTaskInfo.configuration, this /* layoutChangeListener */,
|
||||||
b -> b.setParent(mRootTaskLeash));
|
b -> b.setParent(mRootTaskLeash), mDisplayImeController);
|
||||||
|
|
||||||
final WindowContainerToken token1 = task1.token;
|
final WindowContainerToken token1 = task1.token;
|
||||||
final WindowContainerToken token2 = task2.token;
|
final WindowContainerToken token2 = task2.token;
|
||||||
|
|||||||
@@ -23,17 +23,16 @@ import android.util.Slog;
|
|||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
import com.android.wm.shell.common.DisplayController;
|
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.ShellExecutor;
|
||||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class manages app-pairs multitasking mode and implements the main interface {@link AppPairs}.
|
* 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.
|
// Active app-pairs mapped by root task id key.
|
||||||
private final SparseArray<AppPair> mActiveAppPairs = new SparseArray<>();
|
private final SparseArray<AppPair> mActiveAppPairs = new SparseArray<>();
|
||||||
private final DisplayController mDisplayController;
|
private final DisplayController mDisplayController;
|
||||||
|
private final DisplayImeController mDisplayImeController;
|
||||||
|
|
||||||
public AppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
|
public AppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
|
||||||
DisplayController displayController, ShellExecutor mainExecutor) {
|
DisplayController displayController, ShellExecutor mainExecutor,
|
||||||
|
DisplayImeController displayImeController) {
|
||||||
mTaskOrganizer = organizer;
|
mTaskOrganizer = organizer;
|
||||||
mSyncQueue = syncQueue;
|
mSyncQueue = syncQueue;
|
||||||
mDisplayController = displayController;
|
mDisplayController = displayController;
|
||||||
|
mDisplayImeController = displayImeController;
|
||||||
mMainExecutor = mainExecutor;
|
mMainExecutor = mainExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,18 +132,22 @@ public class AppPairsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShellTaskOrganizer getTaskOrganizer() {
|
ShellTaskOrganizer getTaskOrganizer() {
|
||||||
return mTaskOrganizer;
|
return mTaskOrganizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SyncTransactionQueue getSyncTransactionQueue() {
|
SyncTransactionQueue getSyncTransactionQueue() {
|
||||||
return mSyncQueue;
|
return mSyncQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayController getDisplayController() {
|
DisplayController getDisplayController() {
|
||||||
return mDisplayController;
|
return mDisplayController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisplayImeController getDisplayImeController() {
|
||||||
|
return mDisplayImeController;
|
||||||
|
}
|
||||||
|
|
||||||
public void dump(@NonNull PrintWriter pw, String prefix) {
|
public void dump(@NonNull PrintWriter pw, String prefix) {
|
||||||
final String innerPrefix = prefix + " ";
|
final String innerPrefix = prefix + " ";
|
||||||
final String childPrefix = innerPrefix + " ";
|
final String childPrefix = innerPrefix + " ";
|
||||||
|
|||||||
@@ -36,11 +36,13 @@ import androidx.annotation.Nullable;
|
|||||||
import com.android.internal.policy.DividerSnapAlgorithm;
|
import com.android.internal.policy.DividerSnapAlgorithm;
|
||||||
import com.android.wm.shell.R;
|
import com.android.wm.shell.R;
|
||||||
import com.android.wm.shell.animation.Interpolators;
|
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_ANIMATION_DURATION = 150;
|
||||||
public static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;
|
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 boolean mMoving;
|
||||||
private int mStartPos;
|
private int mStartPos;
|
||||||
private GestureDetector mDoubleTapDetector;
|
private GestureDetector mDoubleTapDetector;
|
||||||
|
private boolean mInteractive;
|
||||||
|
|
||||||
public DividerView(@NonNull Context context) {
|
public DividerView(@NonNull Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@@ -91,12 +94,19 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
|
|||||||
mTouchElevation = getResources().getDimensionPixelSize(
|
mTouchElevation = getResources().getDimensionPixelSize(
|
||||||
R.dimen.docked_stack_divider_lift_elevation);
|
R.dimen.docked_stack_divider_lift_elevation);
|
||||||
mDoubleTapDetector = new GestureDetector(getContext(), new DoubleTapListener());
|
mDoubleTapDetector = new GestureDetector(getContext(), new DoubleTapListener());
|
||||||
|
mInteractive = true;
|
||||||
setOnTouchListener(this);
|
setOnTouchListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onImeVisibilityChanged(int displayId, boolean isShowing) {
|
||||||
|
if (displayId != getDisplay().getDisplayId()) return;
|
||||||
|
setInteractive(!isShowing);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
if (mSplitLayout == null) {
|
if (mSplitLayout == null || !mInteractive) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +212,13 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
|
|||||||
mViewHost.relayout(lp);
|
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() {
|
private boolean isLandscape() {
|
||||||
return getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE;
|
return getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import androidx.annotation.Nullable;
|
|||||||
|
|
||||||
import com.android.internal.policy.DividerSnapAlgorithm;
|
import com.android.internal.policy.DividerSnapAlgorithm;
|
||||||
import com.android.wm.shell.animation.Interpolators;
|
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
|
* 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,
|
public SplitLayout(String windowName, Context context, Configuration configuration,
|
||||||
LayoutChangeListener layoutChangeListener,
|
LayoutChangeListener layoutChangeListener,
|
||||||
SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks) {
|
SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks,
|
||||||
|
DisplayImeController displayImeController) {
|
||||||
mContext = context.createConfigurationContext(configuration);
|
mContext = context.createConfigurationContext(configuration);
|
||||||
mLayoutChangeListener = layoutChangeListener;
|
mLayoutChangeListener = layoutChangeListener;
|
||||||
mSplitWindowManager = new SplitWindowManager(
|
mSplitWindowManager = new SplitWindowManager(
|
||||||
windowName, mContext, configuration, parentContainerCallbacks);
|
windowName, mContext, configuration, parentContainerCallbacks,
|
||||||
|
displayImeController);
|
||||||
|
|
||||||
mDividerWindowWidth = context.getResources().getDimensionPixelSize(
|
mDividerWindowWidth = context.getResources().getDimensionPixelSize(
|
||||||
com.android.internal.R.dimen.docked_stack_divider_thickness);
|
com.android.internal.R.dimen.docked_stack_divider_thickness);
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import android.view.WindowlessWindowManager;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.wm.shell.R;
|
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.
|
* 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 {
|
public final class SplitWindowManager extends WindowlessWindowManager {
|
||||||
private static final String TAG = SplitWindowManager.class.getSimpleName();
|
private static final String TAG = SplitWindowManager.class.getSimpleName();
|
||||||
|
|
||||||
|
private final String mWindowName;
|
||||||
|
private final DisplayImeController mDisplayImeController;
|
||||||
private final ParentContainerCallbacks mParentContainerCallbacks;
|
private final ParentContainerCallbacks mParentContainerCallbacks;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private SurfaceControlViewHost mViewHost;
|
private SurfaceControlViewHost mViewHost;
|
||||||
private SurfaceControl mLeash;
|
private SurfaceControl mLeash;
|
||||||
private boolean mResizingSplits;
|
private boolean mResizingSplits;
|
||||||
private final String mWindowName;
|
private DividerView mDividerView;
|
||||||
|
|
||||||
public interface ParentContainerCallbacks {
|
public interface ParentContainerCallbacks {
|
||||||
void attachToParentSurface(SurfaceControl.Builder b);
|
void attachToParentSurface(SurfaceControl.Builder b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SplitWindowManager(String windowName, Context context, Configuration config,
|
public SplitWindowManager(String windowName, Context context, Configuration config,
|
||||||
ParentContainerCallbacks parentContainerCallbacks) {
|
ParentContainerCallbacks parentContainerCallbacks,
|
||||||
|
DisplayImeController displayImeController) {
|
||||||
super(config, null /* rootSurface */, null /* hostInputToken */);
|
super(config, null /* rootSurface */, null /* hostInputToken */);
|
||||||
mContext = context.createConfigurationContext(config);
|
mContext = context.createConfigurationContext(config);
|
||||||
mParentContainerCallbacks = parentContainerCallbacks;
|
mParentContainerCallbacks = parentContainerCallbacks;
|
||||||
mWindowName = windowName;
|
mWindowName = windowName;
|
||||||
|
mDisplayImeController = displayImeController;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -103,14 +108,16 @@ public final class SplitWindowManager extends WindowlessWindowManager {
|
|||||||
|
|
||||||
/** Inflates {@link DividerView} on to the root surface. */
|
/** Inflates {@link DividerView} on to the root surface. */
|
||||||
void init(SplitLayout splitLayout) {
|
void init(SplitLayout splitLayout) {
|
||||||
if (mViewHost == null) {
|
if (mDividerView != null || mViewHost != null) {
|
||||||
mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
|
throw new UnsupportedOperationException(
|
||||||
|
"Try to inflate divider view again without release first");
|
||||||
}
|
}
|
||||||
|
|
||||||
final Rect dividerBounds = splitLayout.getDividerBounds();
|
mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
|
||||||
final DividerView dividerView = (DividerView) LayoutInflater.from(mContext)
|
mDividerView = (DividerView) LayoutInflater.from(mContext)
|
||||||
.inflate(R.layout.split_divider, null /* root */);
|
.inflate(R.layout.split_divider, null /* root */);
|
||||||
|
|
||||||
|
final Rect dividerBounds = splitLayout.getDividerBounds();
|
||||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||||
dividerBounds.width(), dividerBounds.height(), TYPE_DOCK_DIVIDER,
|
dividerBounds.width(), dividerBounds.height(), TYPE_DOCK_DIVIDER,
|
||||||
FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_WATCH_OUTSIDE_TOUCH
|
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.token = new Binder();
|
||||||
lp.setTitle(mWindowName);
|
lp.setTitle(mWindowName);
|
||||||
lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
|
lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
|
||||||
mViewHost.setView(dividerView, lp);
|
mViewHost.setView(mDividerView, lp);
|
||||||
dividerView.setup(splitLayout, mViewHost);
|
mDividerView.setup(splitLayout, mViewHost);
|
||||||
|
mDisplayImeController.addPositionProcessor(mDividerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,6 +136,11 @@ public final class SplitWindowManager extends WindowlessWindowManager {
|
|||||||
* hierarchy.
|
* hierarchy.
|
||||||
*/
|
*/
|
||||||
void release() {
|
void release() {
|
||||||
|
if (mDividerView != null) {
|
||||||
|
mDisplayImeController.removePositionProcessor(mDividerView);
|
||||||
|
mDividerView = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (mViewHost != null){
|
if (mViewHost != null){
|
||||||
mViewHost.release();
|
mViewHost.release();
|
||||||
mViewHost = null;
|
mViewHost = null;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import androidx.annotation.Nullable;
|
|||||||
|
|
||||||
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
|
import com.android.wm.shell.common.DisplayImeController;
|
||||||
import com.android.wm.shell.common.ShellExecutor;
|
import com.android.wm.shell.common.ShellExecutor;
|
||||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||||
import com.android.wm.shell.draganddrop.DragAndDropPolicy;
|
import com.android.wm.shell.draganddrop.DragAndDropPolicy;
|
||||||
@@ -62,18 +63,20 @@ public class SplitScreenController implements DragAndDropPolicy.Starter {
|
|||||||
private final RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
|
private final RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
|
||||||
private final ShellExecutor mMainExecutor;
|
private final ShellExecutor mMainExecutor;
|
||||||
private final SplitScreenImpl mImpl = new SplitScreenImpl();
|
private final SplitScreenImpl mImpl = new SplitScreenImpl();
|
||||||
|
private final DisplayImeController mDisplayImeController;
|
||||||
|
|
||||||
private StageCoordinator mStageCoordinator;
|
private StageCoordinator mStageCoordinator;
|
||||||
|
|
||||||
public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer,
|
public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer,
|
||||||
SyncTransactionQueue syncQueue, Context context,
|
SyncTransactionQueue syncQueue, Context context,
|
||||||
RootTaskDisplayAreaOrganizer rootTDAOrganizer,
|
RootTaskDisplayAreaOrganizer rootTDAOrganizer,
|
||||||
ShellExecutor mainExecutor) {
|
ShellExecutor mainExecutor, DisplayImeController displayImeController) {
|
||||||
mTaskOrganizer = shellTaskOrganizer;
|
mTaskOrganizer = shellTaskOrganizer;
|
||||||
mSyncQueue = syncQueue;
|
mSyncQueue = syncQueue;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mRootTDAOrganizer = rootTDAOrganizer;
|
mRootTDAOrganizer = rootTDAOrganizer;
|
||||||
mMainExecutor = mainExecutor;
|
mMainExecutor = mainExecutor;
|
||||||
|
mDisplayImeController = displayImeController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SplitScreen asSplitScreen() {
|
public SplitScreen asSplitScreen() {
|
||||||
@@ -84,7 +87,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter {
|
|||||||
if (mStageCoordinator == null) {
|
if (mStageCoordinator == null) {
|
||||||
// TODO: Multi-display
|
// TODO: Multi-display
|
||||||
mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
|
mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
|
||||||
mRootTDAOrganizer, mTaskOrganizer);
|
mRootTDAOrganizer, mTaskOrganizer, mDisplayImeController);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
|
|
||||||
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
|
import com.android.wm.shell.common.DisplayImeController;
|
||||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||||
import com.android.wm.shell.common.split.SplitLayout;
|
import com.android.wm.shell.common.split.SplitLayout;
|
||||||
|
|
||||||
@@ -79,10 +80,12 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
|
|||||||
private DisplayAreaInfo mDisplayAreaInfo;
|
private DisplayAreaInfo mDisplayAreaInfo;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final List<SplitScreen.SplitScreenListener> mListeners = new ArrayList<>();
|
private final List<SplitScreen.SplitScreenListener> mListeners = new ArrayList<>();
|
||||||
|
private final DisplayImeController mDisplayImeController;
|
||||||
private boolean mExitSplitScreenOnHide = true;
|
private boolean mExitSplitScreenOnHide = true;
|
||||||
|
|
||||||
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
||||||
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer) {
|
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
||||||
|
DisplayImeController displayImeController) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDisplayId = displayId;
|
mDisplayId = displayId;
|
||||||
mSyncQueue = syncQueue;
|
mSyncQueue = syncQueue;
|
||||||
@@ -90,13 +93,14 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
|
|||||||
mTaskOrganizer = taskOrganizer;
|
mTaskOrganizer = taskOrganizer;
|
||||||
mMainStage = new MainStage(mTaskOrganizer, mDisplayId, mMainStageListener, mSyncQueue);
|
mMainStage = new MainStage(mTaskOrganizer, mDisplayId, mMainStageListener, mSyncQueue);
|
||||||
mSideStage = new SideStage(mTaskOrganizer, mDisplayId, mSideStageListener, mSyncQueue);
|
mSideStage = new SideStage(mTaskOrganizer, mDisplayId, mSideStageListener, mSyncQueue);
|
||||||
|
mDisplayImeController = displayImeController;
|
||||||
mRootTDAOrganizer.registerListener(displayId, this);
|
mRootTDAOrganizer.registerListener(displayId, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
||||||
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
||||||
MainStage mainStage, SideStage sideStage) {
|
MainStage mainStage, SideStage sideStage, DisplayImeController displayImeController) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDisplayId = displayId;
|
mDisplayId = displayId;
|
||||||
mSyncQueue = syncQueue;
|
mSyncQueue = syncQueue;
|
||||||
@@ -104,6 +108,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
|
|||||||
mTaskOrganizer = taskOrganizer;
|
mTaskOrganizer = taskOrganizer;
|
||||||
mMainStage = mainStage;
|
mMainStage = mainStage;
|
||||||
mSideStage = sideStage;
|
mSideStage = sideStage;
|
||||||
|
mDisplayImeController = displayImeController;
|
||||||
mRootTDAOrganizer.registerListener(displayId, this);
|
mRootTDAOrganizer.registerListener(displayId, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,7 +425,8 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
|
|||||||
if (mSplitLayout == null) {
|
if (mSplitLayout == null) {
|
||||||
mSplitLayout = new SplitLayout(TAG + "SplitDivider", mContext,
|
mSplitLayout = new SplitLayout(TAG + "SplitDivider", mContext,
|
||||||
mDisplayAreaInfo.configuration, this,
|
mDisplayAreaInfo.configuration, this,
|
||||||
b -> mRootTDAOrganizer.attachToDisplayArea(mDisplayId, b));
|
b -> mRootTDAOrganizer.attachToDisplayArea(mDisplayId, b),
|
||||||
|
mDisplayImeController);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,17 @@ import static org.mockito.Mockito.mock;
|
|||||||
|
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
import com.android.wm.shell.common.DisplayController;
|
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.ShellExecutor;
|
||||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||||
|
|
||||||
import org.mockito.Mock;
|
|
||||||
|
|
||||||
public class TestAppPairsController extends AppPairsController {
|
public class TestAppPairsController extends AppPairsController {
|
||||||
private TestAppPairsPool mPool;
|
private TestAppPairsPool mPool;
|
||||||
|
|
||||||
public TestAppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
|
public TestAppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
|
||||||
DisplayController displayController) {
|
DisplayController displayController) {
|
||||||
super(organizer, syncQueue, displayController, mock(ShellExecutor.class));
|
super(organizer, syncQueue, displayController, mock(ShellExecutor.class),
|
||||||
|
mock(DisplayImeController.class));
|
||||||
mPool = new TestAppPairsPool(this);
|
mPool = new TestAppPairsPool(this);
|
||||||
setPairsPool(mPool);
|
setPairsPool(mPool);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import androidx.test.filters.SmallTest;
|
|||||||
|
|
||||||
import com.android.internal.policy.DividerSnapAlgorithm;
|
import com.android.internal.policy.DividerSnapAlgorithm;
|
||||||
import com.android.wm.shell.ShellTestCase;
|
import com.android.wm.shell.ShellTestCase;
|
||||||
|
import com.android.wm.shell.common.DisplayImeController;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -49,6 +50,7 @@ import org.mockito.MockitoAnnotations;
|
|||||||
public class SplitLayoutTests extends ShellTestCase {
|
public class SplitLayoutTests extends ShellTestCase {
|
||||||
@Mock SplitLayout.LayoutChangeListener mLayoutChangeListener;
|
@Mock SplitLayout.LayoutChangeListener mLayoutChangeListener;
|
||||||
@Mock SurfaceControl mRootLeash;
|
@Mock SurfaceControl mRootLeash;
|
||||||
|
@Mock DisplayImeController mDisplayImeController;
|
||||||
private SplitLayout mSplitLayout;
|
private SplitLayout mSplitLayout;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -59,7 +61,8 @@ public class SplitLayoutTests extends ShellTestCase {
|
|||||||
mContext,
|
mContext,
|
||||||
getConfiguration(false),
|
getConfiguration(false),
|
||||||
mLayoutChangeListener,
|
mLayoutChangeListener,
|
||||||
b -> b.setParent(mRootLeash));
|
b -> b.setParent(mRootLeash),
|
||||||
|
mDisplayImeController);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.wm.shell.ShellTestCase;
|
import com.android.wm.shell.ShellTestCase;
|
||||||
|
import com.android.wm.shell.common.DisplayImeController;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -42,6 +43,7 @@ import org.mockito.MockitoAnnotations;
|
|||||||
public class SplitWindowManagerTests extends ShellTestCase {
|
public class SplitWindowManagerTests extends ShellTestCase {
|
||||||
@Mock SurfaceControl mSurfaceControl;
|
@Mock SurfaceControl mSurfaceControl;
|
||||||
@Mock SplitLayout mSplitLayout;
|
@Mock SplitLayout mSplitLayout;
|
||||||
|
@Mock DisplayImeController mDisplayImeController;
|
||||||
private SplitWindowManager mSplitWindowManager;
|
private SplitWindowManager mSplitWindowManager;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -50,7 +52,7 @@ public class SplitWindowManagerTests extends ShellTestCase {
|
|||||||
final Configuration configuration = new Configuration();
|
final Configuration configuration = new Configuration();
|
||||||
configuration.setToDefaults();
|
configuration.setToDefaults();
|
||||||
mSplitWindowManager = new SplitWindowManager("TestSplitDivider", mContext, configuration,
|
mSplitWindowManager = new SplitWindowManager("TestSplitDivider", mContext, configuration,
|
||||||
b -> b.setParent(mSurfaceControl));
|
b -> b.setParent(mSurfaceControl), mDisplayImeController);
|
||||||
when(mSplitLayout.getDividerBounds()).thenReturn(
|
when(mSplitLayout.getDividerBounds()).thenReturn(
|
||||||
new Rect(0, 0, configuration.windowConfiguration.getBounds().width(),
|
new Rect(0, 0, configuration.windowConfiguration.getBounds().width(),
|
||||||
configuration.windowConfiguration.getBounds().height()));
|
configuration.windowConfiguration.getBounds().height()));
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
|||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
import com.android.wm.shell.ShellTestCase;
|
import com.android.wm.shell.ShellTestCase;
|
||||||
import com.android.wm.shell.TestRunningTaskInfoBuilder;
|
import com.android.wm.shell.TestRunningTaskInfoBuilder;
|
||||||
|
import com.android.wm.shell.common.DisplayImeController;
|
||||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -58,13 +59,14 @@ public class StageCoordinatorTests extends ShellTestCase {
|
|||||||
@Mock private RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
|
@Mock private RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
|
||||||
@Mock private MainStage mMainStage;
|
@Mock private MainStage mMainStage;
|
||||||
@Mock private SideStage mSideStage;
|
@Mock private SideStage mSideStage;
|
||||||
|
@Mock private DisplayImeController mDisplayImeController;
|
||||||
private StageCoordinator mStageCoordinator;
|
private StageCoordinator mStageCoordinator;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mStageCoordinator = new TestStageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
|
mStageCoordinator = new TestStageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
|
||||||
mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage);
|
mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage, mDisplayImeController);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -94,9 +96,9 @@ public class StageCoordinatorTests extends ShellTestCase {
|
|||||||
|
|
||||||
TestStageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
TestStageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
||||||
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
||||||
MainStage mainStage, SideStage sideStage) {
|
MainStage mainStage, SideStage sideStage, DisplayImeController imeController) {
|
||||||
super(context, displayId, syncQueue, rootTDAOrganizer, taskOrganizer, mainStage,
|
super(context, displayId, syncQueue, rootTDAOrganizer, taskOrganizer, mainStage,
|
||||||
sideStage);
|
sideStage, imeController);
|
||||||
|
|
||||||
// Prepare default TaskDisplayArea for testing.
|
// Prepare default TaskDisplayArea for testing.
|
||||||
mDisplayAreaInfo = new DisplayAreaInfo(
|
mDisplayAreaInfo = new DisplayAreaInfo(
|
||||||
|
|||||||
@@ -415,10 +415,11 @@ public abstract class WMShellBaseModule {
|
|||||||
ShellTaskOrganizer shellTaskOrganizer,
|
ShellTaskOrganizer shellTaskOrganizer,
|
||||||
SyncTransactionQueue syncQueue, Context context,
|
SyncTransactionQueue syncQueue, Context context,
|
||||||
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
|
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
|
||||||
@ShellMainThread ShellExecutor mainExecutor) {
|
@ShellMainThread ShellExecutor mainExecutor,
|
||||||
|
DisplayImeController displayImeController) {
|
||||||
if (ActivityTaskManager.supportsSplitScreenMultiWindow(context)) {
|
if (ActivityTaskManager.supportsSplitScreenMultiWindow(context)) {
|
||||||
return Optional.of(new SplitScreenController(shellTaskOrganizer, syncQueue, context,
|
return Optional.of(new SplitScreenController(shellTaskOrganizer, syncQueue, context,
|
||||||
rootTaskDisplayAreaOrganizer, mainExecutor));
|
rootTaskDisplayAreaOrganizer, mainExecutor, displayImeController));
|
||||||
} else {
|
} else {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,9 +104,10 @@ public class WMShellModule {
|
|||||||
@Provides
|
@Provides
|
||||||
static AppPairsController provideAppPairs(ShellTaskOrganizer shellTaskOrganizer,
|
static AppPairsController provideAppPairs(ShellTaskOrganizer shellTaskOrganizer,
|
||||||
SyncTransactionQueue syncQueue, DisplayController displayController,
|
SyncTransactionQueue syncQueue, DisplayController displayController,
|
||||||
@ShellMainThread ShellExecutor mainExecutor) {
|
@ShellMainThread ShellExecutor mainExecutor,
|
||||||
|
DisplayImeController displayImeController) {
|
||||||
return new AppPairsController(shellTaskOrganizer, syncQueue, displayController,
|
return new AppPairsController(shellTaskOrganizer, syncQueue, displayController,
|
||||||
mainExecutor);
|
mainExecutor, displayImeController);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -150,7 +150,6 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityManagerInternal;
|
import android.app.ActivityManagerInternal;
|
||||||
import android.app.WindowConfiguration;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.ActivityInfo.ScreenOrientation;
|
import android.content.pm.ActivityInfo.ScreenOrientation;
|
||||||
@@ -3639,8 +3638,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isImeControlledByApp() {
|
private boolean isImeControlledByApp() {
|
||||||
return mImeInputTarget != null && !WindowConfiguration.isSplitScreenWindowingMode(
|
return mImeInputTarget != null && !mImeInputTarget.inMultiWindowMode();
|
||||||
mImeInputTarget.getWindowingMode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isImeAttachedToApp() {
|
boolean isImeAttachedToApp() {
|
||||||
|
|||||||
Reference in New Issue
Block a user