When long pressing recents and already docked, undock
Bug: 26771328
Change-Id: I1fe12181cd80fd948e4184be6a8790c77bfe9e45
diff --git a/packages/SystemUI/src/com/android/systemui/Interpolators.java b/packages/SystemUI/src/com/android/systemui/Interpolators.java
index cd6dce0..5e33a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/Interpolators.java
+++ b/packages/SystemUI/src/com/android/systemui/Interpolators.java
@@ -34,4 +34,10 @@
public static final Interpolator LINEAR = new LinearInterpolator();
public static final Interpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator();
public static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f);
+
+ /**
+ * Interpolator to be used when animating a move based on a click. Pair with enough duration.
+ */
+ public static final Interpolator TOUCH_RESPONSE =
+ new PathInterpolator(0.3f, 0f, 0.1f, 1f);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/UndockingTaskEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/UndockingTaskEvent.java
new file mode 100644
index 0000000..d5083a8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/UndockingTaskEvent.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * Fires when the user invoked the gesture to undock the task in the docked stack.
+ */
+public class UndockingTaskEvent extends EventBus.Event {
+
+ public UndockingTaskEvent() {
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
index 5ef56f3..12e2713 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
@@ -26,10 +26,9 @@
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Property;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
import android.widget.ImageButton;
+import com.android.systemui.Interpolators;
import com.android.systemui.R;
/**
@@ -71,7 +70,6 @@
private final int mWidth;
private final int mHeight;
private final int mCircleDiameter;
- private final Interpolator mFastOutSlowInInterpolator;
private int mCurrentWidth;
private int mCurrentHeight;
private AnimatorSet mAnimator;
@@ -85,8 +83,6 @@
mCurrentWidth = mWidth;
mCurrentHeight = mHeight;
mCircleDiameter = (mWidth + mHeight) / 3;
- mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
- android.R.interpolator.fast_out_slow_in);
}
public void setTouching(boolean touching, boolean animate) {
@@ -120,8 +116,8 @@
? DividerView.TOUCH_ANIMATION_DURATION
: DividerView.TOUCH_RELEASE_ANIMATION_DURATION);
mAnimator.setInterpolator(touching
- ? DividerView.TOUCH_RESPONSE_INTERPOLATOR
- : mFastOutSlowInInterpolator);
+ ? Interpolators.TOUCH_RESPONSE
+ : Interpolators.FAST_OUT_SLOW_IN);
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 40e2611..83c22b1 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -48,10 +48,12 @@
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
import com.android.internal.policy.DockedDividerUtils;
+import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.DockingTopTaskEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
+import com.android.systemui.recents.events.activity.UndockingTaskEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
@@ -67,8 +69,6 @@
static final long TOUCH_ANIMATION_DURATION = 150;
static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;
- static final Interpolator TOUCH_RESPONSE_INTERPOLATOR =
- new PathInterpolator(0.3f, 0f, 0.1f, 1f);
private static final String TAG = "DividerView";
@@ -116,7 +116,6 @@
private final Rect mOtherInsetRect = new Rect();
private final Rect mLastResizeRect = new Rect();
private final WindowManagerProxy mWindowManagerProxy = WindowManagerProxy.getInstance();
- private Interpolator mFastOutSlowInInterpolator;
private DividerWindowManager mWindowManager;
private VelocityTracker mVelocityTracker;
private FlingAnimationUtils mFlingAnimationUtils;
@@ -158,8 +157,6 @@
mTouchElevation = getResources().getDimensionPixelSize(
R.dimen.docked_stack_divider_lift_elevation);
mGrowRecents = getResources().getBoolean(R.bool.recents_grow_in_multiwindow);
- mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
- android.R.interpolator.fast_out_slow_in);
mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.3f);
updateDisplayInfo();
@@ -229,8 +226,13 @@
public void stopDragging(int position, SnapTarget target, long duration,
Interpolator interpolator) {
+ stopDragging(position, target, duration, 0 /* startDelay*/, interpolator);
+ }
+
+ public void stopDragging(int position, SnapTarget target, long duration, long startDelay,
+ Interpolator interpolator) {
mHandle.setTouching(false, true /* animate */);
- flingTo(position, target, duration, interpolator);
+ flingTo(position, target, duration, startDelay, interpolator);
mWindowManager.setSlippery(true);
releaseBackground();
}
@@ -335,10 +337,11 @@
anim.start();
}
- private void flingTo(int position, SnapTarget target, long duration,
+ private void flingTo(int position, SnapTarget target, long duration, long startDelay,
Interpolator interpolator) {
ValueAnimator anim = getFlingAnimator(position, target);
anim.setDuration(duration);
+ anim.setStartDelay(startDelay);
anim.setInterpolator(interpolator);
anim.start();
}
@@ -392,7 +395,7 @@
mBackground.animate().scaleX(1.4f);
}
mBackground.animate()
- .setInterpolator(TOUCH_RESPONSE_INTERPOLATOR)
+ .setInterpolator(Interpolators.TOUCH_RESPONSE)
.setDuration(TOUCH_ANIMATION_DURATION)
.translationZ(mTouchElevation)
.start();
@@ -400,7 +403,7 @@
// Lift handle as well so it doesn't get behind the background, even though it doesn't
// cast shadow.
mHandle.animate()
- .setInterpolator(TOUCH_RESPONSE_INTERPOLATOR)
+ .setInterpolator(Interpolators.TOUCH_RESPONSE)
.setDuration(TOUCH_ANIMATION_DURATION)
.translationZ(mTouchElevation)
.start();
@@ -408,14 +411,14 @@
private void releaseBackground() {
mBackground.animate()
- .setInterpolator(mFastOutSlowInInterpolator)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.setDuration(TOUCH_RELEASE_ANIMATION_DURATION)
.translationZ(0)
.scaleX(1f)
.scaleY(1f)
.start();
mHandle.animate()
- .setInterpolator(mFastOutSlowInInterpolator)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.setDuration(TOUCH_RELEASE_ANIMATION_DURATION)
.translationZ(0)
.start();
@@ -743,13 +746,27 @@
mAnimateAfterRecentsDrawn = false;
updateDockSide();
stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 250,
- TOUCH_RESPONSE_INTERPOLATOR);
+ Interpolators.TOUCH_RESPONSE);
}
if (mGrowAfterRecentsDrawn) {
mGrowAfterRecentsDrawn = false;
updateDockSide();
stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 250,
- TOUCH_RESPONSE_INTERPOLATOR);
+ Interpolators.TOUCH_RESPONSE);
+ }
+ }
+
+ public final void onBusEvent(UndockingTaskEvent undockingTaskEvent) {
+ int dockSide = mWindowManagerProxy.getDockSide();
+ if (dockSide != WindowManager.DOCKED_INVALID) {
+ startDragging(false /* animate */, false /* touching */);
+ SnapTarget target = dockSideTopLeft(dockSide)
+ ? mSnapAlgorithm.getDismissEndTarget()
+ : mSnapAlgorithm.getDismissStartTarget();
+
+ // Don't start immediately - give a little bit time to settle the drag resize change.
+ stopDragging(getCurrentPosition(), target, 336 /* duration */, 100 /* startDelay */,
+ Interpolators.TOUCH_RESPONSE);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 575eda7..f822bd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -39,8 +39,6 @@
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
import android.widget.TextView;
@@ -212,10 +210,6 @@
}
};
- /** Interpolator to be used for animations that respond directly to a touch */
- private final Interpolator mTouchResponseInterpolator =
- new PathInterpolator(0.3f, 0f, 0.1f, 1f);
-
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(!DEBUG);
@@ -1447,7 +1441,7 @@
mScrollView.setBlockFlinging(true);
ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target);
if (isClick) {
- animator.setInterpolator(mTouchResponseInterpolator);
+ animator.setInterpolator(Interpolators.TOUCH_RESPONSE);
animator.setDuration(368);
} else {
mFlingAnimationUtils.apply(animator, mQsExpansionHeight, target, vel);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 21c1295..4dee51d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -118,7 +118,10 @@
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.UndockingTaskEvent;
import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.stackdivider.WindowManagerProxy;
import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.BackDropView;
import com.android.systemui.statusbar.BaseStatusBar;
@@ -1112,17 +1115,25 @@
@Override
public boolean onLongClick(View v) {
if (mRecents != null) {
- Point realSize = new Point();
- mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY)
- .getRealSize(realSize);
- Rect initialBounds= new Rect(0, 0, realSize.x, realSize.y);
- boolean docked = mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
- ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
- initialBounds);
- if (docked) {
- MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS);
+ int dockSide = WindowManagerProxy.getInstance().getDockSide();
+ if (dockSide == WindowManager.DOCKED_INVALID) {
+ Point realSize = new Point();
+ mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY)
+ .getRealSize(realSize);
+ Rect initialBounds= new Rect(0, 0, realSize.x, realSize.y);
+ boolean docked = mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
+ ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
+ initialBounds);
+ if (docked) {
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS);
+ return true;
+ }
+ } else {
+ EventBus.getDefault().send(new UndockingTaskEvent());
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
return true;
}
+
}
return false;
}