Loading libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java +4 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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; Loading libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java +12 −6 Original line number Diff line number Diff line Loading @@ -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}. Loading @@ -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; } Loading Loading @@ -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 + " "; Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +20 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +5 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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); Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +21 −8 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 Loading Loading @@ -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 Loading @@ -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); } /** Loading @@ -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 Loading
libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java +4 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java +12 −6 Original line number Diff line number Diff line Loading @@ -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}. Loading @@ -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; } Loading Loading @@ -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 + " "; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +20 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +5 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java +21 −8 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 Loading Loading @@ -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 Loading @@ -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); } /** Loading @@ -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