summaryrefslogtreecommitdiffstats
path: root/quickstep
diff options
context:
space:
mode:
Diffstat (limited to 'quickstep')
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java4
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/DragPauseDetector.java92
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java165
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java6
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java71
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/LandscapeStatesTouchController.java70
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/OverviewState.java26
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeUpController.java71
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java128
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/TaggedAnimatorSetBuilder.java51
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java (renamed from quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java)87
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java447
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/UiFactory.java13
-rw-r--r--quickstep/src/com/android/quickstep/ActivityControlHelper.java24
-rw-r--r--quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java48
-rw-r--r--quickstep/src/com/android/quickstep/util/SysuiEventLogger.java47
16 files changed, 387 insertions, 963 deletions
diff --git a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
index efa83e4b6..1fb3584a2 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
@@ -85,8 +85,8 @@ public class AllAppsState extends LauncherState {
}
@Override
- public float getHoseatAlpha(Launcher launcher) {
- return 0;
+ public int getVisibleElements(Launcher launcher) {
+ return ALL_APPS_HEADER | ALL_APPS_CONTENT;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/DragPauseDetector.java b/quickstep/src/com/android/launcher3/uioverrides/DragPauseDetector.java
deleted file mode 100644
index 6df1aba01..000000000
--- a/quickstep/src/com/android/launcher3/uioverrides/DragPauseDetector.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2017 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.launcher3.uioverrides;
-
-import com.android.launcher3.Alarm;
-import com.android.launcher3.OnAlarmListener;
-
-/**
- * Utility class to detect a pause during a drag.
- */
-public class DragPauseDetector implements OnAlarmListener {
-
- private static final float MAX_VELOCITY_TO_PAUSE = 0.2f;
- private static final long PAUSE_DURATION = 100;
-
- private final Alarm mAlarm;
- private final Runnable mOnPauseCallback;
-
- private boolean mTriggered = false;
- private int mDisabledFlags = 0;
-
- public DragPauseDetector(Runnable onPauseCallback) {
- mOnPauseCallback = onPauseCallback;
-
- mAlarm = new Alarm();
- mAlarm.setOnAlarmListener(this);
- mAlarm.setAlarm(PAUSE_DURATION);
- }
-
- public void onDrag(float velocity) {
- if (mTriggered || !isEnabled()) {
- return;
- }
-
- if (Math.abs(velocity) > MAX_VELOCITY_TO_PAUSE) {
- // Cancel any previous alarm and set a new alarm
- mAlarm.setAlarm(PAUSE_DURATION);
- }
- }
-
- @Override
- public void onAlarm(Alarm alarm) {
- if (!mTriggered && isEnabled()) {
- mTriggered = true;
- mOnPauseCallback.run();
- }
- }
-
- public boolean isTriggered () {
- return mTriggered;
- }
-
- public boolean isEnabled() {
- return mDisabledFlags == 0;
- }
-
- public void addDisabledFlags(int flags) {
- boolean wasEnabled = isEnabled();
- mDisabledFlags |= flags;
- resetAlarm(wasEnabled);
- }
-
- public void clearDisabledFlags(int flags) {
- boolean wasEnabled = isEnabled();
- mDisabledFlags &= ~flags;
- resetAlarm(wasEnabled);
- }
-
- private void resetAlarm(boolean wasEnabled) {
- boolean isEnabled = isEnabled();
- if (wasEnabled == isEnabled) {
- // Nothing has changed
- } if (isEnabled && !mTriggered) {
- mAlarm.setAlarm(PAUSE_DURATION);
- } else if (!isEnabled) {
- mAlarm.cancelAlarm();
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java
deleted file mode 100644
index 97ac3e606..000000000
--- a/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2018 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.launcher3.uioverrides;
-
-import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.touch.SwipeDetector.DIRECTION_NEGATIVE;
-import static com.android.launcher3.touch.SwipeDetector.DIRECTION_POSITIVE;
-import static com.android.launcher3.touch.SwipeDetector.HORIZONTAL;
-import static com.android.launcher3.touch.SwipeDetector.VERTICAL;
-import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
-
-import android.graphics.Rect;
-import android.metrics.LogMaker;
-import android.view.MotionEvent;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.util.VerticalSwipeController;
-import com.android.quickstep.views.RecentsView;
-
-class EventLogTags {
- private EventLogTags() {
- } // don't instantiate
-
- /** 524292 sysui_multi_action (content|4) */
- public static final int SYSUI_MULTI_ACTION = 524292;
-
- public static void writeSysuiMultiAction(Object[] content) {
- android.util.EventLog.writeEvent(SYSUI_MULTI_ACTION, content);
- }
-}
-
-class MetricsLogger {
- private static MetricsLogger sMetricsLogger;
-
- private static MetricsLogger getLogger() {
- if (sMetricsLogger == null) {
- sMetricsLogger = new MetricsLogger();
- }
- return sMetricsLogger;
- }
-
- protected void saveLog(Object[] rep) {
- EventLogTags.writeSysuiMultiAction(rep);
- }
-
- public void write(LogMaker content) {
- if (content.getType() == 0/*MetricsEvent.TYPE_UNKNOWN*/) {
- content.setType(4/*MetricsEvent.TYPE_ACTION*/);
- }
- saveLog(content.serialize());
- }
-}
-
-/**
- * Extension of {@link VerticalSwipeController} to go from NORMAL to OVERVIEW.
- */
-public class EdgeSwipeController extends VerticalSwipeController implements
- OnDeviceProfileChangeListener {
-
- private static final Rect sTempRect = new Rect();
-
- private final MetricsLogger mMetricsLogger = new MetricsLogger();
-
- public EdgeSwipeController(Launcher l) {
- super(l, NORMAL, OVERVIEW, l.getDeviceProfile().isVerticalBarLayout()
- ? HORIZONTAL : VERTICAL);
- l.addOnDeviceProfileChangeListener(this);
- }
-
- @Override
- public void onDeviceProfileChanged(DeviceProfile dp) {
- mDetector.updateDirection(dp.isVerticalBarLayout() ? HORIZONTAL : VERTICAL);
- }
-
- @Override
- protected boolean shouldInterceptTouch(MotionEvent ev) {
- return mLauncher.isInState(NORMAL) && (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
- }
-
- @Override
- protected int getSwipeDirection(MotionEvent ev) {
- return isTransitionFlipped() ? DIRECTION_NEGATIVE : DIRECTION_POSITIVE;
- }
-
- public EdgeSwipeController(Launcher l, LauncherState baseState) {
- super(l, baseState);
- }
-
- @Override
- protected boolean isTransitionFlipped() {
- return mLauncher.getDeviceProfile().isSeascape();
- }
-
- @Override
- protected void onTransitionComplete(boolean wasFling, boolean stateChanged) {
- if (stateChanged && mToState instanceof OverviewState) {
- // Mimic ActivityMetricsLogger.logAppTransitionMultiEvents() logging for
- // "Recents" activity for app transition tests.
- final LogMaker builder = new LogMaker(761/*APP_TRANSITION*/);
- builder.setPackageName("com.android.systemui");
- builder.addTaggedData(871/*FIELD_CLASS_NAME*/,
- "com.android.systemui.recents.RecentsActivity");
- builder.addTaggedData(319/*APP_TRANSITION_DELAY_MS*/,
- 0/* zero time */);
- mMetricsLogger.write(builder);
-
- // Add user event logging for launcher pipeline
- int direction = Direction.UP;
- if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
- direction = Direction.LEFT;
- if (mLauncher.getDeviceProfile().isSeascape()) {
- direction = Direction.RIGHT;
- }
- }
- mLauncher.getUserEventDispatcher().logStateChangeAction(
- wasFling ? Touch.FLING : Touch.SWIPE, direction,
- ContainerType.NAVBAR, ContainerType.WORKSPACE, // src target
- ContainerType.TASKSWITCHER, // dst target
- mLauncher.getWorkspace().getCurrentPage());
- }
- }
-
- @Override
- protected float getShiftRange() {
- return getShiftRange(mLauncher);
- }
-
- public static float getShiftRange(Launcher launcher) {
- RecentsView.getPageRect(launcher.getDeviceProfile(), launcher, sTempRect);
- DragLayer dl = launcher.getDragLayer();
- Rect insets = dl.getInsets();
- DeviceProfile dp = launcher.getDeviceProfile();
-
- if (dp.isVerticalBarLayout()) {
- if (dp.isSeascape()) {
- return insets.left + sTempRect.left;
- } else {
- return dl.getWidth() - sTempRect.right + insets.right;
- }
- } else {
- return dl.getHeight() - sTempRect.bottom + insets.bottom;
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
index 9541d0d05..9e82b2571 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
@@ -41,10 +41,10 @@ public class FastOverviewState extends OverviewState {
}
@Override
- public float getHoseatAlpha(Launcher launcher) {
+ public int getVisibleElements(Launcher launcher) {
if (DEBUG_DIFFERENT_UI) {
- return 0;
+ return NONE;
}
- return super.getHoseatAlpha(launcher);
+ return super.getVisibleElements(launcher);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
new file mode 100644
index 000000000..23add9595
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
@@ -0,0 +1,71 @@
+package com.android.launcher3.uioverrides;
+
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
+
+import android.view.MotionEvent;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.touch.AbstractStateChangeTouchController;
+import com.android.launcher3.touch.SwipeDetector;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.quickstep.util.SysuiEventLogger;
+
+/**
+ * Touch controller for handling edge swipes in landscape/seascape UI
+ */
+public class LandscapeEdgeSwipeController extends AbstractStateChangeTouchController {
+
+ public LandscapeEdgeSwipeController(Launcher l) {
+ super(l, SwipeDetector.HORIZONTAL);
+ }
+
+ @Override
+ protected boolean canInterceptTouch(MotionEvent ev) {
+ if (mCurrentAnimation != null) {
+ // If we are already animating from a previous state, we can intercept.
+ return true;
+ }
+ if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
+ return false;
+ }
+ return mLauncher.isInState(NORMAL) && (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
+ }
+
+ @Override
+ protected int getSwipeDirection(MotionEvent ev) {
+ mFromState = NORMAL;
+ mToState = OVERVIEW;
+ return SwipeDetector.DIRECTION_BOTH;
+ }
+
+ @Override
+ protected float getShiftRange() {
+ return mLauncher.getDragLayer().getWidth();
+ }
+
+ @Override
+ protected float initCurrentAnimation() {
+ float range = getShiftRange();
+ long maxAccuracy = (long) (2 * range);
+ mCurrentAnimation = mLauncher.getStateManager()
+ .createAnimationToNewWorkspace(mToState, maxAccuracy);
+ return (mLauncher.getDeviceProfile().isSeascape() ? 2 : -2) / range;
+ }
+
+ @Override
+ protected int getDirectionForLog() {
+ return mLauncher.getDeviceProfile().isSeascape() ? Direction.RIGHT : Direction.LEFT;
+ }
+
+ @Override
+ protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
+ super.onSwipeInteractionCompleted(targetState, logAction);
+ if (mFromState == NORMAL && targetState == OVERVIEW) {
+ SysuiEventLogger.writeDummyRecentsTransition(0);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/LandscapeStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/LandscapeStatesTouchController.java
new file mode 100644
index 000000000..720b20ac1
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/LandscapeStatesTouchController.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 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.launcher3.uioverrides;
+
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+
+import android.view.MotionEvent;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.quickstep.TouchInteractionService;
+import com.android.quickstep.views.RecentsView;
+
+/**
+ * Touch controller from going from OVERVIEW to ALL_APPS
+ */
+public class LandscapeStatesTouchController extends PortraitStatesTouchController {
+
+ public LandscapeStatesTouchController(Launcher l) {
+ super(l);
+ }
+
+ @Override
+ protected boolean canInterceptTouch(MotionEvent ev) {
+ if (mCurrentAnimation != null) {
+ // If we are already animating from a previous state, we can intercept.
+ return true;
+ }
+ if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
+ return false;
+ }
+ if (mLauncher.isInState(ALL_APPS)) {
+ // In all-apps only listen if the container cannot scroll itself
+ return mLauncher.getAppsView().shouldContainerScroll(ev);
+ } else if (mLauncher.isInState(NORMAL)) {
+ return true;
+ } else if (mLauncher.isInState(OVERVIEW)) {
+ RecentsView rv = mLauncher.getOverviewPanel();
+ return ev.getY() > (rv.getBottom() - rv.getPaddingBottom());
+ } else {
+ return false;
+ }
+ }
+
+ protected LauncherState getTargetState() {
+ if (mLauncher.isInState(ALL_APPS)) {
+ // Should swipe down go to OVERVIEW instead?
+ return TouchInteractionService.isConnected() ?
+ mLauncher.getStateManager().getLastState() : NORMAL;
+ } else {
+ return ALL_APPS;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 09acb1d2b..d123dce5a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -22,6 +22,7 @@ import static com.android.launcher3.states.RotationHelper.REQUEST_ROTATE;
import android.graphics.Rect;
import android.view.View;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Workspace;
@@ -105,4 +106,29 @@ public class OverviewState extends LauncherState {
return new float[] {scale, 0, translationY};
}
+
+ @Override
+ public int getVisibleElements(Launcher launcher) {
+ if (launcher.getDeviceProfile().isVerticalBarLayout()) {
+ // TODO: Remove hotseat from overview
+ return HOTSEAT;
+ } else {
+ return launcher.getAppsView().getFloatingHeaderView().hasVisibleContent()
+ ? ALL_APPS_HEADER : HOTSEAT;
+ }
+ }
+
+ @Override
+ public float getVerticalProgress(Launcher launcher) {
+ if (getVisibleElements(launcher) == HOTSEAT) {
+ return super.getVerticalProgress(launcher);
+ }
+ return 1 - (getDefaultSwipeHeight(launcher)
+ / launcher.getAllAppsController().getShiftRange());
+ }
+
+ public static float getDefaultSwipeHeight(Launcher launcher) {
+ DeviceProfile dp = launcher.getDeviceProfile();
+ return dp.allAppsCellHeightPx - dp.allAppsIconTextSizePx;
+ }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeUpController.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeUpController.java
deleted file mode 100644
index 4fb388613..000000000
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeUpController.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2017 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.launcher3.uioverrides;
-
-import static com.android.launcher3.LauncherState.OVERVIEW;
-
-import android.view.MotionEvent;
-
-import com.android.launcher3.Launcher;
-import com.android.launcher3.touch.SwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.util.VerticalSwipeController;
-
-/**
- * Extension of {@link VerticalSwipeController} which allows swipe up from OVERVIEW to ALL_APPS
- * Note that the swipe down is handled by {@link TwoStepSwipeController}.
- */
-public class OverviewSwipeUpController extends VerticalSwipeController {
-
- public OverviewSwipeUpController(Launcher l) {
- super(l, OVERVIEW);
- }
-
- @Override
- protected boolean shouldInterceptTouch(MotionEvent ev) {
- if (!mLauncher.isInState(OVERVIEW)) {
- return false;
- }
- if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
- return ev.getY() >
- mLauncher.getDragLayer().getHeight() * OVERVIEW.getVerticalProgress(mLauncher);
- } else {
- return mLauncher.getDragLayer().isEventOverHotseat(ev);
- }
- }
-
- @Override
- protected int getSwipeDirection(MotionEvent ev) {
- return SwipeDetector.DIRECTION_POSITIVE;
- }
-
- @Override
- protected void onTransitionComplete(boolean wasFling, boolean stateChanged) {
- if (stateChanged) {
- // Transition complete. log the action
- mLauncher.getUserEventDispatcher().logStateChangeAction(
- wasFling ? Touch.FLING : Touch.SWIPE,
- Direction.UP,
- ContainerType.HOTSEAT,
- ContainerType.TASKSWITCHER,
- ContainerType.ALLAPPS,
- mLauncher.getWorkspace().getCurrentPage());
- }
-
- }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
new file mode 100644
index 000000000..9f648edd1
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2018 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.launcher3.uioverrides;
+
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+
+import android.view.MotionEvent;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.touch.SwipeDetector;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.touch.AbstractStateChangeTouchController;
+import com.android.quickstep.TouchInteractionService;
+import com.android.quickstep.util.SysuiEventLogger;
+
+/**
+ * Touch controller for handling various state transitions in portrait UI.
+ */
+public class PortraitStatesTouchController extends AbstractStateChangeTouchController {
+
+ public PortraitStatesTouchController(Launcher l) {
+ super(l, SwipeDetector.VERTICAL);
+ }
+
+ @Override
+ protected boolean canInterceptTouch(MotionEvent ev) {
+ if (mCurrentAnimation != null) {
+ // If we are already animating from a previous state, we can intercept.
+ return true;
+ }
+ if (mLauncher.isInState(ALL_APPS)) {
+ // In all-apps only listen if the container cannot scroll itself
+ if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
+ return false;
+ }
+ } else {
+ // For all other states, only listen if the event originated below the hotseat height
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+ int hotseatHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
+ if (ev.getY() < (mLauncher.getDragLayer().getHeight() - hotseatHeight)) {
+ return false;
+ }
+ }
+ if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected int getSwipeDirection(MotionEvent ev) {
+ final int directionsToDetectScroll;
+ if (mLauncher.isInState(ALL_APPS)) {
+ directionsToDetectScroll = SwipeDetector.DIRECTION_NEGATIVE;
+ mStartContainerType = ContainerType.ALLAPPS;
+ } else if (mLauncher.isInState(NORMAL)) {
+ directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
+ mStartContainerType = ContainerType.HOTSEAT;
+ } else if (mLauncher.isInState(OVERVIEW)) {
+ directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
+ mStartContainerType = ContainerType.TASKSWITCHER;
+ } else {
+ return 0;
+ }
+ mFromState = mLauncher.getStateManager().getState();
+ mToState = getTargetState();
+ if (mFromState == mToState) {
+ return 0;
+ }
+ return directionsToDetectScroll;
+ }
+
+ protected LauncherState getTargetState() {
+ if (mLauncher.isInState(ALL_APPS)) {
+ // Should swipe down go to OVERVIEW instead?
+ return TouchInteractionService.isConnected() ?
+ mLauncher.getStateManager().getLastState() : NORMAL;
+ } else if (mLauncher.isInState(OVERVIEW)) {
+ return ALL_APPS;
+ } else {
+ return TouchInteractionService.isConnected() ? OVERVIEW : ALL_APPS;
+ }
+ }
+
+ @Override
+ protected float initCurrentAnimation() {
+ float range = getShiftRange();
+ long maxAccuracy = (long) (2 * range);
+ mCurrentAnimation = mLauncher.getStateManager()
+ .createAnimationToNewWorkspace(mToState, maxAccuracy);
+
+ float startVerticalShift = mFromState.getVerticalProgress(mLauncher) * range;
+ float endVerticalShift = mToState.getVerticalProgress(mLauncher) * range;
+
+ float totalShift = endVerticalShift - startVerticalShift;
+ if (totalShift == 0) {
+ totalShift = Math.signum(mFromState.ordinal - mToState.ordinal)
+ * OverviewState.getDefaultSwipeHeight(mLauncher);
+ }
+ return 1 / totalShift;
+ }
+
+ @Override
+ protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
+ super.onSwipeInteractionCompleted(targetState, logAction);
+ if (mFromState == NORMAL && targetState == OVERVIEW) {
+ SysuiEventLogger.writeDummyRecentsTransition(0);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TaggedAnimatorSetBuilder.java b/quickstep/src/com/android/launcher3/uioverrides/TaggedAnimatorSetBuilder.java
deleted file mode 100644
index 651a75354..000000000
--- a/quickstep/src/com/android/launcher3/uioverrides/TaggedAnimatorSetBuilder.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2017 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.launcher3.uioverrides;
-
-import android.animation.Animator;
-import android.util.SparseArray;
-
-import com.android.launcher3.anim.AnimatorSetBuilder;
-
-import java.util.Collections;
-import java.util.List;
-
-public class TaggedAnimatorSetBuilder extends AnimatorSetBuilder {
-
- /**
- * Map of the index in {@link #mAnims} to tag. All the animations in {@link #mAnims} starting
- * from this index correspond to the tag (until a new tag is specified for an index)
- */
- private final SparseArray<Object> mTags = new SparseArray<>();
-
- @Override
- public void startTag(Object obj) {
- mTags.put(mAnims.size(), obj);
- }
-
- public List<Animator> getAnimationsForTag(Object tag) {
- int startIndex = mTags.indexOfValue(tag);
- if (startIndex < 0) {
- return Collections.emptyList();
- }
- int startPos = mTags.keyAt(startIndex);
-
- int endIndex = startIndex + 1;
- int endPos = endIndex >= mTags.size() ? mAnims.size() : mTags.keyAt(endIndex);
-
- return mAnims.subList(startPos, endPos);
- }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
index 8b738091a..d11547de8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.uioverrides;
-import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
@@ -30,24 +28,21 @@ import android.view.View;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.touch.SwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.PendingAnimation;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
/**
- * Touch controller for swipe interaction in Overview state
+ * Touch controller for handling task view card swipes
*/
-public class OverviewSwipeController extends AnimatorListenerAdapter
+public class TaskViewTouchController extends AnimatorListenerAdapter
implements TouchController, SwipeDetector.Listener {
private static final String TAG = "OverviewSwipeController";
@@ -68,16 +63,14 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
private boolean mCurrentAnimationIsGoingUp;
private boolean mNoIntercept;
- private boolean mSwipeDownEnabled;
private float mDisplacementShift;
private float mProgressMultiplier;
private float mEndDisplacement;
- private int mStartingTarget;
private TaskView mTaskBeingDragged;
- public OverviewSwipeController(Launcher launcher) {
+ public TaskViewTouchController(Launcher launcher) {
mLauncher = launcher;
mRecentsView = launcher.getOverviewPanel();
mDetector = new SwipeDetector(launcher, this, SwipeDetector.VERTICAL);
@@ -94,15 +87,6 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
return mLauncher.isInState(OVERVIEW);
}
- private boolean isEventOverHotseat(MotionEvent ev) {
- if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
- return ev.getY() >
- mLauncher.getDragLayer().getHeight() * OVERVIEW.getVerticalProgress(mLauncher);
- } else {
- return mLauncher.getDragLayer().isEventOverHotseat(ev);
- }
- }
-
@Override
public void onAnimationCancel(Animator animation) {
if (mCurrentAnimation != null && animation == mCurrentAnimation.getTarget()) {
@@ -129,22 +113,14 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
ignoreSlopWhenSettling = true;
} else {
mTaskBeingDragged = null;
- mSwipeDownEnabled = true;
View view = mRecentsView.getChildAt(mRecentsView.getCurrentPage());
if (view instanceof TaskView && mLauncher.getDragLayer().isEventOverView(view, ev)) {
// The tile can be dragged down to open the task.
mTaskBeingDragged = (TaskView) view;
directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
- mStartingTarget = LauncherLogProto.ItemType.TASK;
- } else if (isEventOverHotseat(ev)) {
- // The hotseat is being dragged
- directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
- mSwipeDownEnabled = false;
- mStartingTarget = ContainerType.HOTSEAT;
} else {
mNoIntercept = true;
- mStartingTarget = ContainerType.WORKSPACE;
return false;
}
}
@@ -167,9 +143,6 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
}
private void reInitAnimationController(boolean goingUp) {
- if (!goingUp && !mSwipeDownEnabled) {
- goingUp = true;
- }
if (mCurrentAnimation != null && mCurrentAnimationIsGoingUp == goingUp) {
// No need to init
return;
@@ -187,31 +160,20 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
long maxDuration = (long) (2 * range);
DragLayer dl = mLauncher.getDragLayer();
- if (mTaskBeingDragged == null) {
- // User is either going to all apps or home
- mCurrentAnimation = mLauncher.getStateManager()
- .createAnimationToNewWorkspace(goingUp ? ALL_APPS : NORMAL, maxDuration);
- if (goingUp) {
- mEndDisplacement = -range;
- } else {
- mEndDisplacement = EdgeSwipeController.getShiftRange(mLauncher);
- }
+ if (goingUp) {
+ mPendingAnimation = mRecentsView.createTaskDismissAnimation(mTaskBeingDragged,
+ true /* animateTaskView */, true /* removeTask */, maxDuration);
+ mCurrentAnimation = AnimatorPlaybackController
+ .wrap(mPendingAnimation.anim, maxDuration);
+ mEndDisplacement = -mTaskBeingDragged.getHeight();
} else {
- if (goingUp) {
- mPendingAnimation = mRecentsView.createTaskDismissAnimation(mTaskBeingDragged,
- true /* animateTaskView */, true /* removeTask */, maxDuration);
- mCurrentAnimation = AnimatorPlaybackController
- .wrap(mPendingAnimation.anim, maxDuration);
- mEndDisplacement = -mTaskBeingDragged.getHeight();
- } else {
- AnimatorSet anim = new AnimatorSet();
- // TODO: Setup a zoom animation
- mCurrentAnimation = AnimatorPlaybackController.wrap(anim, maxDuration);
+ AnimatorSet anim = new AnimatorSet();
+ // TODO: Setup a zoom animation
+ mCurrentAnimation = AnimatorPlaybackController.wrap(anim, maxDuration);
- mTempCords[1] = mTaskBeingDragged.getHeight();
- dl.getDescendantCoordRelativeToSelf(mTaskBeingDragged, mTempCords);
- mEndDisplacement = dl.getHeight() - mTempCords[1];
- }
+ mTempCords[1] = mTaskBeingDragged.getHeight();
+ dl.getDescendantCoordRelativeToSelf(mTaskBeingDragged, mTempCords);
+ mEndDisplacement = dl.getHeight() - mTempCords[1];
}
mCurrentAnimation.getTarget().addListener(this);
@@ -249,9 +211,7 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
if (fling) {
logAction = Touch.FLING;
boolean goingUp = velocity < 0;
- if (!goingUp && !mSwipeDownEnabled) {
- goingToEnd = false;
- } else if (goingUp != mCurrentAnimationIsGoingUp) {
+ if (goingUp != mCurrentAnimationIsGoingUp) {
// In case the fling is in opposite direction, make sure if is close enough
// from the start position
if (mCurrentAnimation.getProgressFraction()
@@ -277,7 +237,6 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
float nextFrameProgress = Utilities.boundToRange(
progress + velocity * SINGLE_FRAME_MS / Math.abs(mEndDisplacement), 0f, 1f);
-
mCurrentAnimation.setEndAction(() -> onCurrentAnimationEnd(goingToEnd, logAction));
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
@@ -292,25 +251,13 @@ public class OverviewSwipeController extends AnimatorListenerAdapter
mPendingAnimation.finish(wasSuccess);
mPendingAnimation = null;
}
- if (mTaskBeingDragged == null) {
- LauncherState state = wasSuccess ?
- (mCurrentAnimationIsGoingUp ? ALL_APPS : NORMAL) : OVERVIEW;
- mLauncher.getStateManager().goToState(state, false);
-
- } else if (wasSuccess) {
+ if (wasSuccess) {
if (!mCurrentAnimationIsGoingUp) {
mTaskBeingDragged.launchTask(false);
mLauncher.getUserEventDispatcher().logTaskLaunch(logAction,
Direction.DOWN, mTaskBeingDragged.getTask().getTopComponent());
}
}
- if (mTaskBeingDragged == null || (wasSuccess && mCurrentAnimationIsGoingUp)) {
- mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
- mCurrentAnimationIsGoingUp ? Direction.UP : Direction.DOWN,
- mStartingTarget, ContainerType.TASKSWITCHER,
- mLauncher.getStateManager().getState().containerType,
- mRecentsView.getCurrentPage());
- }
mDetector.finishedScrolling();
mTaskBeingDragged = null;
mCurrentAnimation = null;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java
deleted file mode 100644
index c8d75dc6f..000000000
--- a/quickstep/src/com/android/launcher3/uioverrides/TwoStepSwipeController.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright (C) 2017 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.launcher3.uioverrides;
-
-import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
-import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager;
-import com.android.launcher3.LauncherStateManager.AnimationConfig;
-import com.android.launcher3.LauncherStateManager.StateHandler;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.AnimationSuccessListener;
-import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.anim.AnimatorSetBuilder;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.touch.SwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.util.FloatRange;
-import com.android.launcher3.util.TouchController;
-import com.android.quickstep.TouchInteractionService;
-
-/**
- * Handles vertical touch gesture on the DragLayer
- */
-public class TwoStepSwipeController extends AnimatorListenerAdapter
- implements TouchController, SwipeDetector.Listener {
-
- private static final String TAG = "TwoStepSwipeController";
-
- private static final float RECATCH_REJECTION_FRACTION = .0875f;
- private static final int SINGLE_FRAME_MS = 16;
- private static final long QUICK_SNAP_TO_OVERVIEW_DURATION = 250;
-
- // Progress after which the transition is assumed to be a success in case user does not fling
- private static final float SUCCESS_TRANSITION_PROGRESS = 0.5f;
-
- /**
- * Index of the vertical swipe handles in {@link LauncherStateManager#getStateHandlers()}.
- */
- private static final int SWIPE_HANDLER_INDEX = 0;
-
- /**
- * Index of various UI handlers in {@link LauncherStateManager#getStateHandlers()} not related
- * to vertical swipe.
- */
- private static final int OTHER_HANDLERS_START_INDEX = SWIPE_HANDLER_INDEX + 1;
-
- // Swipe progress range (when starting from NORMAL state) where OVERVIEW state is allowed
- private static final float MIN_PROGRESS_TO_OVERVIEW = 0.1f;
- private static final float MAX_PROGRESS_TO_OVERVIEW = 0.4f;
-
- private static final int FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE = 1 << 0;
- private static final int FLAG_OVERVIEW_DISABLED_FLING = 1 << 1;
- private static final int FLAG_OVERVIEW_DISABLED_CANCEL_STATE = 1 << 2;
- private static final int FLAG_OVERVIEW_DISABLED = 1 << 4;
- private static final int FLAG_DISABLED_TWO_TARGETS = 1 << 5;
- private static final int FLAG_DISABLED_BACK_TARGET = 1 << 6;
-
- private final Launcher mLauncher;
- private final SwipeDetector mDetector;
-
- private boolean mNoIntercept;
- private int mStartContainerType;
-
- private DragPauseDetector mDragPauseDetector;
- private FloatRange mOverviewProgressRange;
- private TaggedAnimatorSetBuilder mTaggedAnimatorSetBuilder;
- private AnimatorSet mQuickOverviewAnimation;
- private boolean mAnimatingToOverview;
- private CroppedAnimationController mCroppedAnimationController;
-
- private AnimatorPlaybackController mCurrentAnimation;
- private LauncherState mFromState;
- private LauncherState mToState;
-
- private float mStartProgress;
- // Ratio of transition process [0, 1] to drag displacement (px)
- private float mProgressMultiplier;
-
- public TwoStepSwipeController(Launcher l) {
- mLauncher = l;
- mDetector = new SwipeDetector(l, this, SwipeDetector.VERTICAL);
- }
-
- private boolean canInterceptTouch(MotionEvent ev) {
- if (mCurrentAnimation != null) {
- // If we are already animating from a previous state, we can intercept.
- return true;
- }
- if (mLauncher.isInState(NORMAL)) {
- if ((ev.getEdgeFlags() & EDGE_NAV_BAR) != 0 &&
- !mLauncher.getDeviceProfile().isVerticalBarLayout()) {
- // On normal swipes ignore edge swipes
- return false;
- }
- } else if (mLauncher.isInState(ALL_APPS)) {
- if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
- return false;
- }
- } else {
- // Don't listen for the swipe gesture if we are already in some other state.
- return false;
- }
- if (mAnimatingToOverview) {
- return false;
- }
- if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- if (mCurrentAnimation != null && animation == mCurrentAnimation.getOriginalTarget()) {
- Log.e(TAG, "Who dare cancel the animation when I am in control", new Exception());
- clearState();
- }
- }
-
- @Override
- public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mNoIntercept = !canInterceptTouch(ev);
- if (mNoIntercept) {
- return false;
- }
-
- // Now figure out which direction scroll events the controller will start
- // calling the callbacks.
- final int directionsToDetectScroll;
- boolean ignoreSlopWhenSettling = false;
-
- if (mCurrentAnimation != null) {
- if (mCurrentAnimation.getProgressFraction() > 1 - RECATCH_REJECTION_FRACTION) {
- directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
- } else if (mCurrentAnimation.getProgressFraction() < RECATCH_REJECTION_FRACTION ) {
- directionsToDetectScroll = SwipeDetector.DIRECTION_NEGATIVE;
- } else {
- directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
- ignoreSlopWhenSettling = true;
- }
- } else {
- if (mLauncher.isInState(ALL_APPS)) {
- directionsToDetectScroll = SwipeDetector.DIRECTION_NEGATIVE;
- mStartContainerType = ContainerType.ALLAPPS;
- } else {
- directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
- mStartContainerType = mLauncher.getDragLayer().isEventOverHotseat(ev) ?
- ContainerType.HOTSEAT : ContainerType.WORKSPACE;
- }
- }
-
- mDetector.setDetectableScrollConditions(
- directionsToDetectScroll, ignoreSlopWhenSettling);
- }
-
- if (mNoIntercept) {
- return false;
- }
-
- onControllerTouchEvent(ev);
- return mDetector.isDraggingOrSettling();
- }
-
- @Override
- public boolean onControllerTouchEvent(MotionEvent ev) {
- return mDetector.onTouchEvent(ev);
- }
-
- @Override
- public void onDragStart(boolean start) {
- if (mCurrentAnimation == null) {
- float range = getShiftRange();
- long maxAccuracy = (long) (2 * range);
-
- mDragPauseDetector = new DragPauseDetector(this::onDragPauseDetected);
- mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE);
- if (FeatureFlags.ENABLE_TWO_SWIPE_TARGETS) {
- mDragPauseDetector.addDisabledFlags(FLAG_DISABLED_TWO_TARGETS);
- }
-
- mOverviewProgressRange = new FloatRange();
- mOverviewProgressRange.start = mLauncher.isInState(NORMAL)
- ? MIN_PROGRESS_TO_OVERVIEW
- : 1 - MAX_PROGRESS_TO_OVERVIEW;
- mOverviewProgressRange.end = mOverviewProgressRange.start
- + MAX_PROGRESS_TO_OVERVIEW - MIN_PROGRESS_TO_OVERVIEW;
-
- // Build current animation
- mFromState = mLauncher.getStateManager().getState();
- mToState = mLauncher.isInState(ALL_APPS) ? NORMAL : ALL_APPS;
-
- if (mToState == NORMAL && mLauncher.getStateManager().getLastState() == OVERVIEW) {
- mToState = OVERVIEW;
- mDragPauseDetector.addDisabledFlags(FLAG_DISABLED_BACK_TARGET);
- }
-
- mTaggedAnimatorSetBuilder = new TaggedAnimatorSetBuilder();
- mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace(
- mToState, mTaggedAnimatorSetBuilder, maxAccuracy);
-
- if (!TouchInteractionService.isConnected()) {
- mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED);
- }
-
- mCurrentAnimation.getTarget().addListener(this);
- mStartProgress = 0;
- mProgressMultiplier = (mLauncher.isInState(ALL_APPS) ? 1 : -1) / range;
- mCurrentAnimation.dispatchOnStart();
- } else {
- mCurrentAnimation.pause();
- mStartProgress = mCurrentAnimation.getProgressFraction();
-
- mDragPauseDetector.clearDisabledFlags(FLAG_OVERVIEW_DISABLED_FLING);
- updatePauseDetectorRangeFlag();
- }
- }
-
- private float getShiftRange() {
- return mLauncher.getAllAppsController().getShiftRange();
- }
-
- @Override
- public boolean onDrag(float displacement, float velocity) {
- float deltaProgress = mProgressMultiplier * displacement;
- mCurrentAnimation.setPlayFraction(deltaProgress + mStartProgress);
-
- updatePauseDetectorRangeFlag();
- mDragPauseDetector.onDrag(velocity);
-
- return true;
- }
-
- private void updatePauseDetectorRangeFlag() {
- if (mOverviewProgressRange.contains(mCurrentAnimation.getProgressFraction())) {
- mDragPauseDetector.clearDisabledFlags(FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE);
- } else {
- mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_OUT_OF_RANGE);
- }
- }
-
- @Override
- public void onDragEnd(float velocity, boolean fling) {
- mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_FLING);
-
- final int logAction;
- LauncherState targetState;
- final float progress = mCurrentAnimation.getProgressFraction();
-
- if (fling) {
- logAction = Touch.FLING;
- targetState = velocity < 0 ? ALL_APPS : mLauncher.getStateManager().getLastState();
- // snap to top or bottom using the release velocity
- } else {
- logAction = Touch.SWIPE;
- targetState = (progress > SUCCESS_TRANSITION_PROGRESS) ? mToState : mFromState;
- }
-
- float endProgress;
-
- if (mDragPauseDetector.isTriggered() && targetState == NORMAL) {
- targetState = OVERVIEW;
- endProgress = OVERVIEW.getVerticalProgress(mLauncher);
- if (mFromState == NORMAL) {
- endProgress = 1 - endProgress;
- }
- } else if (targetState == mToState) {
- endProgress = 1;
- } else {
- endProgress = 0;
- }
-
- LauncherState targetStateFinal = targetState;
- mCurrentAnimation.setEndAction(() ->
- onSwipeInteractionCompleted(targetStateFinal, logAction));
-
- float nextFrameProgress = Utilities.boundToRange(
- progress + velocity * SINGLE_FRAME_MS / getShiftRange(), 0f, 1f);
-
- ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
- anim.setFloatValues(nextFrameProgress, endProgress);
- anim.setDuration(
- SwipeDetector.calculateDuration(velocity, Math.abs(endProgress - progress)));
- anim.setInterpolator(scrollInterpolatorForVelocity(velocity));
- anim.start();
- }
-
- private void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
- if (targetState != mFromState) {
- // Transition complete. log the action
- mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
- mToState == ALL_APPS ? Direction.UP : Direction.DOWN,
- mStartContainerType,
- mFromState.containerType,
- mToState.containerType,
- mLauncher.getWorkspace().getCurrentPage());
- }
- clearState();
-
- // TODO: mQuickOverviewAnimation might still be running in which changing a state instantly
- // may cause a jump. Animate the state change with a short duration in this case?
- mLauncher.getStateManager().goToState(targetState, false /* animated */);
- }
-
- private void onDragPauseDetected() {
- final ValueAnimator twoStepAnimator = ValueAnimator.ofFloat(0, 1);
- twoStepAnimator.setDuration(mCurrentAnimation.getDuration());
- StateHandler[] handlers = mLauncher.getStateManager().getStateHandlers();
-
- // Change the current animation to only play the vertical handle
- AnimatorSet anim = new AnimatorSet();
- anim.playTogether(mTaggedAnimatorSetBuilder.getAnimationsForTag(
- handlers[SWIPE_HANDLER_INDEX]));
- anim.play(twoStepAnimator);
- mCurrentAnimation = mCurrentAnimation.cloneFor(anim);
-
- AnimatorSetBuilder builder = new AnimatorSetBuilder();
- AnimationConfig config = new AnimationConfig();
- config.duration = QUICK_SNAP_TO_OVERVIEW_DURATION;
- for (int i = OTHER_HANDLERS_START_INDEX; i < handlers.length; i++) {
- handlers[i].setStateWithAnimation(OVERVIEW, builder, config);
- }
- mQuickOverviewAnimation = builder.build();
- mQuickOverviewAnimation.addListener(new AnimationSuccessListener() {
- @Override
- public void onAnimationSuccess(Animator animator) {
- onQuickOverviewAnimationComplete(twoStepAnimator);
- }
- });
- mQuickOverviewAnimation.start();
- }
-
- private void onQuickOverviewAnimationComplete(ValueAnimator animator) {
- if (mAnimatingToOverview) {
- return;
- }
-
- // For the remainder to the interaction, the user can either go to the ALL_APPS state or
- // the OVERVIEW state.
- // The remaining state handlers are on the OVERVIEW state. Create one animation towards the
- // ALL_APPS state and only call it when the user moved above the current range.
- AnimationConfig config = new AnimationConfig();
- config.duration = (long) (2 * getShiftRange());
- config.userControlled = true;
-
- AnimatorSetBuilder builderToAllAppsState = new AnimatorSetBuilder();
- StateHandler[] handlers = mLauncher.getStateManager().getStateHandlers();
- for (int i = OTHER_HANDLERS_START_INDEX; i < handlers.length; i++) {
- handlers[i].setStateWithAnimation(ALL_APPS, builderToAllAppsState, config);
- }
-
- mCroppedAnimationController = new CroppedAnimationController(
- AnimatorPlaybackController.wrap(builderToAllAppsState.build(), config.duration),
- new FloatRange(animator.getAnimatedFraction(), mToState == ALL_APPS ? 1 : 0));
- animator.addUpdateListener(mCroppedAnimationController);
- }
-
- private void clearState() {
- mCurrentAnimation = null;
- mTaggedAnimatorSetBuilder = null;
- if (mDragPauseDetector != null) {
- mDragPauseDetector.addDisabledFlags(FLAG_OVERVIEW_DISABLED_CANCEL_STATE);
- }
- mDragPauseDetector = null;
-
- if (mQuickOverviewAnimation != null) {
- mQuickOverviewAnimation.cancel();
- mQuickOverviewAnimation = null;
- }
- mCroppedAnimationController = null;
- mAnimatingToOverview = false;
-
- mDetector.finishedScrolling();
- }
-
- /**
- * {@link AnimatorUpdateListener} which controls another animation for a fraction of range
- */
- private static class CroppedAnimationController implements AnimatorUpdateListener {
-
- private final AnimatorPlaybackController mTarget;
- private final FloatRange mRange;
-
- CroppedAnimationController(AnimatorPlaybackController target, FloatRange range) {
- mTarget = target;
- mRange = range;
- }
-
-
- @Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- float fraction = valueAnimator.getAnimatedFraction();
-
- if (mRange.start < mRange.end) {
- if (fraction <= mRange.start) {
- mTarget.setPlayFraction(0);
- } else if (fraction >= mRange.end) {
- mTarget.setPlayFraction(1);
- } else {
- mTarget.setPlayFraction((fraction - mRange.start) / (mRange.end - mRange.start));
- }
- } else if (mRange.start > mRange.end) {
- if (fraction >= mRange.start) {
- mTarget.setPlayFraction(0);
- } else if (fraction <= mRange.end) {
- mTarget.setPlayFraction(1);
- } else {
- mTarget.setPlayFraction((fraction - mRange.start) / (mRange.end - mRange.start));
- }
- } else {
- // mRange.start == mRange.end
- mTarget.setPlayFraction(0);
- }
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 637ce60a2..49792ac25 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -25,7 +25,6 @@ import android.view.View.AccessibilityDelegate;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherStateManager.StateHandler;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.OverviewInteractionState;
@@ -35,17 +34,17 @@ import com.android.quickstep.views.RecentsView;
public class UiFactory {
public static TouchController[] createTouchControllers(Launcher launcher) {
- if (FeatureFlags.ENABLE_TWO_SWIPE_TARGETS) {
+ if (launcher.getDeviceProfile().isVerticalBarLayout()) {
return new TouchController[] {
launcher.getDragController(),
- new EdgeSwipeController(launcher),
- new TwoStepSwipeController(launcher),
- new OverviewSwipeController(launcher)};
+ new LandscapeStatesTouchController(launcher),
+ new LandscapeEdgeSwipeController(launcher),
+ new TaskViewTouchController(launcher)};
} else {
return new TouchController[] {
launcher.getDragController(),
- new TwoStepSwipeController(launcher),
- new OverviewSwipeController(launcher)};
+ new PortraitStatesTouchController(launcher),
+ new TaskViewTouchController(launcher)};
}
}
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index a9da4f916..b43352a04 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -143,10 +143,13 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
activity.getStateManager().setRestState(startState);
if (!activityVisible) {
+ // Since the launcher is not visible, we can safely reset the scroll position.
+ // This ensures then the next swipe up to all-apps starts from scroll 0.
+ activity.getAppsView().reset(false /* animate */);
activity.getStateManager().goToState(OVERVIEW, false);
// Optimization, hide the all apps view to prevent layout while initializing
- activity.getAppsView().setVisibility(View.GONE);
+ activity.getAppsView().getContentView().setVisibility(View.GONE);
}
}
@@ -160,20 +163,21 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
@Override
public AnimatorPlaybackController createControllerForHiddenActivity(
Launcher activity, int transitionLength) {
- float startProgress;
AllAppsTransitionController controller = activity.getAllAppsController();
-
+ AnimatorSet anim = new AnimatorSet();
if (activity.getDeviceProfile().isVerticalBarLayout()) {
- startProgress = 1;
+ // TODO:
} else {
float scrollRange = Math.max(controller.getShiftRange(), 1);
- startProgress = (transitionLength / scrollRange) + 1;
+ float progressDelta = (transitionLength / scrollRange);
+
+ float endProgress = OVERVIEW.getVerticalProgress(activity);
+ float startProgress = endProgress + progressDelta;
+ ObjectAnimator shiftAnim = ObjectAnimator.ofFloat(
+ controller, ALL_APPS_PROGRESS, startProgress, endProgress);
+ shiftAnim.setInterpolator(LINEAR);
+ anim.play(shiftAnim);
}
- AnimatorSet anim = new AnimatorSet();
- ObjectAnimator shiftAnim = ObjectAnimator.ofFloat(controller, ALL_APPS_PROGRESS,
- startProgress, OVERVIEW.getVerticalProgress(activity));
- shiftAnim.setInterpolator(LINEAR);
- anim.play(shiftAnim);
// TODO: Link this animation to state animation, so that it is cancelled
// automatically on state change
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 96cd4a024..2d2a483b5 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -35,7 +35,6 @@ import android.graphics.Matrix.ScaleToFit;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.metrics.LogMaker;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -64,6 +63,7 @@ import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import com.android.quickstep.ActivityControlHelper.LayoutListener;
import com.android.quickstep.TouchConsumer.InteractionType;
+import com.android.quickstep.util.SysuiEventLogger;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -77,40 +77,6 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
import java.util.StringJoiner;
-class EventLogTags {
- private EventLogTags() {
- } // don't instantiate
-
- /** 524292 sysui_multi_action (content|4) */
- public static final int SYSUI_MULTI_ACTION = 524292;
-
- public static void writeSysuiMultiAction(Object[] content) {
- android.util.EventLog.writeEvent(SYSUI_MULTI_ACTION, content);
- }
-}
-
-class MetricsLogger {
- private static MetricsLogger sMetricsLogger;
-
- private static MetricsLogger getLogger() {
- if (sMetricsLogger == null) {
- sMetricsLogger = new MetricsLogger();
- }
- return sMetricsLogger;
- }
-
- protected void saveLog(Object[] rep) {
- EventLogTags.writeSysuiMultiAction(rep);
- }
-
- public void write(LogMaker content) {
- if (content.getType() == 0/*MetricsEvent.TYPE_UNKNOWN*/) {
- content.setType(4/*MetricsEvent.TYPE_ACTION*/);
- }
- saveLog(content.serialize());
- }
-}
-
@TargetApi(Build.VERSION_CODES.O)
public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
@@ -229,7 +195,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private Matrix mTmpMatrix = new Matrix();
private final long mTouchTimeMs;
private long mLauncherFrameDrawnTime;
- private final MetricsLogger mMetricsLogger = new MetricsLogger();
WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs,
ActivityControlHelper<T> controller) {
@@ -453,15 +418,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
onLauncherLayoutChanged();
final long transitionDelay = mLauncherFrameDrawnTime - mTouchTimeMs;
- // Mimic ActivityMetricsLogger.logAppTransitionMultiEvents() logging for
- // "Recents" activity for app transition tests for the app-to-recents case.
- final LogMaker builder = new LogMaker(761/*APP_TRANSITION*/);
- builder.setPackageName("com.android.systemui");
- builder.addTaggedData(871/*FIELD_CLASS_NAME*/,
- "com.android.systemui.recents.RecentsActivity");
- builder.addTaggedData(319/*APP_TRANSITION_DELAY_MS*/,
- transitionDelay);
- mMetricsLogger.write(builder);
+ SysuiEventLogger.writeDummyRecentsTransition(transitionDelay);
+
if (LatencyTrackerCompat.isEnabled(mContext)) {
LatencyTrackerCompat.logToggleRecents((int) transitionDelay);
}
diff --git a/quickstep/src/com/android/quickstep/util/SysuiEventLogger.java b/quickstep/src/com/android/quickstep/util/SysuiEventLogger.java
new file mode 100644
index 000000000..d474ded90
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/SysuiEventLogger.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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.quickstep.util;
+
+import android.metrics.LogMaker;
+import android.util.EventLog;
+
+/**
+ * Utility class for writing logs on behalf of systemUI
+ */
+public class SysuiEventLogger {
+
+ /** 524292 sysui_multi_action (content|4) */
+ public static final int SYSUI_MULTI_ACTION = 524292;
+
+ private static void write(LogMaker content) {
+ if (content.getType() == 0/*MetricsEvent.TYPE_UNKNOWN*/) {
+ content.setType(4/*MetricsEvent.TYPE_ACTION*/);
+ }
+ EventLog.writeEvent(SYSUI_MULTI_ACTION, content.serialize());
+ }
+
+ public static void writeDummyRecentsTransition(long transitionDelay) {
+ // Mimic ActivityMetricsLogger.logAppTransitionMultiEvents() logging for
+ // "Recents" activity for app transition tests for the app-to-recents case.
+ final LogMaker builder = new LogMaker(761/*APP_TRANSITION*/);
+ builder.setPackageName("com.android.systemui");
+ builder.addTaggedData(871/*FIELD_CLASS_NAME*/,
+ "com.android.systemui.recents.RecentsActivity");
+ builder.addTaggedData(319/*APP_TRANSITION_DELAY_MS*/,
+ transitionDelay);
+ write(builder);
+ }
+}