Merge "Disabling OverviewActionsView buttons while scrolling or clear all shown." into ub-launcher3-rvc-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 036fb02..cac2d8f 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -26,6 +26,7 @@
Task task = 2;
Shortcut shortcut = 3;
Widget widget = 4;
+ FolderIcon folder_icon = 9;
}
// When used for launch event, stores the global predictive rank
optional int32 rank = 5;
@@ -92,6 +93,11 @@
optional int32 index = 3;
}
+// Represents folder in a closed state.
+message FolderIcon {
+ optional int32 cardinality = 1;
+}
+
//////////////////////////////////////////////
// Containers
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index a515070..c037e44 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -16,39 +16,24 @@
package com.android.launcher3;
-import static com.android.launcher3.LauncherState.BACKGROUND_APP;
-import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
-import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
import static com.android.quickstep.TaskViewUtils.getRecentsWindowAnimator;
-import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.LauncherState.ScaleAndTranslation;
-import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.anim.SpringAnimationBuilder;
-import com.android.launcher3.states.StateAnimationConfig;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -59,13 +44,6 @@
*/
public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransitionManagerImpl {
- public static final int INDEX_SHELF_ANIM = 0;
- public static final int INDEX_RECENTS_FADE_ANIM = 1;
- public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = 2;
- public static final int INDEX_PAUSE_TO_OVERVIEW_ANIM = 3;
-
- public static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300;
-
public LauncherAppTransitionManagerImpl(Context context) {
super(context);
}
@@ -151,77 +129,4 @@
mLauncher.getStateManager().reapplyState();
};
}
-
- @Override
- public int getStateElementAnimationsCount() {
- return 4;
- }
-
- @Override
- public Animator createStateElementAnimation(int index, float... values) {
- switch (index) {
- case INDEX_SHELF_ANIM: {
- AllAppsTransitionController aatc = mLauncher.getAllAppsController();
- Animator springAnim = aatc.createSpringAnimation(values);
-
- if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
- // Translate hotseat with the shelf until reaching overview.
- float overviewProgress = OVERVIEW.getVerticalProgress(mLauncher);
- ScaleAndTranslation sat = OVERVIEW.getHotseatScaleAndTranslation(mLauncher);
- float shiftRange = aatc.getShiftRange();
- if (values.length == 1) {
- values = new float[] {aatc.getProgress(), values[0]};
- }
- ValueAnimator hotseatAnim = ValueAnimator.ofFloat(values);
- hotseatAnim.addUpdateListener(anim -> {
- float progress = (Float) anim.getAnimatedValue();
- if (progress >= overviewProgress || mLauncher.isInState(BACKGROUND_APP)) {
- float hotseatShift = (progress - overviewProgress) * shiftRange;
- mLauncher.getHotseat().setTranslationY(hotseatShift + sat.translationY);
- }
- });
- hotseatAnim.setInterpolator(LINEAR);
- hotseatAnim.setDuration(springAnim.getDuration());
-
- AnimatorSet anim = new AnimatorSet();
- anim.play(hotseatAnim);
- anim.play(springAnim);
- return anim;
- }
-
- return springAnim;
- }
- case INDEX_RECENTS_FADE_ANIM:
- return ObjectAnimator.ofFloat(mLauncher.getOverviewPanel(),
- RecentsView.CONTENT_ALPHA, values);
- case INDEX_RECENTS_TRANSLATE_X_ANIM: {
- RecentsView rv = mLauncher.getOverviewPanel();
- return new SpringAnimationBuilder(mLauncher)
- .setMinimumVisibleChange(1f / rv.getPageOffsetScale())
- .setDampingRatio(0.8f)
- .setStiffness(250)
- .setValues(values)
- .build(rv, ADJACENT_PAGE_OFFSET);
- }
- case INDEX_PAUSE_TO_OVERVIEW_ANIM: {
- StateAnimationConfig config = new StateAnimationConfig();
- config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
-
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, OVERSHOOT_1_2);
- config.setInterpolator(ANIM_ALL_APPS_FADE, DEACCEL_3);
- if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
- config.setInterpolator(ANIM_HOTSEAT_SCALE, OVERSHOOT_1_2);
- config.setInterpolator(ANIM_HOTSEAT_TRANSLATE, OVERSHOOT_1_2);
- }
-
-
- LauncherStateManager stateManager = mLauncher.getStateManager();
- return stateManager.createAtomicAnimation(
- stateManager.getCurrentStableState(), OVERVIEW, config);
- }
-
- default:
- return super.createStateElementAnimation(index, values);
- }
- }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index eaf9f61..1876424 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -38,6 +38,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AtomicAnimationFactory;
import com.android.launcher3.Workspace;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -48,6 +49,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
+import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
import com.android.launcher3.uioverrides.touchcontrollers.FlingAndHoldTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
@@ -278,6 +280,11 @@
return list.toArray(new TouchController[list.size()]);
}
+ @Override
+ public AtomicAnimationFactory createAtomicAnimationFactory() {
+ return new QuickstepAtomicAnimationFactory(this);
+ }
+
private static final class LauncherTaskViewController extends
TaskViewTouchController<Launcher> {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java
index b27f16a..fc9a11b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java
@@ -15,16 +15,7 @@
*/
package com.android.launcher3.uioverrides.states;
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
-import static com.android.launcher3.anim.Interpolators.INSTANT;
-import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
-
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.states.StateAnimationConfig;
public class OverviewPeekState extends OverviewState {
private static final float OVERVIEW_OFFSET = 0.7f;
@@ -37,14 +28,4 @@
public float[] getOverviewScaleAndOffset(Launcher launcher) {
return new float[] {NO_SCALE, OVERVIEW_OFFSET};
}
-
- @Override
- public void prepareForAtomicAnimation(Launcher launcher, LauncherState fromState,
- StateAnimationConfig config) {
- if (this == OVERVIEW_PEEK && fromState == NORMAL) {
- config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
- config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_7);
- config.setInterpolator(ANIM_OVERVIEW_SCRIM_FADE, FAST_OUT_SLOW_IN);
- }
- }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 6f57281..9f31608 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -15,36 +15,21 @@
*/
package com.android.launcher3.uioverrides.states;
-import static android.view.View.VISIBLE;
-
-import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
-import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
-import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
import android.content.Context;
import android.graphics.Rect;
import android.view.View;
-import android.view.animation.Interpolator;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
-import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.SysUINavigationMode;
@@ -57,9 +42,6 @@
*/
public class OverviewState extends LauncherState {
- // Scale recents takes before animating in
- private static final float RECENTS_PREPARE_SCALE = 1.33f;
-
protected static final Rect sTempRect = new Rect();
private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
@@ -202,35 +184,6 @@
}
}
- @Override
- public void prepareForAtomicAnimation(Launcher launcher, LauncherState fromState,
- StateAnimationConfig config) {
- if ((fromState == NORMAL || fromState == HINT_STATE) && this == OVERVIEW) {
- if (SysUINavigationMode.getMode(launcher) == NO_BUTTON) {
- config.setInterpolator(ANIM_WORKSPACE_SCALE,
- fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
- config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL);
- } else {
- config.setInterpolator(ANIM_WORKSPACE_SCALE, OVERSHOOT_1_2);
-
- // Scale up the recents, if it is not coming from the side
- RecentsView overview = launcher.getOverviewPanel();
- if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
- SCALE_PROPERTY.set(overview, RECENTS_PREPARE_SCALE);
- }
- }
- config.setInterpolator(ANIM_WORKSPACE_FADE, OVERSHOOT_1_2);
- config.setInterpolator(ANIM_OVERVIEW_SCALE, OVERSHOOT_1_2);
- Interpolator translationInterpolator = ENABLE_OVERVIEW_ACTIONS.get()
- && removeShelfFromOverview(launcher)
- ? OVERSHOOT_1_2
- : OVERSHOOT_1_7;
- config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, translationInterpolator);
- config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, translationInterpolator);
- config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
- }
- }
-
public static OverviewState newBackgroundState(int id) {
return new BackgroundAppState(id);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
new file mode 100644
index 0000000..6bc69f9
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2020 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.states;
+
+import static android.view.View.VISIBLE;
+
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherState.BACKGROUND_APP;
+import static com.android.launcher3.LauncherState.HINT_STATE;
+import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
+import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.launcher3.anim.Interpolators.INSTANT;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
+import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
+import static com.android.launcher3.anim.Interpolators.clampToProgress;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.CellLayout;
+import com.android.launcher3.Hotseat;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherState.ScaleAndTranslation;
+import com.android.launcher3.LauncherStateManager;
+import com.android.launcher3.LauncherStateManager.AtomicAnimationFactory;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.launcher3.anim.SpringAnimationBuilder;
+import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
+import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.views.RecentsView;
+
+/**
+ * Animation factory for quickstep specific transitions
+ */
+public class QuickstepAtomicAnimationFactory extends AtomicAnimationFactory {
+
+ // Scale recents takes before animating in
+ private static final float RECENTS_PREPARE_SCALE = 1.33f;
+
+ public static final int INDEX_SHELF_ANIM = 0;
+ public static final int INDEX_RECENTS_FADE_ANIM = 1;
+ public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = 2;
+ public static final int INDEX_PAUSE_TO_OVERVIEW_ANIM = 3;
+ private static final int ANIM_COUNT = 4;
+
+ public static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300;
+
+ private final QuickstepLauncher mLauncher;
+
+ public QuickstepAtomicAnimationFactory(QuickstepLauncher launcher) {
+ super(ANIM_COUNT);
+ mLauncher = launcher;
+ }
+
+ @Override
+ public Animator createStateElementAnimation(int index, float... values) {
+ switch (index) {
+ case INDEX_SHELF_ANIM: {
+ AllAppsTransitionController aatc = mLauncher.getAllAppsController();
+ Animator springAnim = aatc.createSpringAnimation(values);
+
+ if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
+ // Translate hotseat with the shelf until reaching overview.
+ float overviewProgress = OVERVIEW.getVerticalProgress(mLauncher);
+ ScaleAndTranslation sat = OVERVIEW.getHotseatScaleAndTranslation(mLauncher);
+ float shiftRange = aatc.getShiftRange();
+ if (values.length == 1) {
+ values = new float[] {aatc.getProgress(), values[0]};
+ }
+ ValueAnimator hotseatAnim = ValueAnimator.ofFloat(values);
+ hotseatAnim.addUpdateListener(anim -> {
+ float progress = (Float) anim.getAnimatedValue();
+ if (progress >= overviewProgress || mLauncher.isInState(BACKGROUND_APP)) {
+ float hotseatShift = (progress - overviewProgress) * shiftRange;
+ mLauncher.getHotseat().setTranslationY(hotseatShift + sat.translationY);
+ }
+ });
+ hotseatAnim.setInterpolator(LINEAR);
+ hotseatAnim.setDuration(springAnim.getDuration());
+
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(hotseatAnim);
+ anim.play(springAnim);
+ return anim;
+ }
+
+ return springAnim;
+ }
+ case INDEX_RECENTS_FADE_ANIM:
+ return ObjectAnimator.ofFloat(mLauncher.getOverviewPanel(),
+ RecentsView.CONTENT_ALPHA, values);
+ case INDEX_RECENTS_TRANSLATE_X_ANIM: {
+ RecentsView rv = mLauncher.getOverviewPanel();
+ return new SpringAnimationBuilder(mLauncher)
+ .setMinimumVisibleChange(1f / rv.getPageOffsetScale())
+ .setDampingRatio(0.8f)
+ .setStiffness(250)
+ .setValues(values)
+ .build(rv, ADJACENT_PAGE_OFFSET);
+ }
+ case INDEX_PAUSE_TO_OVERVIEW_ANIM: {
+ StateAnimationConfig config = new StateAnimationConfig();
+ config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
+
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS, OVERSHOOT_1_2);
+ config.setInterpolator(ANIM_ALL_APPS_FADE, DEACCEL_3);
+ if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
+ config.setInterpolator(ANIM_HOTSEAT_SCALE, OVERSHOOT_1_2);
+ config.setInterpolator(ANIM_HOTSEAT_TRANSLATE, OVERSHOOT_1_2);
+ }
+
+ LauncherStateManager stateManager = mLauncher.getStateManager();
+ return stateManager.createAtomicAnimation(
+ stateManager.getCurrentStableState(), OVERVIEW, config);
+ }
+
+ default:
+ return super.createStateElementAnimation(index, values);
+ }
+ }
+
+ @Override
+ public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
+ StateAnimationConfig config) {
+ if (toState == NORMAL && fromState == OVERVIEW) {
+ config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
+ config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
+ config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f));
+ config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL);
+ config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
+ Workspace workspace = mLauncher.getWorkspace();
+
+ // Start from a higher workspace scale, but only if we're invisible so we don't jump.
+ boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE;
+ if (isWorkspaceVisible) {
+ CellLayout currentChild = (CellLayout) workspace.getChildAt(
+ workspace.getCurrentPage());
+ isWorkspaceVisible = currentChild.getVisibility() == VISIBLE
+ && currentChild.getShortcutsAndWidgets().getAlpha() > 0;
+ }
+ if (!isWorkspaceVisible) {
+ workspace.setScaleX(0.92f);
+ workspace.setScaleY(0.92f);
+ }
+ Hotseat hotseat = mLauncher.getHotseat();
+ boolean isHotseatVisible = hotseat.getVisibility() == VISIBLE && hotseat.getAlpha() > 0;
+ if (!isHotseatVisible) {
+ hotseat.setScaleX(0.92f);
+ hotseat.setScaleY(0.92f);
+ if (ENABLE_OVERVIEW_ACTIONS.get()) {
+ AllAppsContainerView qsbContainer = mLauncher.getAppsView();
+ View qsb = qsbContainer.getSearchView();
+ boolean qsbVisible = qsb.getVisibility() == VISIBLE && qsb.getAlpha() > 0;
+ if (!qsbVisible) {
+ qsbContainer.setScaleX(0.92f);
+ qsbContainer.setScaleY(0.92f);
+ }
+ }
+ }
+ } else if (toState == NORMAL && fromState == OVERVIEW_PEEK) {
+ // Keep fully visible until the very end (when overview is offscreen) to make invisible.
+ config.setInterpolator(ANIM_OVERVIEW_FADE, t -> t < 1 ? 0 : 1);
+ } else if (toState == OVERVIEW_PEEK && fromState == NORMAL) {
+ config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
+ config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_7);
+ config.setInterpolator(ANIM_OVERVIEW_SCRIM_FADE, FAST_OUT_SLOW_IN);
+ } else if ((fromState == NORMAL || fromState == HINT_STATE) && toState == OVERVIEW) {
+ if (SysUINavigationMode.getMode(mLauncher) == NO_BUTTON) {
+ config.setInterpolator(ANIM_WORKSPACE_SCALE,
+ fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
+ config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL);
+ } else {
+ config.setInterpolator(ANIM_WORKSPACE_SCALE, OVERSHOOT_1_2);
+
+ // Scale up the recents, if it is not coming from the side
+ RecentsView overview = mLauncher.getOverviewPanel();
+ if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
+ SCALE_PROPERTY.set(overview, RECENTS_PREPARE_SCALE);
+ }
+ }
+ config.setInterpolator(ANIM_WORKSPACE_FADE, OVERSHOOT_1_2);
+ config.setInterpolator(ANIM_OVERVIEW_SCALE, OVERSHOOT_1_2);
+ Interpolator translationInterpolator = ENABLE_OVERVIEW_ACTIONS.get()
+ && removeShelfFromOverview(mLauncher)
+ ? OVERSHOOT_1_2
+ : OVERSHOOT_1_7;
+ config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, translationInterpolator);
+ config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, translationInterpolator);
+ config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
+ }
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
index 8af2747..05dd797 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
@@ -16,7 +16,6 @@
package com.android.launcher3.uioverrides.touchcontrollers;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_PAUSE_TO_OVERVIEW_ANIM;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -31,6 +30,7 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
+import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_PAUSE_TO_OVERVIEW_ANIM;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
@@ -42,12 +42,12 @@
import android.view.ViewConfiguration;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppTransitionManagerImpl;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
+import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.VibratorWrapper;
import com.android.quickstep.SystemUiProxy;
@@ -82,7 +82,7 @@
@Override
protected long getAtomicDuration() {
- return LauncherAppTransitionManagerImpl.ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
+ return QuickstepAtomicAnimationFactory.ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
}
@Override
@@ -206,8 +206,8 @@
mPeekAnim.cancel();
}
- Animator overviewAnim = mLauncher.getAppTransitionManager().createStateElementAnimation(
- INDEX_PAUSE_TO_OVERVIEW_ANIM);
+ Animator overviewAnim = mLauncher.createAtomicAnimationFactory()
+ .createStateElementAnimation(INDEX_PAUSE_TO_OVERVIEW_ANIM);
mAtomicAnim = new AnimatorSet();
mAtomicAnim.addListener(new AnimationSuccessListener() {
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index f4f8bc9..7385658 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -16,7 +16,6 @@
package com.android.launcher3.uioverrides.touchcontrollers;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_PAUSE_TO_OVERVIEW_ANIM;
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -35,6 +34,7 @@
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
+import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_PAUSE_TO_OVERVIEW_ANIM;
import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.CANCEL;
@@ -312,8 +312,8 @@
if (mMotionPauseDetector.isPaused() && noFling) {
cancelAnimations();
- Animator overviewAnim = mLauncher.getAppTransitionManager().createStateElementAnimation(
- INDEX_PAUSE_TO_OVERVIEW_ANIM);
+ Animator overviewAnim = mLauncher.createAtomicAnimationFactory()
+ .createStateElementAnimation(INDEX_PAUSE_TO_OVERVIEW_ANIM);
overviewAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
index 4c2bd1b..5e688fb 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
@@ -16,15 +16,15 @@
package com.android.quickstep;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_RECENTS_FADE_ANIM;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_RECENTS_TRANSLATE_X_ANIM;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_SHELF_ANIM;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
+import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
+import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_SHELF_ANIM;
import static com.android.quickstep.LauncherSwipeHandler.RECENTS_ATTACH_DURATION;
import static com.android.quickstep.util.WindowSizeStrategy.LAUNCHER_ACTIVITY_SIZE_STRATEGY;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 6b0d7a3..1f6c506 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -26,7 +26,6 @@
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.util.TraceHelper.FLAG_CHECK_FOR_RACE_CONDITIONS;
-import static com.android.quickstep.GestureState.STATE_OVERSCROLL_WINDOW_CREATED;
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@@ -431,6 +430,6 @@
@Override
public boolean allowInterceptByParent() {
- return !mPassedPilferInputSlop || mGestureState.hasState(STATE_OVERSCROLL_WINDOW_CREATED);
+ return !mPassedPilferInputSlop;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
index 1941830..c49b8f2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
@@ -24,11 +24,9 @@
import static com.android.launcher3.Utilities.squaredHypot;
-import static java.lang.Math.abs;
-
import android.content.Context;
import android.graphics.PointF;
-import android.util.Log;
+import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
@@ -46,31 +44,24 @@
* Input consumer for handling events to pass to an {@code OverscrollPlugin}.
*/
public class OverscrollInputConsumer extends DelegateInputConsumer {
+
private static final String TAG = "OverscrollInputConsumer";
- private static final boolean DEBUG_LOGS_ENABLED = false;
- private static void debugPrint(String log) {
- if (DEBUG_LOGS_ENABLED) {
- Log.v(TAG, log);
- }
- }
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
private final PointF mStartDragPos = new PointF();
private final int mAngleThreshold;
- private final int mFlingDistanceThresholdPx;
- private final int mFlingVelocityThresholdPx;
+ private final float mFlingThresholdPx;
private int mActivePointerId = -1;
private boolean mPassedSlop = false;
- // True if we set ourselves as active, meaning we no longer pass events to the delegate.
- private boolean mPassedActiveThreshold = false;
- private final float mSquaredActiveThreshold;
+
private final float mSquaredSlop;
private final GestureState mGestureState;
@Nullable
private final OverscrollPlugin mPlugin;
+ private final GestureDetector mGestureDetector;
@Nullable
private RecentsView mRecentsView;
@@ -81,19 +72,15 @@
mAngleThreshold = context.getResources()
.getInteger(R.integer.assistant_gesture_corner_deg_threshold);
- mFlingDistanceThresholdPx = (int) context.getResources()
- .getDimension(R.dimen.gestures_overscroll_fling_threshold);
- mFlingVelocityThresholdPx = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
+ mFlingThresholdPx = context.getResources()
+ .getDimension(R.dimen.gestures_overscroll_fling_threshold);
mGestureState = gestureState;
mPlugin = plugin;
float slop = ViewConfiguration.get(context).getScaledTouchSlop();
mSquaredSlop = slop * slop;
-
- float dragThreshold = (int) context.getResources()
- .getDimension(R.dimen.gestures_overscroll_drag_threshold);
- mSquaredActiveThreshold = dragThreshold * dragThreshold;
+ mGestureDetector = new GestureDetector(context, new FlingGestureListener());
}
@Override
@@ -103,27 +90,12 @@
@Override
public void onMotionEvent(MotionEvent ev) {
- if (mPlugin == null) {
- return;
- }
-
switch (ev.getActionMasked()) {
case ACTION_DOWN: {
- if (mPlugin.blockOtherGestures()) {
- // When an Activity is visible, blocking other gestures prevents the Activity
- // from disappearing upon ACTION_DOWN in the navigation bar. (it will reappear
- // on ACTION_MOVE or ACTION_UP)
- debugPrint("Becoming active on ACTION_DOWN");
- if (mState != STATE_ACTIVE) {
- setActive(ev);
- }
- }
mActivePointerId = ev.getPointerId(0);
mDownPos.set(ev.getX(), ev.getY());
mLastPos.set(mDownPos);
- mPlugin.onTouchEvent(ev, getHorizontalDistancePx(), getVerticalDistancePx(),
- (int) Math.sqrt(mSquaredActiveThreshold), mFlingDistanceThresholdPx,
- mFlingVelocityThresholdPx, getDeviceState(), getUnderlyingActivity());
+
break;
}
case ACTION_POINTER_DOWN: {
@@ -159,82 +131,53 @@
}
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
- float squaredDist = squaredHypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y);
-
-
-
if (!mPassedSlop) {
// Normal gesture, ensure we pass the slop before we start tracking the gesture
- if (squaredDist > mSquaredSlop) {
- debugPrint("passed slop");
+ if (squaredHypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y)
+ > mSquaredSlop) {
+
mPassedSlop = true;
mStartDragPos.set(mLastPos.x, mLastPos.y);
if (isOverscrolled()) {
- debugPrint("setting STATE_OVERSCROLL_WINDOW_CREATED");
- mGestureState.setState(GestureState.STATE_OVERSCROLL_WINDOW_CREATED);
- if (!mPlugin.allowsUnderlyingActivityOverscroll()
- && (mState != STATE_ACTIVE)) {
- debugPrint("setting active gesture handler to overscroll to "
- + "prevent losing active touch when Activity starts");
- setActive(ev);
- }
- }
- } else {
- debugPrint("Not past slop");
- }
- }
-
- if (mPassedSlop && !mPassedActiveThreshold && isOverscrolled()) {
- if ((squaredDist > mSquaredActiveThreshold)) {
- debugPrint("Past slop and past threshold, set active");
-
- mPassedActiveThreshold = true;
- if (mState != STATE_ACTIVE) {
setActive(ev);
+
+ if (mPlugin != null) {
+ mPlugin.onTouchStart(getDeviceState(), getUnderlyingActivity());
+ }
+ } else {
+ mState = STATE_DELEGATE_ACTIVE;
}
}
}
- if (mPassedSlop && mState != STATE_DELEGATE_ACTIVE && isOverscrolled()) {
- debugPrint("Relaying touch event");
- mPlugin.onTouchEvent(ev, getHorizontalDistancePx(), getVerticalDistancePx(),
- (int) Math.sqrt(mSquaredActiveThreshold), mFlingDistanceThresholdPx,
- mFlingVelocityThresholdPx, getDeviceState(), getUnderlyingActivity());
+ if (mPassedSlop && mState != STATE_DELEGATE_ACTIVE && isOverscrolled()
+ && mPlugin != null) {
+ mPlugin.onTouchTraveled(getDistancePx());
}
break;
}
case ACTION_CANCEL:
case ACTION_UP:
- if (mPassedSlop && isOverscrolled()) {
- mPlugin.onTouchEvent(ev, getHorizontalDistancePx(), getVerticalDistancePx(),
- (int) Math.sqrt(mSquaredActiveThreshold), mFlingDistanceThresholdPx,
- mFlingVelocityThresholdPx, getDeviceState(), getUnderlyingActivity());
+ if (mState != STATE_DELEGATE_ACTIVE && mPassedSlop && mPlugin != null) {
+ mPlugin.onTouchEnd(getDistancePx());
}
mPassedSlop = false;
- mPassedActiveThreshold = false;
mState = STATE_INACTIVE;
break;
}
+ if (mState != STATE_DELEGATE_ACTIVE) {
+ mGestureDetector.onTouchEvent(ev);
+ }
+
if (mState != STATE_ACTIVE) {
mDelegate.onMotionEvent(ev);
}
}
private boolean isOverscrolled() {
- if (mPlugin.blockOtherGestures()) {
- // When an Activity is visible, this `InputConsumer` immediately becomes
- // the active gesture handler to prevent the Activity from disappearing on TOUCH_DOWN
- // in the navbar.
- //
- // Returning `true` ensures that case will still result in touches being handled,
- // instead of dropping touches until the gesture reaches the thresholds calculated
- // below.
- return true;
- }
-
if (mRecentsView == null) {
BaseDraggingActivity activity = mGestureState.getActivityInterface()
.getCreatedActivity();
@@ -253,10 +196,9 @@
|| mRecentsView.getRunningTaskIndex() <= maxIndex);
// Check if the gesture is within our angle threshold of horizontal
- float deltaY = abs(mLastPos.y - mDownPos.y);
- float deltaX = abs(mDownPos.x - mLastPos.x);
-
- boolean angleInBounds = (Math.toDegrees(Math.atan2(deltaY, deltaX)) < mAngleThreshold);
+ float deltaY = Math.abs(mLastPos.y - mDownPos.y);
+ float deltaX = mDownPos.x - mLastPos.x; // Positive if this is a gesture to the left
+ boolean angleInBounds = Math.toDegrees(Math.atan2(deltaY, deltaX)) < mAngleThreshold;
return atRightMostApp && angleInBounds;
}
@@ -277,22 +219,35 @@
return deviceState;
}
- private int getHorizontalDistancePx() {
- return (int) (mLastPos.x - mDownPos.x);
- }
-
- private int getVerticalDistancePx() {
- return (int) (mLastPos.y - mDownPos.y);
+ private int getDistancePx() {
+ return (int) Math.hypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y);
}
private String getUnderlyingActivity() {
- // Overly defensive, got guidance on code review that something in the chain of
- // `mGestureState.getRunningTask().topActivity` can be null and thus cause a null pointer
- // exception to be thrown, but we aren't sure which part can be null.
- if ((mGestureState == null) || (mGestureState.getRunningTask() == null)
- || (mGestureState.getRunningTask().topActivity == null)) {
- return "";
- }
return mGestureState.getRunningTask().topActivity.flattenToString();
}
+
+ private class FlingGestureListener extends GestureDetector.SimpleOnGestureListener {
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ if (isValidAngle(velocityX, -velocityY)
+ && getDistancePx() >= mFlingThresholdPx
+ && mState != STATE_DELEGATE_ACTIVE) {
+
+ if (mPlugin != null) {
+ mPlugin.onFling(-velocityX);
+ }
+ }
+ return true;
+ }
+
+ private boolean isValidAngle(float deltaX, float deltaY) {
+ float angle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX));
+ // normalize so that angle is measured clockwise from horizontal in the bottom right
+ // corner and counterclockwise from horizontal in the bottom left corner
+
+ angle = angle > 90 ? 180 - angle : angle;
+ return (angle < mAngleThreshold);
+ }
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java
index 217eca5..85006da 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ShelfPeekAnim.java
@@ -15,10 +15,10 @@
*/
package com.android.quickstep.util;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_SHELF_ANIM;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
+import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_SHELF_ANIM;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 6624ff9..b06dc6b 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -79,7 +79,6 @@
<!-- Overscroll Gesture -->
<dimen name="gestures_overscroll_fling_threshold">40dp</dimen>
- <dimen name="gestures_overscroll_drag_threshold">136dp</dimen>
<!-- Tips Gesture Tutorial -->
<dimen name="gesture_tutorial_title_margin_start_end">40dp</dimen>
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 209412a..544f420 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -106,10 +106,6 @@
public static final int STATE_RECENTS_ANIMATION_ENDED =
getFlagForIndex("STATE_RECENTS_ANIMATION_ENDED");
- // Called when we create an overscroll window when swiping right to left on the most recent app
- public static final int STATE_OVERSCROLL_WINDOW_CREATED =
- getFlagForIndex("STATE_OVERSCROLL_WINDOW_CREATED");
-
// Called when RecentsView stops scrolling and settles on a TaskView.
public static final int STATE_RECENTS_SCROLLING_FINISHED =
getFlagForIndex("STATE_RECENTS_SCROLLING_FINISHED");
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index f5088e7..21e8c92 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -71,6 +71,12 @@
@Override
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) {
+ if (mCallbacks == null) {
+ // It's possible for the recents animation to have finished and be cleaned up
+ // by the time we process the start callback, and in that case, just we can skip
+ // handling this call entirely
+ return;
+ }
mController = controller;
mTargets = targets;
}
diff --git a/src/com/android/launcher3/DropTarget.java b/src/com/android/launcher3/DropTarget.java
index 6cb803a..0b0983c 100644
--- a/src/com/android/launcher3/DropTarget.java
+++ b/src/com/android/launcher3/DropTarget.java
@@ -78,7 +78,7 @@
public DraggableView originalView = null;
/** Used for matching DROP event with its corresponding DRAG event on the server side. */
- final InstanceId mLogInstanceId =
+ public final InstanceId logInstanceId =
new InstanceIdSequence(1 << 20 /*InstanceId.INSTANCE_ID_MAX*/)
.newInstanceId();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1d9c0c3..873b066 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -92,6 +92,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.LauncherStateManager.AtomicAnimationFactory;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.allapps.AllAppsContainerView;
@@ -2724,6 +2725,13 @@
return new StateHandler[] { getAllAppsController(), getWorkspace() };
}
+ /**
+ * Creates a factory for atomic state animations
+ */
+ public AtomicAnimationFactory createAtomicAnimationFactory() {
+ return new AtomicAnimationFactory(0);
+ }
+
public TouchController[] createTouchControllers() {
return new TouchController[] {getDragController(), new AllAppsSwipeController(this)};
}
diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java
index 9148c2f..24e0d14 100644
--- a/src/com/android/launcher3/LauncherAppTransitionManager.java
+++ b/src/com/android/launcher3/LauncherAppTransitionManager.java
@@ -13,11 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.android.launcher3;
-
-import android.animation.Animator;
import android.app.ActivityOptions;
import android.content.Context;
import android.graphics.Rect;
@@ -58,17 +55,6 @@
}
/**
- * Number of animations which run on state properties.
- */
- public int getStateElementAnimationsCount() {
- return 0;
- }
-
- public Animator createStateElementAnimation(int index, float... values) {
- throw new RuntimeException("Unknown gesture animation " + index);
- }
-
- /**
* Registers remote animations for certain system transitions.
*/
public void registerRemoteAnimations() {
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index d3af5fc..87ead9e 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -152,6 +152,7 @@
public static final int CONTAINER_HOTSEAT = -101;
public static final int CONTAINER_PREDICTION = -102;
public static final int CONTAINER_HOTSEAT_PREDICTION = -103;
+ public static final int CONTAINER_ALL_APPS = -104;
public static final String containerToString(int container) {
switch (container) {
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 686a241..e133d31 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -15,19 +15,7 @@
*/
package com.android.launcher3;
-import static android.view.View.VISIBLE;
-
-import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
-import static com.android.launcher3.anim.Interpolators.DEACCEL;
-import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
-import static com.android.launcher3.anim.Interpolators.clampToProgress;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL;
@@ -39,20 +27,16 @@
import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
import android.content.Context;
-import android.view.View;
import android.view.animation.Interpolator;
-import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.states.HintState;
import com.android.launcher3.states.SpringLoadedState;
-import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.uioverrides.states.AllAppsState;
import com.android.launcher3.uioverrides.states.OverviewState;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import java.util.Arrays;
-
/**
* Base state for various states used for the Launcher
*/
@@ -293,55 +277,6 @@
}
}
- /**
- * Prepares for a non-user controlled animation from fromState to this state. Preparations
- * include:
- * - Setting interpolators for various animations included in the state transition.
- * - Setting some start values (e.g. scale) for views that are hidden but about to be shown.
- */
- public void prepareForAtomicAnimation(Launcher launcher, LauncherState fromState,
- StateAnimationConfig config) {
- if (this == NORMAL && fromState == OVERVIEW) {
- config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
- config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
- config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f));
- config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL);
- config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
- Workspace workspace = launcher.getWorkspace();
-
- // Start from a higher workspace scale, but only if we're invisible so we don't jump.
- boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE;
- if (isWorkspaceVisible) {
- CellLayout currentChild = (CellLayout) workspace.getChildAt(
- workspace.getCurrentPage());
- isWorkspaceVisible = currentChild.getVisibility() == VISIBLE
- && currentChild.getShortcutsAndWidgets().getAlpha() > 0;
- }
- if (!isWorkspaceVisible) {
- workspace.setScaleX(0.92f);
- workspace.setScaleY(0.92f);
- }
- Hotseat hotseat = launcher.getHotseat();
- boolean isHotseatVisible = hotseat.getVisibility() == VISIBLE && hotseat.getAlpha() > 0;
- if (!isHotseatVisible) {
- hotseat.setScaleX(0.92f);
- hotseat.setScaleY(0.92f);
- if (ENABLE_OVERVIEW_ACTIONS.get()) {
- AllAppsContainerView qsbContainer = launcher.getAppsView();
- View qsb = qsbContainer.getSearchView();
- boolean qsbVisible = qsb.getVisibility() == VISIBLE && qsb.getAlpha() > 0;
- if (!qsbVisible) {
- qsbContainer.setScaleX(0.92f);
- qsbContainer.setScaleY(0.92f);
- }
- }
- }
- } else if (this == NORMAL && fromState == OVERVIEW_PEEK) {
- // Keep fully visible until the very end (when overview is offscreen) to make invisible.
- config.setInterpolator(ANIM_OVERVIEW_FADE, t -> t < 1 ? 0 : 1);
- }
- }
-
public static abstract class PageAlphaProvider {
public final Interpolator interpolator;
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index ea41fc4..1aae201 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -86,7 +86,7 @@
private final ArrayList<StateListener> mListeners = new ArrayList<>();
// Animators which are run on properties also controlled by state animations.
- private Animator[] mStateElementAnimators;
+ private final AtomicAnimationFactory mAtomicAnimationFactory;
private StateHandler[] mStateHandlers;
private LauncherState mState = NORMAL;
@@ -99,6 +99,8 @@
public LauncherStateManager(Launcher l) {
mUiHandler = new Handler(Looper.getMainLooper());
mLauncher = l;
+
+ mAtomicAnimationFactory = l.createAtomicAnimationFactory();
}
public LauncherState getState() {
@@ -195,7 +197,7 @@
public void reapplyState(boolean cancelCurrentAnimation) {
boolean wasInAnimation = mConfig.currentAnimation != null;
if (cancelCurrentAnimation) {
- cancelAllStateElementAnimation();
+ mAtomicAnimationFactory.cancelAllStateElementAnimation();
cancelAnimation();
}
if (mConfig.currentAnimation == null) {
@@ -233,7 +235,7 @@
mConfig.reset();
if (!animated) {
- cancelAllStateElementAnimation();
+ mAtomicAnimationFactory.cancelAllStateElementAnimation();
onStateTransitionStart(state);
for (StateHandler handler : getStateHandlers()) {
handler.setState(state);
@@ -284,7 +286,7 @@
*/
public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
StateAnimationConfig config) {
- toState.prepareForAtomicAnimation(mLauncher, fromState, config);
+ mAtomicAnimationFactory.prepareForAtomicAnimation(fromState, toState, config);
}
/**
@@ -447,42 +449,23 @@
mConfig.setAnimation(anim, null);
}
- private void cancelAllStateElementAnimation() {
- if (mStateElementAnimators == null) {
- return;
- }
-
- for (Animator animator : mStateElementAnimators) {
- if (animator != null) {
- animator.cancel();
- }
- }
- }
-
/**
* Cancels a currently running gesture animation
*/
public void cancelStateElementAnimation(int index) {
- if (mStateElementAnimators == null) {
- return;
- }
- if (mStateElementAnimators[index] != null) {
- mStateElementAnimators[index].cancel();
+ if (mAtomicAnimationFactory.mStateElementAnimators[index] != null) {
+ mAtomicAnimationFactory.mStateElementAnimators[index].cancel();
}
}
public Animator createStateElementAnimation(int index, float... values) {
cancelStateElementAnimation(index);
- LauncherAppTransitionManager latm = mLauncher.getAppTransitionManager();
- if (mStateElementAnimators == null) {
- mStateElementAnimators = new Animator[latm.getStateElementAnimationsCount()];
- }
- Animator anim = latm.createStateElementAnimation(index, values);
- mStateElementAnimators[index] = anim;
+ Animator anim = mAtomicAnimationFactory.createStateElementAnimation(index, values);
+ mAtomicAnimationFactory.mStateElementAnimators[index] = anim;
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mStateElementAnimators[index] = null;
+ mAtomicAnimationFactory.mStateElementAnimators[index] = null;
}
});
return anim;
@@ -590,4 +573,46 @@
default void onStateTransitionComplete(LauncherState finalState) { }
}
+
+ /**
+ * Factory class to configure and create atomic animations.
+ */
+ public static class AtomicAnimationFactory {
+
+ private final Animator[] mStateElementAnimators;
+
+ /**
+ *
+ * @param sharedElementAnimCount number of animations which run on state properties
+ */
+ public AtomicAnimationFactory(int sharedElementAnimCount) {
+ mStateElementAnimators = new Animator[sharedElementAnimCount];
+ }
+
+ void cancelAllStateElementAnimation() {
+ for (Animator animator : mStateElementAnimators) {
+ if (animator != null) {
+ animator.cancel();
+ }
+ }
+ }
+
+ /**
+ * Creates animations for elements which can be also be part of state transitions. The
+ * actual definition of the animation is up to the app to define.
+ *
+ */
+ public Animator createStateElementAnimation(int index, float... values) {
+ throw new RuntimeException("Unknown gesture animation " + index);
+ }
+
+ /**
+ * Prepares for a non-user controlled animation from fromState to this state. Preparations
+ * include:
+ * - Setting interpolators for various animations included in the state transition.
+ * - Setting some start values (e.g. scale) for views that are hidden but about to be shown.
+ */
+ public void prepareForAtomicAnimation(
+ LauncherState fromState, LauncherState toState, StateAnimationConfig config) { }
+ }
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index dd00bd3..412eef1 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -416,8 +416,12 @@
mLauncher.getStateManager().goToState(SPRING_LOADED);
mStatsLogManager.log(
LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED,
- dragObject.mLogInstanceId,
- dragObject.originalDragInfo.buildProto(null));
+ dragObject.logInstanceId,
+ dragObject.originalDragInfo.buildProto(
+ dragObject.dragSource instanceof Folder
+ ? ((Folder) dragObject.dragSource).mInfo
+ : null)
+ );
}
public void deferRemoveExtraEmptyScreen() {
@@ -1645,7 +1649,10 @@
Rect folderLocation = new Rect();
float scale = mLauncher.getDragLayer().getDescendantRectRelativeToSelf(v, folderLocation);
target.removeView(v);
-
+ mStatsLogManager.log(
+ LauncherEvent.LAUNCHER_ITEM_DROP_FOLDER_CREATED,
+ d.logInstanceId,
+ destInfo.buildProto(null));
FolderIcon fi = mLauncher.addFolder(target, container, screenId, targetCell[0],
targetCell[1]);
destInfo.cellX = -1;
@@ -1683,6 +1690,10 @@
if (dropOverView instanceof FolderIcon) {
FolderIcon fi = (FolderIcon) dropOverView;
if (fi.acceptDrop(d.dragInfo)) {
+ mStatsLogManager.log(
+ LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
+ d.logInstanceId,
+ fi.mInfo.buildProto(null));
fi.onDrop(d, false /* itemReturnedOnFailedDrop */);
// if the drag started here, we need to remove it from the workspace
@@ -1885,15 +1896,15 @@
mLauncher.getStateManager().goToState(
NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable);
+ mStatsLogManager.log(
+ LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
+ d.logInstanceId,
+ d.dragInfo.buildProto(null));
}
if (d.stateAnnouncer != null && !droppedOnOriginalCell) {
d.stateAnnouncer.completeAction(R.string.item_moved);
}
- mStatsLogManager.log(
- LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
- d.mLogInstanceId,
- d.dragInfo.buildProto(null));
}
public void onNoCellFound(View dropTargetLayout) {
@@ -2515,6 +2526,10 @@
resetTransitionTransform();
}
}
+ mStatsLogManager.log(
+ LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
+ d.logInstanceId,
+ d.dragInfo.buildProto(null));
}
public Bitmap createWidgetBitmap(ItemInfo widgetInfo, View layout) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 6919339..78d194b 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -110,9 +110,6 @@
public static final BooleanFlag ENABLE_QUICK_CAPTURE_GESTURE = getDebugFlag(
"ENABLE_QUICK_CAPTURE_GESTURE", true, "Swipe from right to left to quick capture");
- public static final BooleanFlag ENABLE_QUICK_CAPTURE_WINDOW = getDebugFlag(
- "ENABLE_QUICK_CAPTURE_WINDOW", false, "Use window to host quick capture");
-
public static final BooleanFlag FORCE_LOCAL_OVERSCROLL_PLUGIN = getDebugFlag(
"FORCE_LOCAL_OVERSCROLL_PLUGIN", false,
"Use a launcher-provided OverscrollPlugin if available");
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index d93fb1a..03028d3 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -186,8 +186,7 @@
mDragObject.dragSource = source;
mDragObject.dragInfo = dragInfo;
- mDragObject.originalDragInfo = new ItemInfo();
- mDragObject.originalDragInfo.copyFrom(dragInfo);
+ mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy();
if (dragOffset != null) {
dragView.setDragVisualizeOffset(new Point(dragOffset));
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index c287190..9a36b3e 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -87,6 +87,7 @@
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.FolderInfo.FolderListener;
@@ -1346,6 +1347,10 @@
if (d.stateAnnouncer != null) {
d.stateAnnouncer.completeAction(R.string.item_moved);
}
+ StatsLogManager.newInstance(getContext())
+ .log(StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
+ d.logInstanceId,
+ d.dragInfo.buildProto(mInfo));
}
// This is used so the item doesn't immediately appear in the folder when added. In one case
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index b875a0b..e2963d7 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -85,7 +85,7 @@
@Thunk ActivityContext mActivity;
@Thunk Folder mFolder;
- private FolderInfo mInfo;
+ public FolderInfo mInfo;
private CheckLongPressHelper mLongPressHelper;
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 62a3829..abf027d 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -47,7 +47,10 @@
@LauncherUiEvent(doc = "User dragged a launcher item")
LAUNCHER_ITEM_DRAG_STARTED(383),
@LauncherUiEvent(doc = "A dragged launcher item is successfully dropped")
- LAUNCHER_ITEM_DROP_COMPLETED(385);
+ LAUNCHER_ITEM_DROP_COMPLETED(385),
+ @LauncherUiEvent(doc = "A dragged launcher item is successfully dropped on another item "
+ + "resulting in new folder creation")
+ LAUNCHER_ITEM_DROP_FOLDER_CREATED(386);
// ADD MORE
private final int mId;
diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java
index ae79f0d..b17b062 100644
--- a/src/com/android/launcher3/model/data/AppInfo.java
+++ b/src/com/android/launcher3/model/data/AppInfo.java
@@ -16,6 +16,8 @@
package com.android.launcher3.model.data;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -74,7 +76,7 @@
public AppInfo(LauncherActivityInfo info, UserHandle user, boolean quietModeEnabled) {
this.componentName = info.getComponentName();
- this.container = ItemInfo.NO_ID;
+ this.container = CONTAINER_ALL_APPS;
this.user = user;
intent = makeLaunchIntent(info);
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index cfe34c1..3ac6a22 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -21,6 +21,7 @@
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Utilities;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.model.ModelWriter;
import com.android.launcher3.util.ContentWriter;
@@ -155,4 +156,20 @@
return super.dumpProperties()
+ " manuallyTypedTitle=" + hasOption(FLAG_MANUAL_FOLDER_NAME);
}
+
+ @Override
+ public LauncherAtom.ItemInfo buildProto(FolderInfo fInfo) {
+ return getDefaultItemInfoBuilder()
+ .setFolderIcon(LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size()))
+ .setContainerInfo(getContainerInfo())
+ .build();
+ }
+
+ @Override
+ public ItemInfo makeShallowCopy() {
+ FolderInfo folderInfo = new FolderInfo();
+ folderInfo.copyFrom(this);
+ folderInfo.contents = this.contents;
+ return folderInfo;
+ }
}
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 561b4ed..4359f25 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -16,6 +16,7 @@
package com.android.launcher3.model.data;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
@@ -36,6 +37,7 @@
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Workspace;
import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logger.LauncherAtom.AllAppsContainer;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.util.ContentWriter;
@@ -251,8 +253,7 @@
* Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info.
*/
public LauncherAtom.ItemInfo buildProto(FolderInfo fInfo) {
- LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
- itemBuilder.setIsWork(user != Process.myUserHandle());
+ LauncherAtom.ItemInfo.Builder itemBuilder = getDefaultItemInfoBuilder();
Optional<ComponentName> nullableComponent = Optional.ofNullable(getTargetComponent());
switch (itemType) {
case ITEM_TYPE_APPLICATION:
@@ -303,23 +304,45 @@
}
itemBuilder.setContainerInfo(ContainerInfo.newBuilder().setFolder(folderBuilder));
} else {
- switch (container) {
- case CONTAINER_HOTSEAT:
- case CONTAINER_HOTSEAT_PREDICTION:
- itemBuilder.setContainerInfo(
- ContainerInfo.newBuilder().setHotseat(
- LauncherAtom.HotseatContainer.newBuilder().setIndex(screenId)));
- break;
- case CONTAINER_DESKTOP:
- itemBuilder.setContainerInfo(
- ContainerInfo.newBuilder().setWorkspace(
- LauncherAtom.WorkspaceContainer.newBuilder()
- .setGridX(cellX)
- .setGridY(cellY)
- .setPageIndex(screenId)));
- break;
- }
+ itemBuilder.setContainerInfo(getContainerInfo());
}
return itemBuilder.build();
}
+
+ LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() {
+ LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
+ itemBuilder.setIsWork(user != Process.myUserHandle());
+ return itemBuilder;
+ }
+
+ ContainerInfo getContainerInfo() {
+ switch (container) {
+ case CONTAINER_HOTSEAT:
+ case CONTAINER_HOTSEAT_PREDICTION:
+ return ContainerInfo.newBuilder()
+ .setHotseat(LauncherAtom.HotseatContainer.newBuilder().setIndex(screenId))
+ .build();
+ case CONTAINER_DESKTOP:
+ return ContainerInfo.newBuilder()
+ .setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder()
+ .setGridX(cellX)
+ .setGridY(cellY)
+ .setPageIndex(screenId))
+ .build();
+ case CONTAINER_ALL_APPS:
+ return ContainerInfo.newBuilder()
+ .setAllAppsContainer(
+ AllAppsContainer.getDefaultInstance())
+ .build();
+ }
+ return ContainerInfo.getDefaultInstance();
+ }
+
+ /** Returns shallow copy of the object. */
+ public ItemInfo makeShallowCopy() {
+ ItemInfo itemInfo = new ItemInfo();
+ itemInfo.copyFrom(this);
+ return itemInfo;
+ }
}
diff --git a/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java b/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java
index a434d07..28a9193 100644
--- a/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java
@@ -15,8 +15,6 @@
*/
package com.android.systemui.plugins;
-import android.view.MotionEvent;
-
import com.android.systemui.plugins.annotations.ProvidesInterface;
/**
@@ -30,7 +28,7 @@
public interface OverscrollPlugin extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_LAUNCHER_OVERSCROLL";
- int VERSION = 4;
+ int VERSION = 3;
String DEVICE_STATE_LOCKED = "Locked";
String DEVICE_STATE_LAUNCHER = "Launcher";
@@ -43,33 +41,33 @@
boolean isActive();
/**
- * Called when a touch has been recognized as an overscroll gesture.
- * @param horizontalDistancePx Horizontal distance from the last finger location to the finger
- * location when it first touched the screen.
- * @param verticalDistancePx Horizontal distance from the last finger location to the finger
- * location when it first touched the screen.
- * @param thresholdPx Minimum distance for gesture.
- * @param flingDistanceThresholdPx Minimum distance for gesture by fling.
- * @param flingVelocityThresholdPx Minimum velocity for gesture by fling.
+ * Called when a touch is down and has been recognized as an overscroll gesture.
+ * A call of this method will always result in `onTouchUp` being called, and possibly
+ * `onFling` as well.
+ *
* @param deviceState String representing the current device state
* @param underlyingActivity String representing the currently active Activity
*/
- void onTouchEvent(MotionEvent event,
- int horizontalDistancePx,
- int verticalDistancePx,
- int thresholdPx,
- int flingDistanceThresholdPx,
- int flingVelocityThresholdPx,
- String deviceState,
- String underlyingActivity);
+ void onTouchStart(String deviceState, String underlyingActivity);
/**
- * @return `true` if overscroll gesture handling should override all other gestures.
+ * Called when a touch that was previously recognized has moved.
+ *
+ * @param px distance between the position of touch on this update and the position of the
+ * touch when it was initially recognized.
*/
- boolean blockOtherGestures();
+ void onTouchTraveled(int px);
/**
- * @return `true` if the overscroll gesture can pan the underlying app.
+ * Called when a touch that was previously recognized has ended.
+ *
+ * @param px distance between the position of touch on this update and the position of the
+ * touch when it was initially recognized.
*/
- boolean allowsUnderlyingActivityOverscroll();
+ void onTouchEnd(int px);
+
+ /**
+ * Called when the user starts Compose with a fling. `onTouchUp` will also be called.
+ */
+ void onFling(float velocity);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
index 5daac39..e1fde3b 100644
--- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
+++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
@@ -19,6 +19,7 @@
import static java.util.regex.Pattern.CASE_INSENSITIVE;
import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
import com.android.launcher3.testing.TestProtocol;
@@ -33,11 +34,14 @@
AddToHomeScreenPrompt(LauncherInstrumentation launcher) {
mLauncher = launcher;
- mWidgetCell = launcher.waitForLauncherObject(By.clazz(
- "com.android.launcher3.widget.WidgetCell"));
+ mWidgetCell = launcher.waitForLauncherObject(getSelector());
mLauncher.assertNotNull("Can't find widget cell object", mWidgetCell);
}
+ private static BySelector getSelector() {
+ return By.clazz("com.android.launcher3.widget.WidgetCell");
+ }
+
public void addAutomatically() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
if (mLauncher.getNavigationModel()
@@ -53,6 +57,7 @@
mLauncher.waitForObjectInContainer(
mWidgetCell.getParent().getParent().getParent().getParent(),
By.text(ADD_AUTOMATICALLY)).click();
+ mLauncher.waitUntilLauncherObjectGone(getSelector());
}
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index dd170c5..240f515 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -542,32 +542,32 @@
if (mDevice.isNaturalOrientation()) {
waitForLauncherObject(APPS_RES_ID);
} else {
- waitUntilGone(APPS_RES_ID);
+ waitUntilLauncherObjectGone(APPS_RES_ID);
}
- waitUntilGone(OVERVIEW_RES_ID);
- waitUntilGone(WIDGETS_RES_ID);
+ waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
+ waitUntilLauncherObjectGone(WIDGETS_RES_ID);
return waitForLauncherObject(WORKSPACE_RES_ID);
}
case WIDGETS: {
- waitUntilGone(WORKSPACE_RES_ID);
- waitUntilGone(APPS_RES_ID);
- waitUntilGone(OVERVIEW_RES_ID);
+ waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
+ waitUntilLauncherObjectGone(APPS_RES_ID);
+ waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
return waitForLauncherObject(WIDGETS_RES_ID);
}
case ALL_APPS: {
- waitUntilGone(WORKSPACE_RES_ID);
- waitUntilGone(OVERVIEW_RES_ID);
- waitUntilGone(WIDGETS_RES_ID);
+ waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
+ waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
+ waitUntilLauncherObjectGone(WIDGETS_RES_ID);
return waitForLauncherObject(APPS_RES_ID);
}
case OVERVIEW: {
if (hasAllAppsInOverview()) {
waitForLauncherObject(APPS_RES_ID);
} else {
- waitUntilGone(APPS_RES_ID);
+ waitUntilLauncherObjectGone(APPS_RES_ID);
}
- waitUntilGone(WORKSPACE_RES_ID);
- waitUntilGone(WIDGETS_RES_ID);
+ waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
+ waitUntilLauncherObjectGone(WIDGETS_RES_ID);
return waitForLauncherObject(OVERVIEW_RES_ID);
}
@@ -575,10 +575,10 @@
return waitForFallbackLauncherObject(OVERVIEW_RES_ID);
}
case BACKGROUND: {
- waitUntilGone(WORKSPACE_RES_ID);
- waitUntilGone(APPS_RES_ID);
- waitUntilGone(OVERVIEW_RES_ID);
- waitUntilGone(WIDGETS_RES_ID);
+ waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
+ waitUntilLauncherObjectGone(APPS_RES_ID);
+ waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
+ waitUntilLauncherObjectGone(WIDGETS_RES_ID);
return null;
}
default:
@@ -622,6 +622,8 @@
* @return the Workspace object.
*/
public Workspace pressHome() {
+ mInstrumentation.getUiAutomation().setOnAccessibilityEventListener(
+ e -> Log.d("b/155926212", e.toString()));
try (LauncherInstrumentation.Closable e = eventsCheck()) {
// Click home, then wait for any accessibility event, then wait until accessibility
// events stop.
@@ -629,7 +631,9 @@
// otherwise waitForIdle may return immediately in case when there was a big enough
// pause in accessibility events prior to pressing Home.
final String action;
+ Log.d("b/155926212", "Before isLauncherVisible()");
final boolean launcherWasVisible = isLauncherVisible();
+ Log.d("b/155926212", "After isLauncherVisible(): " + launcherWasVisible);
if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
checkForAnomaly();
@@ -643,7 +647,7 @@
false, GestureScope.INSIDE_TO_OUTSIDE);
try (LauncherInstrumentation.Closable c = addContextLayer(
"Swiped up from context menu to home")) {
- waitUntilGone(CONTEXT_MENU_RES_ID);
+ waitUntilLauncherObjectGone(CONTEXT_MENU_RES_ID);
}
}
if (hasLauncherObject(WORKSPACE_RES_ID)) {
@@ -685,6 +689,8 @@
"performed action to switch to Home - " + action)) {
return getWorkspace();
}
+ } finally {
+ mInstrumentation.getUiAutomation().setOnAccessibilityEventListener(null);
}
}
@@ -794,9 +800,17 @@
}
}
- void waitUntilGone(String resId) {
- assertTrue("Unexpected launcher object visible: " + resId,
- mDevice.wait(Until.gone(getLauncherObjectSelector(resId)),
+ void waitUntilLauncherObjectGone(String resId) {
+ waitUntilGoneBySelector(getLauncherObjectSelector(resId));
+ }
+
+ void waitUntilLauncherObjectGone(BySelector selector) {
+ waitUntilGoneBySelector(makeLauncherSelector(selector));
+ }
+
+ private void waitUntilGoneBySelector(BySelector launcherSelector) {
+ assertTrue("Unexpected launcher object visible: " + launcherSelector,
+ mDevice.wait(Until.gone(launcherSelector),
WAIT_TIME_MS));
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
index 053847c..bbba4fb 100644
--- a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
+++ b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
@@ -85,18 +85,27 @@
}
private void onRun() {
+ while (true) readEvents();
+ }
+
+ private void readEvents() {
try {
// Note that we use Runtime.exec to start the log reading process instead of running
// it via UIAutomation, so that we can directly access the "Process" object and
// ensure that the instrumentation is not stuck forever.
final String cmd = "logcat -s " + TestProtocol.TAPL_EVENTS_TAG;
+ final Process logcatProcess = Runtime.getRuntime().exec(cmd);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
- Runtime.getRuntime().exec(cmd).getInputStream()))) {
- for (; ; ) {
+ logcatProcess.getInputStream()))) {
+ while (true) {
// Skip everything before the next start command.
for (; ; ) {
final String event = reader.readLine();
+ if (event == null) {
+ Log.d(SKIP_EVENTS_TAG, "Read a null line while waiting for start");
+ return;
+ }
if (event.contains(mStartCommand)) {
Log.d(SKIP_EVENTS_TAG, "Read start: " + event);
break;
@@ -106,6 +115,12 @@
// Store all actual events until the finish command.
for (; ; ) {
final String event = reader.readLine();
+ if (event == null) {
+ Log.d(SKIP_EVENTS_TAG, "Read a null line after waiting for start");
+ mEventsCounter.drainPermits();
+ mEvents.clear();
+ return;
+ }
if (event.contains(mFinishCommand)) {
mFinished.countDown();
Log.d(SKIP_EVENTS_TAG, "Read finish: " + event);
@@ -122,6 +137,8 @@
}
}
}
+ } finally {
+ logcatProcess.destroyForcibly();
}
} catch (IOException e) {
throw new RuntimeException(e);
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 9f80917..f0e686f 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -230,7 +230,7 @@
launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START);
}
LauncherInstrumentation.log("dragIconToWorkspace: end");
- launcher.waitUntilGone("drop_target_bar");
+ launcher.waitUntilLauncherObjectGone("drop_target_bar");
}
/**