summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jerry Chang <chenghsiuchang@google.com> 2020-12-17 06:17:26 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-12-17 06:17:26 +0000
commit39a6d69a5dac71de53326b3f6f3cfeae5ec5d97d (patch)
treecc2c0e4d5dbe8335cd43d881229c6ec96778ec5c
parent46bdad0bab63783853c727ea9b336d3be3607d05 (diff)
parent2c8ea7b0217ecd50a70c52b3fbd3fa7697d297d7 (diff)
Merge "Fix showing black background when resizing the divider bar."
-rw-r--r--libs/WindowManager/Shell/res/layout/docked_stack_divider.xml4
-rw-r--r--libs/WindowManager/Shell/res/layout/split_divider.xml6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java (renamed from libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerHandleView.java)12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java76
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java15
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java3
10 files changed, 116 insertions, 58 deletions
diff --git a/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml b/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml
index ea21eb97df57..ed5d2e1b49f5 100644
--- a/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml
+++ b/libs/WindowManager/Shell/res/layout/docked_stack_divider.xml
@@ -27,9 +27,9 @@
<com.android.wm.shell.legacysplitscreen.MinimizedDockShadow
style="@style/DockedDividerMinimizedShadow"
android:id="@+id/minimized_dock_shadow"
- android:alpha="0"/>">
+ android:alpha="0"/>
- <com.android.wm.shell.legacysplitscreen.DividerHandleView
+ <com.android.wm.shell.common.split.DividerHandleView
style="@style/DockedDividerHandle"
android:id="@+id/docked_divider_handle"
android:contentDescription="@string/accessibility_divider"
diff --git a/libs/WindowManager/Shell/res/layout/split_divider.xml b/libs/WindowManager/Shell/res/layout/split_divider.xml
index 341fe617b2d0..7f583f3e6bac 100644
--- a/libs/WindowManager/Shell/res/layout/split_divider.xml
+++ b/libs/WindowManager/Shell/res/layout/split_divider.xml
@@ -24,4 +24,10 @@
android:id="@+id/docked_divider_background"
android:background="@color/docked_divider_background"/>
+ <com.android.wm.shell.common.split.DividerHandleView
+ style="@style/DockedDividerHandle"
+ android:id="@+id/docked_divider_handle"
+ android:contentDescription="@string/accessibility_divider"
+ android:background="@null"/>
+
</com.android.wm.shell.common.split.DividerView>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
index 9754f5165a1c..563de06fe40c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
@@ -96,7 +96,8 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan
mTaskInfo2 = task2;
mSplitLayout = new SplitLayout(
mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
- mRootTaskInfo.configuration, this, b -> b.setParent(mRootTaskLeash));
+ mRootTaskInfo.configuration, this /* layoutChangeListener */,
+ b -> b.setParent(mRootTaskLeash));
final WindowContainerToken token1 = task1.token;
final WindowContainerToken token2 = task2.token;
@@ -191,22 +192,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan
if (mSplitLayout != null
&& mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)) {
- // Update bounds when root bounds or its orientation changed.
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
- final Rect dividerBounds = mSplitLayout.getDividerBounds();
- final Rect bounds1 = mSplitLayout.getBounds1();
- final Rect bounds2 = mSplitLayout.getBounds2();
-
- wct.setBounds(mTaskInfo1.token, bounds1)
- .setBounds(mTaskInfo2.token, bounds2);
- mController.getTaskOrganizer().applyTransaction(wct);
- mSyncQueue.runInSync(t -> t
- .setPosition(mTaskLeash1, bounds1.left, bounds1.top)
- .setPosition(mTaskLeash2, bounds2.left, bounds2.top)
- .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
- // Resets layer to divider bar to make sure it is always on top.
- .setLayer(dividerLeash, Integer.MAX_VALUE));
+ onBoundsChanged(mSplitLayout);
}
} else if (taskInfo.taskId == getTaskId1()) {
mTaskInfo1 = taskInfo;
@@ -262,6 +248,10 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan
final Rect bounds1 = layout.getBounds1();
final Rect bounds2 = layout.getBounds2();
mSyncQueue.runInSync(t -> t
+ // Ignores the original surface bounds so that the app could fill up the gap
+ // between each surface with corresponding background while resizing.
+ .setWindowCrop(mTaskLeash1, bounds1.width(), bounds1.height())
+ .setWindowCrop(mTaskLeash2, bounds2.width(), bounds2.height())
.setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
.setPosition(mTaskLeash1, bounds1.left, bounds1.top)
.setPosition(mTaskLeash2, bounds2.left, bounds2.top));
@@ -279,6 +269,10 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan
.setBounds(mTaskInfo2.token, bounds2);
mController.getTaskOrganizer().applyTransaction(wct);
mSyncQueue.runInSync(t -> t
+ // Resets layer of divider bar to make sure it is always on top.
+ .setLayer(dividerLeash, Integer.MAX_VALUE)
+ .setWindowCrop(mTaskLeash1, bounds1.width(), bounds1.height())
+ .setWindowCrop(mTaskLeash2, bounds2.width(), bounds2.height())
.setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
.setPosition(mTaskLeash1, bounds1.left, bounds1.top)
.setPosition(mTaskLeash2, bounds2.left, bounds2.top));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java
index 17ca110285bf..218bf47e24aa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerHandleView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerHandleView.java
@@ -14,7 +14,10 @@
* limitations under the License.
*/
-package com.android.wm.shell.legacysplitscreen;
+package com.android.wm.shell.common.split;
+
+import static com.android.wm.shell.common.split.DividerView.TOUCH_ANIMATION_DURATION;
+import static com.android.wm.shell.common.split.DividerView.TOUCH_RELEASE_ANIMATION_DURATION;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -84,7 +87,8 @@ public class DividerHandleView extends View {
mCircleDiameter = (mWidth + mHeight) / 3;
}
- void setTouching(boolean touching, boolean animate) {
+ /** Sets touching state for this handle view. */
+ public void setTouching(boolean touching, boolean animate) {
if (touching == mTouching) {
return;
}
@@ -116,8 +120,8 @@ public class DividerHandleView extends View {
mAnimator = new AnimatorSet();
mAnimator.playTogether(widthAnimator, heightAnimator);
mAnimator.setDuration(touching
- ? DividerView.TOUCH_ANIMATION_DURATION
- : DividerView.TOUCH_RELEASE_ANIMATION_DURATION);
+ ? TOUCH_ANIMATION_DURATION
+ : TOUCH_RELEASE_ANIMATION_DURATION);
mAnimator.setInterpolator(touching
? Interpolators.TOUCH_RESPONSE
: Interpolators.FAST_OUT_SLOW_IN);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index e97fe0a9111c..707747b3889b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -33,17 +33,23 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.policy.DividerSnapAlgorithm;
+import com.android.wm.shell.R;
+import com.android.wm.shell.animation.Interpolators;
/**
* Stack divider for app pair.
*/
-// TODO(b/172704238): add handle view to indicate touching status.
public class DividerView extends FrameLayout implements View.OnTouchListener {
+ public static final long TOUCH_ANIMATION_DURATION = 150;
+ public static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;
+
private final int mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
private SplitLayout mSplitLayout;
private SurfaceControlViewHost mViewHost;
- private DragListener mDragListener;
+ private DividerHandleView mHandle;
+ private View mBackground;
+ private int mTouchElevation;
private VelocityTracker mVelocityTracker;
private boolean mMoving;
@@ -70,16 +76,18 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
/** Sets up essential dependencies of the divider bar. */
public void setup(
SplitLayout layout,
- SurfaceControlViewHost viewHost,
- @Nullable DragListener dragListener) {
+ SurfaceControlViewHost viewHost) {
mSplitLayout = layout;
mViewHost = viewHost;
- mDragListener = dragListener;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ mHandle = findViewById(R.id.docked_divider_handle);
+ mBackground = findViewById(R.id.docked_divider_background);
+ mTouchElevation = getResources().getDimensionPixelSize(
+ R.dimen.docked_stack_divider_lift_elevation);
setOnTouchListener(this);
}
@@ -97,7 +105,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
case MotionEvent.ACTION_DOWN:
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(event);
- setSlippery(false);
+ setTouching();
mStartPos = touchPos;
mMoving = false;
break;
@@ -106,9 +114,6 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
if (!mMoving && Math.abs(touchPos - mStartPos) > mTouchSlop) {
mStartPos = touchPos;
mMoving = true;
- if (mDragListener != null) {
- mDragListener.onDragStart();
- }
}
if (mMoving) {
final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
@@ -122,11 +127,8 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
final float velocity = isLandscape
? mVelocityTracker.getXVelocity()
: mVelocityTracker.getYVelocity();
- setSlippery(true);
+ releaseTouching();
mMoving = false;
- if (mDragListener != null) {
- mDragListener.onDragEnd();
- }
final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
final DividerSnapAlgorithm.SnapTarget snapTarget =
@@ -137,6 +139,45 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
return true;
}
+ private void setTouching() {
+ setSlippery(false);
+ mHandle.setTouching(true, true);
+ if (isLandscape()) {
+ mBackground.animate().scaleX(1.4f);
+ } else {
+ mBackground.animate().scaleY(1.4f);
+ }
+ mBackground.animate()
+ .setInterpolator(Interpolators.TOUCH_RESPONSE)
+ .setDuration(TOUCH_ANIMATION_DURATION)
+ .translationZ(mTouchElevation)
+ .start();
+ // Lift handle as well so it doesn't get behind the background, even though it doesn't
+ // cast shadow.
+ mHandle.animate()
+ .setInterpolator(Interpolators.TOUCH_RESPONSE)
+ .setDuration(TOUCH_ANIMATION_DURATION)
+ .translationZ(mTouchElevation)
+ .start();
+ }
+
+ private void releaseTouching() {
+ setSlippery(true);
+ mHandle.setTouching(false, true);
+ mBackground.animate()
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .setDuration(TOUCH_RELEASE_ANIMATION_DURATION)
+ .translationZ(0)
+ .scaleX(1f)
+ .scaleY(1f)
+ .start();
+ mHandle.animate()
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .setDuration(TOUCH_RELEASE_ANIMATION_DURATION)
+ .translationZ(0)
+ .start();
+ }
+
private void setSlippery(boolean slippery) {
if (mViewHost == null) {
return;
@@ -159,13 +200,4 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
private boolean isLandscape() {
return getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE;
}
-
- /** Monitors dragging action of the divider bar. */
- // TODO(b/172704238): add listeners to deal with resizing state of the app windows.
- public interface DragListener {
- /** Called when start dragging. */
- void onDragStart();
- /** Called when stop dragging. */
- void onDragEnd();
- }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 6b9bf2d44261..291e9bdad69b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -156,12 +156,14 @@ public class SplitLayout {
void updateDivideBounds(int position) {
updateBounds(position);
mLayoutChangeListener.onBoundsChanging(this);
+ mSplitWindowManager.setResizingSplits(true);
}
void setDividePosition(int position) {
mDividePosition = position;
updateBounds(mDividePosition);
mLayoutChangeListener.onBoundsChanged(this);
+ mSplitWindowManager.setResizingSplits(false);
}
/**
@@ -172,9 +174,11 @@ public class SplitLayout {
switch (snapTarget.flag) {
case FLAG_DISMISS_START:
mLayoutChangeListener.onSnappedToDismiss(false /* snappedToEnd */);
+ mSplitWindowManager.setResizingSplits(false);
break;
case FLAG_DISMISS_END:
mLayoutChangeListener.onSnappedToDismiss(true /* snappedToEnd */);
+ mSplitWindowManager.setResizingSplits(false);
break;
default:
flingDividePosition(currentPosition, snapTarget.position);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
index 238caef27547..29116bd6f956 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
@@ -25,6 +25,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import android.app.ActivityTaskManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
@@ -32,6 +33,8 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.os.Binder;
import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
import android.view.IWindow;
import android.view.LayoutInflater;
import android.view.SurfaceControl;
@@ -47,11 +50,13 @@ import com.android.wm.shell.R;
* Holds view hierarchy of a root surface and helps to inflate {@link DividerView} for a split.
*/
public final class SplitWindowManager extends WindowlessWindowManager {
+ private static final String TAG = SplitWindowManager.class.getSimpleName();
private static final String DIVIDER_WINDOW_TITLE = "SplitDivider";
+ private final ParentContainerCallbacks mParentContainerCallbacks;
private Context mContext;
private SurfaceControlViewHost mViewHost;
- final private ParentContainerCallbacks mParentContainerCallbacks;
+ private boolean mResizingSplits;
public interface ParentContainerCallbacks {
void attachToParentSurface(SurfaceControl.Builder b);
@@ -104,7 +109,7 @@ public final class SplitWindowManager extends WindowlessWindowManager {
lp.setTitle(DIVIDER_WINDOW_TITLE);
lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
mViewHost.setView(dividerView, lp);
- dividerView.setup(splitLayout, mViewHost, null /* dragListener */);
+ dividerView.setup(splitLayout, mViewHost);
}
/**
@@ -117,6 +122,16 @@ public final class SplitWindowManager extends WindowlessWindowManager {
mViewHost = null;
}
+ void setResizingSplits(boolean resizing) {
+ if (resizing == mResizingSplits) return;
+ try {
+ ActivityTaskManager.getService().setSplitScreenResizing(resizing);
+ mResizingSplits = resizing;
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Error calling setSplitScreenResizing", e);
+ }
+ }
+
/**
* Gets {@link SurfaceControl} of the surface holding divider view. @return {@code null} if not
* feasible.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
index 16c966fccbf4..c1b6c4fec792 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
@@ -20,6 +20,9 @@ import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
import static android.view.WindowManager.DOCKED_RIGHT;
+import static com.android.wm.shell.common.split.DividerView.TOUCH_ANIMATION_DURATION;
+import static com.android.wm.shell.common.split.DividerView.TOUCH_RELEASE_ANIMATION_DURATION;
+
import android.animation.AnimationHandler;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -66,6 +69,7 @@ import com.android.internal.policy.DockedDividerUtils;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.FlingAnimationUtils;
import com.android.wm.shell.animation.Interpolators;
+import com.android.wm.shell.common.split.DividerHandleView;
import java.util.function.Consumer;
@@ -82,9 +86,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,
void onDraggingEnd();
}
- static final long TOUCH_ANIMATION_DURATION = 150;
- static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;
-
public static final int INVALID_RECENTS_GROW_TARGET = -1;
private static final int LOG_VALUE_RESIZE_50_50 = 0;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
index 708a6c56a3f5..cd468167e372 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
@@ -75,15 +75,16 @@ public class SplitLayoutTests extends ShellTestCase {
}
@Test
- @UiThreadTest
- public void testSnapToTarget() {
- DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */,
- DividerSnapAlgorithm.SnapTarget.FLAG_NONE);
- mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
- verify(mLayoutChangeListener).onBoundsChanging(any(SplitLayout.class));
+ public void testSetDividePosition() {
+ mSplitLayout.setDividePosition(anyInt());
+ verify(mLayoutChangeListener).onBoundsChanged(any(SplitLayout.class));
+ }
+ @Test
+ @UiThreadTest
+ public void testSnapToDismissTarget() {
// verify it callbacks properly when the snap target indicates dismissing split.
- snapTarget = getSnapTarget(0 /* position */,
+ DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */,
DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START);
mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
verify(mLayoutChangeListener).onSnappedToDismiss(eq(false));
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 32b84a8d0a2c..d3102600092f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3843,7 +3843,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (task == null) {
return false;
}
- if (!inSplitScreenWindowingMode() && !inFreeformWindowingMode()) {
+ if (!inSplitScreenWindowingMode() && !inFreeformWindowingMode()
+ && !task.getRootTask().mCreatedByOrganizer) {
return false;
}
// TODO(157912944): formalize drag-resizing so that exceptions aren't hardcoded like this