diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-02-03 01:29:56 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-02-03 01:29:56 +0000 |
commit | b5c5e27ab6bbbaf69203044bab7b9af61efd79dd (patch) | |
tree | d51ac9fb3e2a72b592dde8472dcf2bae54adce13 /quickstep/src/com/android/launcher3/uioverrides | |
parent | 041c765ca5ee78a8b8c21db1882740b81439c1eb (diff) | |
parent | 808fc1574781a8be6700feb728c9ee65426722a8 (diff) | |
download | Launcher3-simpleperf-release.tar.gz |
Merge "Snap for 11400057 from ded14cc2110e39408f74abac8a83e0a0f16608d2 to simpleperf-release" into simpleperf-releasesimpleperf-release
Diffstat (limited to 'quickstep/src/com/android/launcher3/uioverrides')
19 files changed, 400 insertions, 430 deletions
diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java index a53dc1545f..475f465d0e 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java +++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java @@ -16,13 +16,16 @@ package com.android.launcher3.uioverrides; +import android.app.ActivityOptions; import android.app.Person; import android.content.Context; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; +import android.window.RemoteTransition; import com.android.launcher3.Utilities; +import com.android.quickstep.util.FadeOutRemoteTransition; import java.util.Map; @@ -41,4 +44,13 @@ public class ApiWrapper { public static Map<String, LauncherActivityInfo> getActivityOverrides(Context context) { return context.getSystemService(LauncherApps.class).getActivityOverrides(); } + + /** + * Creates an ActivityOptions to play fade-out animation on closing targets + */ + public static ActivityOptions createFadeOutAnimOptions(Context context) { + ActivityOptions options = ActivityOptions.makeBasic(); + options.setRemoteTransition(new RemoteTransition(new FadeOutRemoteTransition())); + return options; + } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java index 955440b49a..d78ca88249 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java @@ -16,40 +16,34 @@ package com.android.launcher3.uioverrides; +import static com.android.app.animation.Interpolators.AGGRESSIVE_EASE_IN_OUT; +import static com.android.app.animation.Interpolators.FINAL_FRAME; +import static com.android.app.animation.Interpolators.INSTANT; +import static com.android.app.animation.Interpolators.LINEAR; import static com.android.launcher3.LauncherState.QUICK_SWITCH_FROM_HOME; -import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT; -import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; -import static com.android.launcher3.anim.Interpolators.INSTANT; -import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE; -import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_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.SKIP_OVERVIEW; -import static com.android.quickstep.views.FloatingTaskView.PRIMARY_TRANSLATE_OFFSCREEN; import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET; import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION; import static com.android.quickstep.views.RecentsView.TASK_THUMBNAIL_SPLASH_ALPHA; -import android.graphics.Rect; -import android.graphics.RectF; import android.util.FloatProperty; import android.view.animation.Interpolator; import androidx.annotation.NonNull; import com.android.launcher3.LauncherState; -import com.android.launcher3.Utilities; import com.android.launcher3.anim.PendingAnimation; -import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; -import com.android.quickstep.views.FloatingTaskView; import com.android.quickstep.views.RecentsView; /** @@ -113,48 +107,19 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView> setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f, config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR)); - if (mRecentsView.isSplitSelectionActive()) { - // TODO (b/238651489): Refactor state management to avoid need for double check - FloatingTaskView floatingTask = mRecentsView.getFirstFloatingTaskView(); - if (floatingTask != null) { - // We are in split selection state currently, transitioning to another state - DragLayer dragLayer = mLauncher.getDragLayer(); - RectF onScreenRectF = new RectF(); - Utilities.getBoundsForViewInDragLayer(mLauncher.getDragLayer(), floatingTask, - new Rect(0, 0, floatingTask.getWidth(), floatingTask.getHeight()), - false, null, onScreenRectF); - // Get the part of the floatingTask that intersects with the DragLayer (i.e. the - // on-screen portion) - onScreenRectF.intersect( - dragLayer.getLeft(), - dragLayer.getTop(), - dragLayer.getRight(), - dragLayer.getBottom() - ); - - setter.setFloat( - mRecentsView.getFirstFloatingTaskView(), - PRIMARY_TRANSLATE_OFFSCREEN, - mRecentsView.getPagedOrientationHandler() - .getFloatingTaskOffscreenTranslationTarget( - floatingTask, - onScreenRectF, - floatingTask.getStagePosition(), - mLauncher.getDeviceProfile() - ), - config.getInterpolator( - ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN, - LINEAR - )); - setter.setViewAlpha( - mRecentsView.getSplitInstructionsView(), - 0, - config.getInterpolator( - ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE, - LINEAR - ) - ); - } + boolean exitingOverview = !FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get() + && !toState.overviewUi; + if (mRecentsView.isSplitSelectionActive() && exitingOverview) { + setter.add(mRecentsView.getSplitSelectController().getSplitAnimationController() + .createPlaceholderDismissAnim(mLauncher)); + setter.setViewAlpha( + mRecentsView.getSplitInstructionsView(), + 0, + config.getInterpolator( + ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE, + LINEAR + ) + ); } setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0, diff --git a/quickstep/src/com/android/launcher3/uioverrides/DejankBinderTracker.java b/quickstep/src/com/android/launcher3/uioverrides/DejankBinderTracker.java deleted file mode 100644 index d8aa235823..0000000000 --- a/quickstep/src/com/android/launcher3/uioverrides/DejankBinderTracker.java +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Copyright (C) 2019 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 android.os.IBinder.FLAG_ONEWAY; - -import android.os.Binder; -import android.os.Build; -import android.os.IBinder; -import android.os.Looper; -import android.os.RemoteException; -import android.util.Log; - -import androidx.annotation.MainThread; - -import java.util.HashSet; -import java.util.Locale; -import java.util.function.BiConsumer; -import java.util.function.Supplier; - -/** - * A binder proxy transaction listener for tracking non-whitelisted binder calls. - */ -public class DejankBinderTracker implements Binder.ProxyTransactListener { - private static final String TAG = "DejankBinderTracker"; - - private static final Object sLock = new Object(); - private static final HashSet<String> sWhitelistedFrameworkClasses = new HashSet<>(); - static { - // Common IPCs that are ok to block the main thread. - sWhitelistedFrameworkClasses.add("android.view.IWindowSession"); - sWhitelistedFrameworkClasses.add("android.os.IPowerManager"); - } - private static boolean sTemporarilyIgnoreTracking = false; - - // Used by the client to limit binder tracking to specific regions - private static boolean sTrackingAllowed = false; - - private BiConsumer<String, Integer> mUnexpectedTransactionCallback; - private boolean mIsTracking = false; - - /** - * Temporarily ignore blocking binder calls for the duration of this {@link Runnable}. - */ - @MainThread - public static void whitelistIpcs(Runnable runnable) { - sTemporarilyIgnoreTracking = true; - runnable.run(); - sTemporarilyIgnoreTracking = false; - } - - /** - * Temporarily ignore blocking binder calls for the duration of this {@link Supplier}. - */ - @MainThread - public static <T> T whitelistIpcs(Supplier<T> supplier) { - sTemporarilyIgnoreTracking = true; - T value = supplier.get(); - sTemporarilyIgnoreTracking = false; - return value; - } - - /** - * Enables binder tracking during a test. - */ - @MainThread - public static void allowBinderTrackingInTests() { - sTrackingAllowed = true; - } - - /** - * Disables binder tracking during a test. - */ - @MainThread - public static void disallowBinderTrackingInTests() { - sTrackingAllowed = false; - } - - public DejankBinderTracker(BiConsumer<String, Integer> unexpectedTransactionCallback) { - mUnexpectedTransactionCallback = unexpectedTransactionCallback; - } - - @MainThread - public void startTracking() { - if (!Build.TYPE.toLowerCase(Locale.ROOT).contains("debug") - && !Build.TYPE.toLowerCase(Locale.ROOT).equals("eng")) { - Log.wtf(TAG, "Unexpected use of binder tracker in non-debug build", new Exception()); - return; - } - if (mIsTracking) { - return; - } - mIsTracking = true; - Binder.setProxyTransactListener(this); - } - - @MainThread - public void stopTracking() { - if (!mIsTracking) { - return; - } - mIsTracking = false; - Binder.setProxyTransactListener(null); - } - - // Override the hidden Binder#onTransactStarted method - public synchronized Object onTransactStarted(IBinder binder, int transactionCode, int flags) { - if (!mIsTracking - || !sTrackingAllowed - || sTemporarilyIgnoreTracking - || (flags & FLAG_ONEWAY) == FLAG_ONEWAY - || !isMainThread()) { - return null; - } - - String descriptor; - try { - descriptor = binder.getInterfaceDescriptor(); - if (sWhitelistedFrameworkClasses.contains(descriptor)) { - return null; - } - } catch (RemoteException e) { - e.printStackTrace(); - descriptor = binder.getClass().getSimpleName(); - } - - mUnexpectedTransactionCallback.accept(descriptor, transactionCode); - return null; - } - - @Override - public Object onTransactStarted(IBinder binder, int transactionCode) { - // Do nothing - return null; - } - - @Override - public void onTransactEnded(Object session) { - // Do nothing - } - - public static boolean isMainThread() { - return Thread.currentThread() == Looper.getMainLooper().getThread(); - } -} diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java index 3e1d0f137a..2064fe22f6 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java +++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java @@ -15,7 +15,7 @@ */ package com.android.launcher3.uioverrides; -import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; +import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE; import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED; import static com.android.launcher3.icons.FastBitmapDrawable.getDisabledColorFilter; @@ -260,8 +260,8 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView { Keyframe.ofFloat(0.82f, finalTrans - getOutlineOffsetY() / 2f), // Overshoot Keyframe.ofFloat(1f, finalTrans) // Ease back into the final position }; - keyframes[1].setInterpolator(ACCEL_DEACCEL); - keyframes[2].setInterpolator(ACCEL_DEACCEL); + keyframes[1].setInterpolator(ACCELERATE_DECELERATE); + keyframes[2].setInterpolator(ACCELERATE_DECELERATE); mSlotMachineAnim = ObjectAnimator.ofPropertyValuesHolder(this, PropertyValuesHolder.ofKeyframe(SLOT_MACHINE_TRANSLATION_Y, keyframes)); @@ -337,7 +337,6 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView { if (getTag() instanceof WorkspaceItemInfo) { WorkspaceItemInfo info = (WorkspaceItemInfo) getTag(); isBadged = !Process.myUserHandle().equals(info.user) - || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 3139e4d91a..5a46b8d8e9 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -20,23 +20,20 @@ import static android.os.Trace.TRACE_TAG_APP; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE; import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED; +import static com.android.app.animation.Interpolators.EMPHASIZED; import static com.android.launcher3.LauncherSettings.Animation.DEFAULT_NO_ICON; import static com.android.launcher3.LauncherSettings.Animation.VIEW_BACKGROUND; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; -import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.NO_OFFSET; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK; import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT; -import static com.android.launcher3.anim.Interpolators.EMPHASIZED; import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent; -import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE; import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE; -import static com.android.launcher3.config.FeatureFlags.RECEIVE_UNFOLD_EVENTS_FROM_SYSUI; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP; import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID; import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition; @@ -60,8 +57,6 @@ import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SY import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; -import android.animation.ValueAnimator; -import android.app.ActivityManager; import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; @@ -71,20 +66,20 @@ import android.content.res.Configuration; import android.graphics.Color; import android.graphics.Rect; import android.graphics.RectF; -import android.hardware.SensorManager; -import android.hardware.devicestate.DeviceStateManager; import android.hardware.display.DisplayManager; import android.media.permission.SafeCloseable; import android.os.Build; import android.os.Bundle; -import android.os.CancellationSignal; import android.os.IBinder; import android.os.SystemProperties; import android.os.Trace; +import android.util.AttributeSet; +import android.util.Log; import android.view.Display; import android.view.HapticFeedbackConstants; -import android.view.RemoteAnimationTarget; import android.view.View; +import android.widget.AnalogClock; +import android.widget.TextClock; import android.window.BackEvent; import android.window.OnBackAnimationCallback; import android.window.OnBackInvokedDispatcher; @@ -111,7 +106,6 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.appprediction.PredictionRowView; import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.hybridhotseat.HotseatPredictionController; import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.StatsLogManager; @@ -119,9 +113,9 @@ import com.android.launcher3.logging.StatsLogManager.StatsLogger; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.WellbeingModel; import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.proxy.ProxyActivityStarter; -import com.android.launcher3.proxy.StartActivityParams; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statehandlers.DesktopVisibilityController; import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory; @@ -153,6 +147,7 @@ import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource; +import com.android.launcher3.util.StartActivityParams; import com.android.launcher3.util.TouchController; import com.android.launcher3.widget.LauncherWidgetHolder; import com.android.quickstep.OverviewCommandHelper; @@ -160,12 +155,10 @@ import com.android.quickstep.RecentsModel; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskUtils; import com.android.quickstep.TouchInteractionService.TISBinder; +import com.android.quickstep.util.AsyncClockEventDelegate; import com.android.quickstep.util.GroupTask; import com.android.quickstep.util.LauncherUnfoldAnimationController; -import com.android.quickstep.util.ProxyScreenStatusProvider; import com.android.quickstep.util.QuickstepOnboardingPrefs; -import com.android.quickstep.util.RemoteAnimationProvider; -import com.android.quickstep.util.RemoteFadeOutAnimationListener; import com.android.quickstep.util.SplitSelectStateController; import com.android.quickstep.util.SplitToWorkspaceController; import com.android.quickstep.util.SplitWithKeyboardShortcutController; @@ -175,16 +168,14 @@ import com.android.quickstep.views.FloatingTaskView; import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; +import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.unfold.RemoteUnfoldSharedComponent; -import com.android.systemui.unfold.UnfoldSharedComponent; import com.android.systemui.unfold.UnfoldTransitionFactory; import com.android.systemui.unfold.UnfoldTransitionProgressProvider; import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig; import com.android.systemui.unfold.config.UnfoldTransitionConfig; import com.android.systemui.unfold.progress.RemoteUnfoldTransitionReceiver; -import com.android.systemui.unfold.system.ActivityManagerActivityTypeProvider; -import com.android.systemui.unfold.system.DeviceStateManagerFoldProvider; import com.android.systemui.unfold.updates.RotationChangeProvider; import java.io.FileDescriptor; @@ -194,16 +185,22 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Stream; public class QuickstepLauncher extends Launcher { + private static final boolean TRACE_LAYOUTS = + SystemProperties.getBoolean("persist.debug.trace_layouts", false); + private static final String TRACE_RELAYOUT_CLASS = + SystemProperties.get("persist.debug.trace_request_layout_class", null); - public static final boolean ENABLE_PIP_KEEP_CLEAR_ALGORITHM = - SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", true); + private static final String TAG = "QuickstepLauncher"; public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false; + protected static final String RING_APPEAR_ANIMATION_PREFIX = "RingAppearAnimation\t"; + private FixedContainerItems mAllAppsPredictions; private HotseatPredictionController mHotseatPredictionController; private DepthController mDepthController; @@ -211,11 +208,8 @@ public class QuickstepLauncher extends Launcher { private QuickstepTransitionManager mAppTransitionManager; private OverviewActionsView mActionsView; private TISBindHelper mTISBindHelper; - private @Nullable TaskbarManager mTaskbarManager; - private @Nullable OverviewCommandHelper mOverviewCommandHelper; private @Nullable LauncherTaskbarUIController mTaskbarUIController; // Will be updated when dragging from taskbar. - private @Nullable DragOptions mNextWorkspaceDragOptions = null; private @Nullable UnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider; private @Nullable LauncherUnfoldAnimationController mLauncherUnfoldAnimationController; @@ -223,6 +217,8 @@ public class QuickstepLauncher extends Launcher { private SplitWithKeyboardShortcutController mSplitWithKeyboardShortcutController; private SplitToWorkspaceController mSplitToWorkspaceController; + private AsyncClockEventDelegate mAsyncClockEventDelegate; + /** * If Launcher restarted while in the middle of an Overview split select, it needs this data to * recover. In all other cases this will remain null. @@ -258,6 +254,10 @@ public class QuickstepLauncher extends Launcher { mTISBindHelper = new TISBindHelper(this, this::onTISConnected); mDepthController = new DepthController(this); mDesktopVisibilityController = new DesktopVisibilityController(this); + if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) { + mDesktopVisibilityController.registerSystemUiListener(); + mSplitSelectStateController.initSplitFromDesktopController(this); + } mHotseatPredictionController = new HotseatPredictionController(this); mEnableWidgetDepth = SystemProperties.getBoolean("ro.launcher.depth.widget", true); @@ -279,7 +279,6 @@ public class QuickstepLauncher extends Launcher { if (mAllAppsPredictions != null && (info.itemType == ITEM_TYPE_APPLICATION - || info.itemType == ITEM_TYPE_SHORTCUT || info.itemType == ITEM_TYPE_DEEP_SHORTCUT)) { int count = mAllAppsPredictions.items.size(); for (int i = 0; i < count; i++) { @@ -349,9 +348,7 @@ public class QuickstepLauncher extends Launcher { mHotseatPredictionController.setPauseUIUpdate(getTaskbarUIController() == null); RunnableList result = super.startActivitySafely(v, intent, item); if (result == null) { - if (getTaskbarUIController() == null) { - mHotseatPredictionController.setPauseUIUpdate(false); - } + mHotseatPredictionController.setPauseUIUpdate(false); } else { result.add(() -> mHotseatPredictionController.setPauseUIUpdate(false)); } @@ -406,8 +403,7 @@ public class QuickstepLauncher extends Launcher { } private List<SystemShortcut.Factory<QuickstepLauncher>> getSplitShortcuts() { - - if (!ENABLE_SPLIT_FROM_WORKSPACE.get() || !mDeviceProfile.isTablet) { + if (!mDeviceProfile.isTablet || mSplitSelectStateController.isSplitSelectActive()) { return Collections.emptyList(); } RecentsView recentsView = getOverviewPanel(); @@ -435,12 +431,8 @@ public class QuickstepLauncher extends Launcher { boolean visible = (state == NORMAL || state == OVERVIEW) && (willUserBeActive || isUserActive()) && !profile.isVerticalBarLayout(); - if (ENABLE_PIP_KEEP_CLEAR_ALGORITHM) { - SystemUiProxy.INSTANCE.get(this) - .setLauncherKeepClearAreaHeight(visible, profile.hotseatBarSizePx); - } else { - SystemUiProxy.INSTANCE.get(this).setShelfHeight(visible, profile.hotseatBarSizePx); - } + SystemUiProxy.INSTANCE.get(this) + .setLauncherKeepClearAreaHeight(visible, profile.hotseatBarSizePx); } if (state == NORMAL && !inTransition) { ((RecentsView) getOverviewPanel()).setSwipeDownShouldLaunchApp(false); @@ -449,6 +441,7 @@ public class QuickstepLauncher extends Launcher { @Override public void bindExtraContainerItems(FixedContainerItems item) { + Log.d(TAG, "Bind extra container items"); if (item.containerId == Favorites.CONTAINER_PREDICTION) { mAllAppsPredictions = item; PredictionRowView<?> predictionRowView = @@ -456,6 +449,7 @@ public class QuickstepLauncher extends Launcher { PredictionRowView.class); predictionRowView.setPredictedApps(item.items); } else if (item.containerId == Favorites.CONTAINER_HOTSEAT_PREDICTION) { + Log.d(TAG, "Bind extra container item is hotseat prediction"); mHotseatPredictionController.setPredictedItems(item); } else if (item.containerId == Favorites.CONTAINER_WIDGETS_PREDICTION) { getPopupDataProvider().setRecommendedWidgets(item.items); @@ -472,22 +466,28 @@ public class QuickstepLauncher extends Launcher { public void onDestroy() { mAppTransitionManager.onActivityDestroyed(); if (mUnfoldTransitionProgressProvider != null) { - if (FeatureFlags.RECEIVE_UNFOLD_EVENTS_FROM_SYSUI.get()) { - SystemUiProxy.INSTANCE.get(this).setUnfoldAnimationListener(null); - } - + SystemUiProxy.INSTANCE.get(this).setUnfoldAnimationListener(null); mUnfoldTransitionProgressProvider.destroy(); } mTISBindHelper.onDestroy(); - if (mTaskbarManager != null) { - mTaskbarManager.clearActivity(this); - } if (mLauncherUnfoldAnimationController != null) { mLauncherUnfoldAnimationController.onDestroy(); } + if (mDesktopVisibilityController != null) { + mDesktopVisibilityController.unregisterSystemUiListener(); + } + + if (mSplitSelectStateController != null) { + mSplitSelectStateController.onDestroy(); + } + + if (mAsyncClockEventDelegate != null) { + mAsyncClockEventDelegate.onDestroy(); + } + super.onDestroy(); mHotseatPredictionController.destroy(); mSplitWithKeyboardShortcutController.onDestroy(); @@ -521,7 +521,7 @@ public class QuickstepLauncher extends Launcher { } case QUICK_SWITCH_STATE_ORDINAL: { RecentsView rv = getOverviewPanel(); - TaskView tasktolaunch = rv.getTaskViewAt(0); + TaskView tasktolaunch = rv.getCurrentPageTaskView(); if (tasktolaunch != null) { tasktolaunch.launchTask(success -> { if (!success) { @@ -545,11 +545,14 @@ public class QuickstepLauncher extends Launcher { ArrayList<TouchController> list = new ArrayList<>(); list.add(getDragController()); + Consumer<AnimatorSet> splitAnimator = animatorSet -> + animatorSet.play(mSplitSelectStateController.getSplitAnimationController() + .createPlaceholderDismissAnim(this)); switch (mode) { case NO_BUTTON: list.add(new NoButtonQuickSwitchTouchController(this)); - list.add(new NavBarToHomeTouchController(this)); - list.add(new NoButtonNavbarToOverviewTouchController(this)); + list.add(new NavBarToHomeTouchController(this, splitAnimator)); + list.add(new NoButtonNavbarToOverviewTouchController(this, splitAnimator)); break; case TWO_BUTTONS: list.add(new TwoButtonNavbarTouchController(this)); @@ -559,8 +562,14 @@ public class QuickstepLauncher extends Launcher { list.add(new PortraitStatesTouchController(this)); break; case THREE_BUTTONS: + list.add(new NoButtonQuickSwitchTouchController(this)); + list.add(new NavBarToHomeTouchController(this, splitAnimator)); + list.add(new NoButtonNavbarToOverviewTouchController(this, splitAnimator)); + list.add(new PortraitStatesTouchController(this)); + break; default: list.add(new PortraitStatesTouchController(this)); + break; } if (!getDeviceProfile().isMultiWindowMode) { @@ -601,6 +610,8 @@ public class QuickstepLauncher extends Launcher { mViewCapture = SettingsAwareViewCapture.getInstance(this).startCapture(getWindow()); } getWindow().addPrivateFlags(PRIVATE_FLAG_OPTIMIZE_MEASURE); + View.setTraceLayoutSteps(TRACE_LAYOUTS); + View.setTracedRequestLayoutClassClass(TRACE_RELAYOUT_CLASS); } @Override @@ -608,12 +619,14 @@ public class QuickstepLauncher extends Launcher { RecentsView recentsView = getOverviewPanel(); // Check if there is already an instance of this app running, if so, initiate the split // using that. - mSplitSelectStateController.findLastActiveTaskAndRunCallback( - splitSelectSource.itemInfo.getComponentKey(), - foundTask -> { - splitSelectSource.alreadyRunningTaskId = foundTask == null - ? INVALID_TASK_ID - : foundTask.key.id; + mSplitSelectStateController.findLastActiveTasksAndRunCallback( + Collections.singletonList(splitSelectSource.itemInfo.getComponentKey()), + foundTasks -> { + @Nullable Task foundTask = foundTasks.get(0); + boolean taskWasFound = foundTask != null; + splitSelectSource.alreadyRunningTaskId = taskWasFound + ? foundTask.key.id + : INVALID_TASK_ID; if (ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) { startSplitToHome(splitSelectSource); } else { @@ -653,9 +666,13 @@ public class QuickstepLauncher extends Launcher { @Override public void onAnimationCancel(Animator animation) { getDragLayer().removeView(floatingTaskView); + mSplitSelectStateController.getSplitAnimationController() + .removeSplitInstructionsView(QuickstepLauncher.this); mSplitSelectStateController.resetState(); } }); + anim.add(mSplitSelectStateController.getSplitAnimationController() + .getShowSplitInstructionsAnim(this).buildAnim()); anim.buildAnim().start(); } @@ -681,9 +698,9 @@ public class QuickstepLauncher extends Launcher { @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - - if (mOverviewCommandHelper != null) { - mOverviewCommandHelper.clearPendingCommands(); + OverviewCommandHelper overviewCommandHelper = mTISBindHelper.getOverviewCommandHelper(); + if (overviewCommandHelper != null) { + overviewCommandHelper.clearPendingCommands(); } } @@ -806,8 +823,9 @@ public class QuickstepLauncher extends Launcher { } private void onTaskbarInAppDisplayProgressUpdate(float progress, int flag) { - if (mTaskbarManager == null - || mTaskbarManager.getCurrentActivityContext() == null + TaskbarManager taskbarManager = mTISBindHelper.getTaskbarManager(); + if (taskbarManager == null + || taskbarManager.getCurrentActivityContext() == null || mTaskbarUIController == null) { return; } @@ -851,7 +869,7 @@ public class QuickstepLauncher extends Launcher { if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) { DesktopVisibilityController controller = mDesktopVisibilityController; if (controller != null && controller.areFreeformTasksVisible() - && !controller.isGestureInProgress()) { + && !controller.isRecentsGestureInProgress()) { // Return early to skip setting activity to appear as resumed // TODO(b/255649902): shouldn't be needed when we have a separate launcher state // for desktop that we can use to control other parts of launcher @@ -879,11 +897,10 @@ public class QuickstepLauncher extends Launcher { } private void onTISConnected(TISBinder binder) { - mTaskbarManager = binder.getTaskbarManager(); - if (mTaskbarManager != null) { - mTaskbarManager.setActivity(this); + TaskbarManager taskbarManager = mTISBindHelper.getTaskbarManager(); + if (taskbarManager != null) { + taskbarManager.setActivity(this); } - mOverviewCommandHelper = binder.getOverviewCommandHelper(); } @Override @@ -894,43 +911,10 @@ public class QuickstepLauncher extends Launcher { private void initUnfoldTransitionProgressProvider() { final UnfoldTransitionConfig config = new ResourceUnfoldTransitionConfig(); if (config.isEnabled()) { - if (RECEIVE_UNFOLD_EVENTS_FROM_SYSUI.get()) { - initRemotelyCalculatedUnfoldAnimation(config); - } else { - initLocallyCalculatedUnfoldAnimation(config); - } - + initRemotelyCalculatedUnfoldAnimation(config); } } - /** Registers hinge angle listener and calculates the animation progress in this process. */ - private void initLocallyCalculatedUnfoldAnimation(UnfoldTransitionConfig config) { - UnfoldSharedComponent unfoldComponent = - UnfoldTransitionFactory.createUnfoldSharedComponent( - /* context= */ this, - config, - ProxyScreenStatusProvider.INSTANCE, - new DeviceStateManagerFoldProvider( - getSystemService(DeviceStateManager.class), /* context= */ this), - new ActivityManagerActivityTypeProvider( - getSystemService(ActivityManager.class)), - getSystemService(SensorManager.class), - getMainThreadHandler(), - getMainExecutor(), - /* backgroundExecutor= */ UI_HELPER_EXECUTOR, - /* tracingTagPrefix= */ "launcher", - getSystemService(DisplayManager.class) - ); - - mUnfoldTransitionProgressProvider = unfoldComponent.getUnfoldTransitionProvider() - .orElseThrow(() -> new IllegalStateException( - "Trying to create UnfoldTransitionProgressProvider when the " - + "transition is disabled")); - - initUnfoldAnimationController(mUnfoldTransitionProgressProvider, - unfoldComponent.getRotationChangeProvider()); - } - /** Receives animation progress from sysui process. */ private void initRemotelyCalculatedUnfoldAnimation(UnfoldTransitionConfig config) { RemoteUnfoldSharedComponent unfoldComponent = @@ -980,6 +964,13 @@ public class QuickstepLauncher extends Launcher { return mSplitToWorkspaceController; } + @Override + protected void handleSplitAnimationGoingToHome() { + super.handleSplitAnimationGoingToHome(); + mSplitSelectStateController.getSplitAnimationController() + .playPlaceholderDismissAnim(this); + } + public <T extends OverviewActionsView> T getActionsView() { return (T) mActionsView; } @@ -1016,41 +1007,6 @@ public class QuickstepLauncher extends Launcher { } @Override - public DragOptions getDefaultWorkspaceDragOptions() { - if (mNextWorkspaceDragOptions != null) { - DragOptions options = mNextWorkspaceDragOptions; - mNextWorkspaceDragOptions = null; - return options; - } - return super.getDefaultWorkspaceDragOptions(); - } - - public void setNextWorkspaceDragOptions(DragOptions dragOptions) { - mNextWorkspaceDragOptions = dragOptions; - } - - @Override - public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) { - QuickstepTransitionManager appTransitionManager = getAppTransitionManager(); - appTransitionManager.setRemoteAnimationProvider(new RemoteAnimationProvider() { - @Override - public AnimatorSet createWindowAnimation(RemoteAnimationTarget[] appTargets, - RemoteAnimationTarget[] wallpaperTargets) { - - // On the first call clear the reference. - signal.cancel(); - - ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0); - fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(appTargets, - wallpaperTargets)); - AnimatorSet anim = new AnimatorSet(); - anim.play(fadeAnimation); - return anim; - } - }, signal); - } - - @Override public float[] getNormalOverviewScaleAndOffset() { return DisplayController.getNavigationMode(this).hasGestures ? new float[] {1, 1} : new float[] {1.1f, NO_OFFSET}; @@ -1100,6 +1056,8 @@ public class QuickstepLauncher extends Launcher { activityOptions.options.setLaunchDisplayId( (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId() : Display.DEFAULT_DISPLAY); + activityOptions.options.setPendingIntentBackgroundActivityStartMode( + ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED); addLaunchCookie(item, activityOptions.options); return activityOptions; } @@ -1112,6 +1070,8 @@ public class QuickstepLauncher extends Launcher { Executors.MAIN_EXECUTOR.getHandler(), null, elapsedRealTime -> callbacks.executeAllAndDestroy()); options.setSplashScreenStyle(splashScreenStyle); + options.setPendingIntentBackgroundActivityStartMode( + ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED); return new ActivityOptionsWrapper(options, callbacks); } @@ -1159,7 +1119,6 @@ public class QuickstepLauncher extends Launcher { } switch (info.itemType) { case Favorites.ITEM_TYPE_APPLICATION: - case Favorites.ITEM_TYPE_SHORTCUT: case Favorites.ITEM_TYPE_DEEP_SHORTCUT: case Favorites.ITEM_TYPE_APPWIDGET: // Fall through and continue if it's an app, shortcut, or widget @@ -1268,8 +1227,9 @@ public class QuickstepLauncher extends Launcher { Trace.instantForTrack(TRACE_TAG_APP, "QuickstepLauncher#DeviceProfileChanged", getDeviceProfile().toSmallString()); SystemUiProxy.INSTANCE.get(this).setLauncherAppIconSize(mDeviceProfile.iconSizePx); - if (mTaskbarManager != null) { - mTaskbarManager.debugWhyTaskbarNotDestroyed("QuickstepLauncher#onDeviceProfileChanged"); + TaskbarManager taskbarManager = mTISBindHelper.getTaskbarManager(); + if (taskbarManager != null) { + taskbarManager.debugWhyTaskbarNotDestroyed("QuickstepLauncher#onDeviceProfileChanged"); } } @@ -1291,7 +1251,7 @@ public class QuickstepLauncher extends Launcher { groupTask.task1.key.id, groupTask.task2.key.id, SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT, - /* callback= */ success -> {}, + /* callback= */ success -> mSplitSelectStateController.resetState(), /* freezeTaskList= */ true, groupTask.mSplitBounds == null ? DEFAULT_SPLIT_RATIO @@ -1300,6 +1260,18 @@ public class QuickstepLauncher extends Launcher { : groupTask.mSplitBounds.leftTaskPercent); } + /** + * Launches two apps as an app pair. + */ + public void launchAppPair(WorkspaceItemInfo app1, WorkspaceItemInfo app2) { + mSplitSelectStateController.getAppPairsController().launchAppPair(app1, app2); + } + + public boolean canStartHomeSafely() { + OverviewCommandHelper overviewCommandHelper = mTISBindHelper.getOverviewCommandHelper(); + return overviewCommandHelper == null || overviewCommandHelper.canStartHomeSafely(); + } + private static final class LauncherTaskViewController extends TaskViewTouchController<Launcher> { @@ -1336,5 +1308,34 @@ public class QuickstepLauncher extends Launcher { if (recentsView != null) { recentsView.getSplitSelectController().dump(prefix, writer); } + if (mAppTransitionManager != null) { + mAppTransitionManager.dump(prefix + "\t" + RING_APPEAR_ANIMATION_PREFIX, writer); + } + if (mHotseatPredictionController != null) { + mHotseatPredictionController.dump(prefix, writer); + } + } + + @Override + public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { + switch (name) { + case "TextClock", "android.widget.TextClock" -> { + TextClock tc = new TextClock(context, attrs); + if (mAsyncClockEventDelegate == null) { + mAsyncClockEventDelegate = new AsyncClockEventDelegate(this); + } + tc.setClockEventDelegate(mAsyncClockEventDelegate); + return tc; + } + case "AnalogClock", "android.widget.AnalogClock" -> { + AnalogClock ac = new AnalogClock(context, attrs); + if (mAsyncClockEventDelegate == null) { + mAsyncClockEventDelegate = new AsyncClockEventDelegate(this); + } + ac.setClockEventDelegate(mAsyncClockEventDelegate); + return ac; + } + } + return super.onCreateView(parent, name, context, attrs); } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java index 39543b0d7d..f7bef031c7 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java @@ -243,6 +243,7 @@ public final class QuickstepWidgetHolder extends LauncherWidgetHolder { } else { widgetView = new LauncherAppWidgetHostView(context); } + widgetView.setIsWidgetCachingDisabled(true); widgetView.setInteractionHandler(mInteractionHandler); widgetView.setAppWidget(appWidgetId, appWidget); mViews.put(appWidgetId, widgetView); diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index f16b43df5e..23e922c945 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -15,10 +15,10 @@ */ package com.android.launcher3.uioverrides; +import static com.android.app.animation.Interpolators.LINEAR; import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON; import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS; import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT; -import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE; import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA; diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java index b901a87753..a76eb437de 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java +++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java @@ -23,6 +23,7 @@ import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; import static android.view.View.GONE; import static android.view.View.VISIBLE; +import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD; import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY; import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED; import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey; @@ -59,6 +60,7 @@ import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; +import androidx.preference.SeekBarPreference; import androidx.preference.SwitchPreference; import com.android.launcher3.LauncherPrefs; @@ -106,6 +108,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { loadPluginPrefs(); maybeAddSandboxCategory(); addOnboardingPrefsCatergory(); + if (FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()) { + addAllAppsFromOverviewCatergory(); + } if (getActivity() != null) { getActivity().setTitle("Developer Options"); @@ -393,6 +398,33 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { } } + private void addAllAppsFromOverviewCatergory() { + PreferenceCategory category = newCategory("All Apps from Overview Config"); + + SeekBarPreference thresholdPref = new SeekBarPreference(getContext()); + thresholdPref.setTitle("Threshold to open All Apps from Overview"); + thresholdPref.setSingleLineTitle(false); + + // These values are 100x swipe up shift value (100 = where overview sits). + thresholdPref.setMax(500); + thresholdPref.setMin(105); + thresholdPref.setUpdatesContinuously(true); + thresholdPref.setIconSpaceReserved(false); + // Don't directly save to shared prefs, use LauncherPrefs instead. + thresholdPref.setPersistent(false); + thresholdPref.setOnPreferenceChangeListener((preference, newValue) -> { + LauncherPrefs.get(getContext()).put(ALL_APPS_OVERVIEW_THRESHOLD, newValue); + preference.setSummary(String.valueOf((int) newValue / 100f)); + return true; + }); + int value = LauncherPrefs.get(getContext()).get(ALL_APPS_OVERVIEW_THRESHOLD); + thresholdPref.setValue(value); + // For some reason the initial value is not triggering the summary update, so call manually. + thresholdPref.getOnPreferenceChangeListener().onPreferenceChange(thresholdPref, value); + + category.addPreference(thresholdPref); + } + private String toName(String action) { String str = action.replace("com.android.systemui.action.PLUGIN_", "") .replace("com.android.launcher3.action.PLUGIN_", ""); diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java index a68e753589..6279f634d6 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java @@ -116,8 +116,9 @@ public class FlagsFactory { boolean defaultValue = DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, key, defaultValueInCode); if (IS_DEBUG_DEVICE) { boolean currentValue = getSharedPreferences().getBoolean(key, defaultValue); - DebugFlag flag = new DeviceFlag(key, description, flagState, currentValue, - defaultValueInCode); + DebugFlag flag = new DeviceFlag(key, description, + (defaultValue == defaultValueInCode) ? flagState + : defaultValue ? ENABLED : DISABLED, currentValue, defaultValueInCode); sDebugFlags.add(flag); return flag; } else { diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java index 2a42175b5b..ed0a0d5172 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java @@ -15,14 +15,16 @@ */ package com.android.launcher3.uioverrides.states; -import static com.android.launcher3.anim.Interpolators.DEACCEL_2; +import static com.android.app.animation.Interpolators.DECELERATE_2; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS; import android.content.Context; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.Themes; import com.android.launcher3.views.ActivityContext; @@ -91,7 +93,7 @@ public class AllAppsState extends LauncherState { @Override public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) { PageAlphaProvider superPageAlphaProvider = super.getWorkspacePageAlphaProvider(launcher); - return new PageAlphaProvider(DEACCEL_2) { + return new PageAlphaProvider(DECELERATE_2) { @Override public float getPageAlpha(int pageIndex) { return launcher.getDeviceProfile().isTablet @@ -103,14 +105,52 @@ public class AllAppsState extends LauncherState { @Override public int getVisibleElements(Launcher launcher) { - // Don't add HOTSEAT_ICONS for non-tablets in ALL_APPS state. - return launcher.getDeviceProfile().isTablet ? ALL_APPS_CONTENT | HOTSEAT_ICONS - : ALL_APPS_CONTENT; + int elements = ALL_APPS_CONTENT | FLOATING_SEARCH_BAR; + // Only add HOTSEAT_ICONS for tablets in ALL_APPS state. + if (launcher.getDeviceProfile().isTablet) { + elements |= HOTSEAT_ICONS; + } + return elements; + } + + @Override + public int getFloatingSearchBarRestingMarginBottom(Launcher launcher) { + return 0; + } + + @Override + public int getFloatingSearchBarRestingMarginStart(Launcher launcher) { + DeviceProfile dp = launcher.getDeviceProfile(); + return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(); + } + + @Override + public int getFloatingSearchBarRestingMarginEnd(Launcher launcher) { + DeviceProfile dp = launcher.getDeviceProfile(); + return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(); + } + + @Override + public boolean shouldFloatingSearchBarUsePillWhenUnfocused(Launcher launcher) { + DeviceProfile dp = launcher.getDeviceProfile(); + return dp.isPhone && !dp.isLandscape; } @Override public LauncherState getHistoryForState(LauncherState previousState) { - return previousState == OVERVIEW ? OVERVIEW : NORMAL; + return previousState == BACKGROUND_APP ? QUICK_SWITCH_FROM_HOME + : previousState == OVERVIEW ? OVERVIEW : NORMAL; + } + + @Override + public float[] getOverviewScaleAndOffset(Launcher launcher) { + if (!FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()) { + return super.getOverviewScaleAndOffset(launcher); + } + // This handles the case of returning to the previous app from Overview -> All Apps gesture. + // This is the start scale/offset of overview that will be used for that transition. + // TODO (b/283336332): Translate in Y direction (ideally with overview resistance). + return new float[] {0.5f /* scale */, NO_OFFSET}; } @Override diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java index 214679acbe..396d0abeb0 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -15,7 +15,7 @@ */ package com.android.launcher3.uioverrides.states; -import static com.android.launcher3.anim.Interpolators.DEACCEL_2; +import static com.android.app.animation.Interpolators.DECELERATE_2; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW; import android.content.Context; @@ -97,7 +97,7 @@ public class OverviewState extends LauncherState { @Override public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) { - return new PageAlphaProvider(DEACCEL_2) { + return new PageAlphaProvider(DECELERATE_2) { @Override public float getPageAlpha(int pageIndex) { return 0; @@ -107,7 +107,32 @@ public class OverviewState extends LauncherState { @Override public int getVisibleElements(Launcher launcher) { - return CLEAR_ALL_BUTTON | OVERVIEW_ACTIONS; + int elements = CLEAR_ALL_BUTTON | OVERVIEW_ACTIONS; + DeviceProfile dp = launcher.getDeviceProfile(); + boolean showFloatingSearch; + if (dp.isPhone) { + // Only show search in phone overview in portrait mode. + showFloatingSearch = !dp.isLandscape; + } else { + // Only show search in tablet overview if taskbar is not visible. + showFloatingSearch = !dp.isTaskbarPresent || isTaskbarStashed(launcher); + } + if (showFloatingSearch) { + elements |= FLOATING_SEARCH_BAR; + } + return elements; + } + + @Override + public int getFloatingSearchBarRestingMarginBottom(Launcher launcher) { + return areElementsVisible(launcher, FLOATING_SEARCH_BAR) ? 0 + : super.getFloatingSearchBarRestingMarginBottom(launcher); + } + + @Override + public boolean shouldFloatingSearchBarUsePillWhenUnfocused(Launcher launcher) { + DeviceProfile dp = launcher.getDeviceProfile(); + return dp.isPhone && !dp.isLandscape; } @Override diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java index a8d7538687..6651c7399e 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java @@ -17,6 +17,20 @@ package com.android.launcher3.uioverrides.states; import static android.view.View.VISIBLE; +import static com.android.app.animation.Interpolators.ACCELERATE; +import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE; +import static com.android.app.animation.Interpolators.DECELERATE; +import static com.android.app.animation.Interpolators.DECELERATE_1_7; +import static com.android.app.animation.Interpolators.DECELERATE_3; +import static com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE; +import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE; +import static com.android.app.animation.Interpolators.FAST_OUT_SLOW_IN; +import static com.android.app.animation.Interpolators.FINAL_FRAME; +import static com.android.app.animation.Interpolators.INSTANT; +import static com.android.app.animation.Interpolators.LINEAR; +import static com.android.app.animation.Interpolators.OVERSHOOT_0_75; +import static com.android.app.animation.Interpolators.OVERSHOOT_1_2; +import static com.android.app.animation.Interpolators.clampToProgress; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.HINT_STATE_TWO_BUTTON; @@ -25,20 +39,6 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT; import static com.android.launcher3.QuickstepTransitionManager.TASKBAR_TO_HOME_DURATION; import static com.android.launcher3.WorkspaceStateTransitionAnimation.getWorkspaceSpringScaleAnimator; -import static com.android.launcher3.anim.Interpolators.ACCEL; -import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; -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.EMPHASIZED_ACCELERATE; -import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE; -import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; -import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; -import static com.android.launcher3.anim.Interpolators.INSTANT; -import static com.android.launcher3.anim.Interpolators.LINEAR; -import static com.android.launcher3.anim.Interpolators.OVERSHOOT_0_75; -import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; -import static com.android.launcher3.anim.Interpolators.clampToProgress; import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE; @@ -55,12 +55,14 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_T import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; import android.animation.ValueAnimator; +import android.util.Log; import com.android.launcher3.CellLayout; import com.android.launcher3.Hotseat; import com.android.launcher3.LauncherState; import com.android.launcher3.Workspace; import com.android.launcher3.states.StateAnimationConfig; +import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.touch.AllAppsSwipeController; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.util.DisplayController; @@ -94,7 +96,8 @@ public class QuickstepAtomicAnimationFactory extends @Override public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState, StateAnimationConfig config) { - + Log.d(TestProtocol.OVERVIEW_OVER_HOME, "creating animation fromState: " + + fromState + " toState: " + toState); RecentsView overview = mActivity.getOverviewPanel(); if ((fromState == OVERVIEW || fromState == OVERVIEW_SPLIT_SELECT) && toState == NORMAL) { overview.switchToScreenshot(() -> @@ -112,8 +115,8 @@ public class QuickstepAtomicAnimationFactory extends fromState == OVERVIEW_SPLIT_SELECT ? clampToProgress(LINEAR, 0.33f, 1) : LINEAR); - config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL); - config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL); + config.setInterpolator(ANIM_WORKSPACE_SCALE, DECELERATE); + config.setInterpolator(ANIM_WORKSPACE_FADE, ACCELERATE); if (DisplayController.getNavigationMode(mActivity).hasGestures && overview.getTaskViewCount() > 0) { @@ -139,9 +142,9 @@ public class QuickstepAtomicAnimationFactory extends } overview.snapToPage(DEFAULT_PAGE, Math.toIntExact(config.duration)); } else { - config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL); - config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f)); - config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7); + config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCELERATE_DECELERATE); + config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCELERATE, 0, 0.9f)); + config.setInterpolator(ANIM_OVERVIEW_FADE, DECELERATE_1_7); } Workspace<?> workspace = mActivity.getWorkspace(); @@ -167,8 +170,8 @@ public class QuickstepAtomicAnimationFactory extends || fromState == HINT_STATE_TWO_BUTTON) && toState == OVERVIEW) { if (DisplayController.getNavigationMode(mActivity).hasGestures) { config.setInterpolator(ANIM_WORKSPACE_SCALE, - fromState == NORMAL ? ACCEL : OVERSHOOT_1_2); - config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL); + fromState == NORMAL ? ACCELERATE : OVERSHOOT_1_2); + config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCELERATE); // Scrolling in tasks, so show straight away if (overview.getTaskViewCount() > 0) { @@ -196,7 +199,7 @@ public class QuickstepAtomicAnimationFactory extends config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_2); config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, OVERSHOOT_1_2); } else if (fromState == HINT_STATE && toState == NORMAL) { - config.setInterpolator(ANIM_DEPTH, DEACCEL_3); + config.setInterpolator(ANIM_DEPTH, DECELERATE_3); if (mHintToNormalDuration == -1) { ValueAnimator va = getWorkspaceSpringScaleAnimator(mActivity, mActivity.getWorkspace(), diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 8cbd6e8b47..b266bcd246 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -15,19 +15,22 @@ */ package com.android.launcher3.uioverrides.touchcontrollers; +import static com.android.app.animation.Interpolators.DECELERATE_3; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL_APPS_EDU; import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS; import static com.android.launcher3.LauncherAnimUtils.newCancelListener; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent; import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PULL_BACK_ALPHA; import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PULL_BACK_TRANSLATION; import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; -import static com.android.launcher3.anim.Interpolators.DEACCEL_3; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE; +import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; +import android.animation.AnimatorSet; import android.animation.ValueAnimator; import android.view.MotionEvent; import android.view.animation.Interpolator; @@ -41,24 +44,29 @@ import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.compat.AccessibilityManagerCompat; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.touch.SingleAxisSwipeDetector; +import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.TouchController; import com.android.quickstep.TaskUtils; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.util.OverviewToHomeAnim; import com.android.quickstep.views.RecentsView; +import java.util.function.Consumer; + /** * Handles swiping up on the nav bar to go home from launcher, e.g. overview or all apps. */ public class NavBarToHomeTouchController implements TouchController, SingleAxisSwipeDetector.Listener { - private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL_3; + private static final Interpolator PULLBACK_INTERPOLATOR = DECELERATE_3; // The min amount of overview scrim we keep during the transition. private static final float OVERVIEW_TO_HOME_SCRIM_MULTIPLIER = 0.5f; private final Launcher mLauncher; + private final Consumer<AnimatorSet> mCancelSplitRunnable; private final SingleAxisSwipeDetector mSwipeDetector; private final float mPullbackDistance; @@ -67,8 +75,14 @@ public class NavBarToHomeTouchController implements TouchController, private LauncherState mEndState = NORMAL; private AnimatorPlaybackController mCurrentAnimation; - public NavBarToHomeTouchController(Launcher launcher) { + /** + * @param cancelSplitRunnable Called when split placeholder view needs to be cancelled. + * Animation should be added to the provided AnimatorSet + */ + public NavBarToHomeTouchController(Launcher launcher, + Consumer<AnimatorSet> cancelSplitRunnable) { mLauncher = launcher; + mCancelSplitRunnable = cancelSplitRunnable; mSwipeDetector = new SingleAxisSwipeDetector(mLauncher, this, SingleAxisSwipeDetector.VERTICAL); mPullbackDistance = mLauncher.getResources().getDimension(R.dimen.home_pullback_distance); @@ -95,6 +109,10 @@ public class NavBarToHomeTouchController implements TouchController, } private boolean canInterceptTouch(MotionEvent ev) { + if (!isTrackpadMotionEvent(ev) && DisplayController.getNavigationMode(mLauncher) + == THREE_BUTTONS) { + return false; + } boolean cameFromNavBar = (ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) != 0; if (!cameFromNavBar) { return false; @@ -176,7 +194,10 @@ public class NavBarToHomeTouchController implements TouchController, recentsView.switchToScreenshot(null, () -> recentsView.finishRecentsAnimation(true /* toRecents */, null)); if (mStartState.overviewUi) { - new OverviewToHomeAnim(mLauncher, () -> onSwipeInteractionCompleted(mEndState)) + new OverviewToHomeAnim(mLauncher, () -> onSwipeInteractionCompleted(mEndState), + FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get() + ? mCancelSplitRunnable + : null) .animateWithVelocity(velocity); } else { mLauncher.getStateManager().goToState(mEndState, true, diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java index b7bafd8969..ca598c8411 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java @@ -16,19 +16,22 @@ package com.android.launcher3.uioverrides.touchcontrollers; +import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE; import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR; import static com.android.launcher3.LauncherAnimUtils.newCancelListener; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent; import static com.android.launcher3.Utilities.EDGE_NAV_BAR; import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; -import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; +import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS; import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; +import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.graphics.PointF; @@ -43,6 +46,7 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.taskbar.LauncherTaskbarUIController; import com.android.launcher3.uioverrides.QuickstepLauncher; +import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.VibratorWrapper; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.util.AnimatorControllerWithResistance; @@ -50,6 +54,8 @@ import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.OverviewToHomeAnim; import com.android.quickstep.views.RecentsView; +import java.util.function.Consumer; + /** * Touch controller which handles swipe and hold from the nav bar to go to Overview. Swiping above * the nav bar falls back to go to All Apps. Swiping from the nav bar without holding goes to the @@ -64,6 +70,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch private static final float TRANSLATION_ANIM_VELOCITY_DP_PER_MS = 0.8f; private final VibratorWrapper mVibratorWrapper; + private final Consumer<AnimatorSet> mCancelSplitRunnable; private final RecentsView mRecentsView; private final MotionPauseDetector mMotionPauseDetector; private final float mMotionPauseMinDisplacement; @@ -79,16 +86,26 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch // Normal to Hint animation has flag SKIP_OVERVIEW, so we update this scrim with this animator. private ObjectAnimator mNormalToHintOverviewScrimAnimator; - public NoButtonNavbarToOverviewTouchController(Launcher l) { + /** + * @param cancelSplitRunnable Called when split placeholder view needs to be cancelled. + * Animation should be added to the provided AnimatorSet + */ + public NoButtonNavbarToOverviewTouchController(Launcher l, + Consumer<AnimatorSet> cancelSplitRunnable) { super(l); mRecentsView = l.getOverviewPanel(); mMotionPauseDetector = new MotionPauseDetector(l); mMotionPauseMinDisplacement = ViewConfiguration.get(l).getScaledTouchSlop(); mVibratorWrapper = VibratorWrapper.INSTANCE.get(l.getApplicationContext()); + mCancelSplitRunnable = cancelSplitRunnable; } @Override protected boolean canInterceptTouch(MotionEvent ev) { + if (!isTrackpadMotionEvent(ev) && DisplayController.getNavigationMode(mLauncher) + == THREE_BUTTONS) { + return false; + } mDidTouchStartInNavBar = (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0; boolean isOneHandedModeActive = (SystemUiProxy.INSTANCE.get(mLauncher) .getLastSystemUiStateFlags() & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0; @@ -102,9 +119,6 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) { if (fromState == NORMAL && mDidTouchStartInNavBar) { return HINT_STATE; - } else if (fromState == OVERVIEW && isDragTowardPositive) { - // Don't allow swiping up to all apps. - return OVERVIEW; } return super.getTargetState(fromState, isDragTowardPositive); } @@ -190,6 +204,9 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch // state, but since the hint state tracks the entire screen without a clear endpoint, we // need to manually set the duration to a reasonable value. animator.setDuration(HINT_STATE.getTransitionDuration(mLauncher, true /* isToState */)); + AnimatorSet animatorSet = new AnimatorSet(); + mCancelSplitRunnable.accept(animatorSet); + animatorSet.start(); } if (FeatureFlags.ENABLE_PREMIUM_HAPTICS_ALL_APPS.get() && ((mFromState == NORMAL && mToState == ALL_APPS) @@ -261,7 +278,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch private void goToOverviewOrHomeOnDragEnd(float velocity) { boolean goToHomeInsteadOfOverview = !mMotionPauseDetector.isPaused(); if (goToHomeInsteadOfOverview) { - new OverviewToHomeAnim(mLauncher, () -> onSwipeInteractionCompleted(NORMAL)) + new OverviewToHomeAnim(mLauncher, () -> onSwipeInteractionCompleted(NORMAL), null) .animateWithVelocity(velocity); } if (mReachedOverview) { @@ -273,7 +290,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch mRecentsView.animate() .translationX(0) .translationY(0) - .setInterpolator(ACCEL_DEACCEL) + .setInterpolator(ACCELERATE_DECELERATE) .setDuration(duration) .withEndAction(goToHomeInsteadOfOverview ? null diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java index 80f5558315..6f421eb14a 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java @@ -16,21 +16,21 @@ package com.android.launcher3.uioverrides.touchcontrollers; import static android.view.MotionEvent.ACTION_DOWN; -import static android.view.MotionEvent.ACTION_MOVE; +import static com.android.app.animation.Interpolators.ACCELERATE_0_75; +import static com.android.app.animation.Interpolators.DECELERATE_3; +import static com.android.app.animation.Interpolators.LINEAR; +import static com.android.app.animation.Interpolators.scrollInterpolatorForVelocity; import static com.android.launcher3.LauncherAnimUtils.newCancelListener; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS; import static com.android.launcher3.LauncherState.QUICK_SWITCH_FROM_HOME; import static com.android.launcher3.MotionEventsUtils.isTrackpadFourFingerSwipe; +import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent; import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe; import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD; import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; -import static com.android.launcher3.anim.Interpolators.ACCEL_0_75; -import static com.android.launcher3.anim.Interpolators.DEACCEL_3; -import static com.android.launcher3.anim.Interpolators.LINEAR; -import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN; @@ -46,6 +46,7 @@ import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW; import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM; import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT; import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP; +import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS; import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC; import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs; import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET; @@ -74,6 +75,7 @@ import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.BaseSwipeDetector; import com.android.launcher3.touch.BothAxesSwipeDetector; import com.android.launcher3.uioverrides.QuickstepLauncher; +import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.TouchController; import com.android.launcher3.util.VibratorWrapper; import com.android.quickstep.SystemUiProxy; @@ -84,6 +86,7 @@ import com.android.quickstep.util.WorkspaceRevealAnim; import com.android.quickstep.views.DesktopTaskView; import com.android.quickstep.views.LauncherRecentsView; import com.android.quickstep.views.RecentsView; +import com.android.systemui.shared.system.InteractionJankMonitorWrapper; /** * Handles quick switching to a recent task from the home screen. To give as much flexibility to @@ -93,8 +96,8 @@ public class NoButtonQuickSwitchTouchController implements TouchController, BothAxesSwipeDetector.Listener { private static final float Y_ANIM_MIN_PROGRESS = 0.25f; - private static final Interpolator FADE_OUT_INTERPOLATOR = DEACCEL_3; - private static final Interpolator TRANSLATE_OUT_INTERPOLATOR = ACCEL_0_75; + private static final Interpolator FADE_OUT_INTERPOLATOR = DECELERATE_3; + private static final Interpolator TRANSLATE_OUT_INTERPOLATOR = ACCELERATE_0_75; private static final Interpolator SCALE_DOWN_INTERPOLATOR = LINEAR; private static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300; @@ -110,7 +113,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController, newCancelListener(this::clearState); private boolean mNoIntercept; - private Boolean mIsTrackpadFourFingerSwipe; private LauncherState mStartState; private boolean mIsHomeScreenVisible = true; @@ -136,9 +138,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, @Override public boolean onControllerInterceptTouchEvent(MotionEvent ev) { - int action = ev.getActionMasked(); - if (action == ACTION_DOWN) { - mIsTrackpadFourFingerSwipe = null; + if (ev.getActionMasked() == ACTION_DOWN) { mNoIntercept = !canInterceptTouch(ev); if (mNoIntercept) { return false; @@ -147,13 +147,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController, // Only detect horizontal swipe for intercept, then we will allow swipe up as well. mSwipeDetector.setDetectableScrollConditions(DIRECTION_RIGHT, false /* ignoreSlopWhenSettling */); - } else if (isTrackpadMultiFingerSwipe(ev) && mIsTrackpadFourFingerSwipe == null - && action == ACTION_MOVE) { - mIsTrackpadFourFingerSwipe = isTrackpadFourFingerSwipe(ev); - mNoIntercept = !mIsTrackpadFourFingerSwipe; - if (mNoIntercept) { - return false; - } } if (mNoIntercept) { @@ -170,6 +163,10 @@ public class NoButtonQuickSwitchTouchController implements TouchController, } private boolean canInterceptTouch(MotionEvent ev) { + if (!isTrackpadMotionEvent(ev) && DisplayController.getNavigationMode(mLauncher) + == THREE_BUTTONS) { + return false; + } if (!mLauncher.isInState(LauncherState.NORMAL)) { return false; } @@ -184,6 +181,9 @@ public class NoButtonQuickSwitchTouchController implements TouchController, // TODO(b/268075592): add support for quickswitch to/from desktop return false; } + if (isTrackpadMultiFingerSwipe(ev)) { + return isTrackpadFourFingerSwipe(ev); + } return true; } @@ -191,6 +191,9 @@ public class NoButtonQuickSwitchTouchController implements TouchController, public void onDragStart(boolean start) { mMotionPauseDetector.clear(); if (start) { + InteractionJankMonitorWrapper.begin(mRecentsView, + InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); + mStartState = mLauncher.getStateManager().getState(); mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseDetected); @@ -325,6 +328,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, if (mMotionPauseDetector.isPaused() && noFling) { // Going to Overview. cancelAnimations(); + InteractionJankMonitorWrapper.cancel(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); StateAnimationConfig config = new StateAnimationConfig(); config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW; @@ -441,6 +445,8 @@ public class NoButtonQuickSwitchTouchController implements TouchController, RecentsView.SCROLL_VIBRATION_PRIMITIVE, RecentsView.SCROLL_VIBRATION_PRIMITIVE_SCALE, RecentsView.SCROLL_VIBRATION_FALLBACK); + } else { + InteractionJankMonitorWrapper.cancel(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); } nonOverviewAnim.setDuration(Math.max(xDuration, yDuration)); @@ -462,6 +468,11 @@ public class NoButtonQuickSwitchTouchController implements TouchController, : targetState.ordinal > mStartState.ordinal ? LAUNCHER_UNKNOWN_SWIPEUP : LAUNCHER_UNKNOWN_SWIPEDOWN)); + + if (targetState == QUICK_SWITCH_FROM_HOME) { + InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); + } + mLauncher.getStateManager().goToState(targetState, false, forEndCallback(this::clearState)); } diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java index 8368f9ca03..e30fe667ff 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java @@ -24,11 +24,12 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import android.view.MotionEvent; +import com.android.app.animation.Interpolators; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.allapps.AllAppsTransitionController; -import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.AbstractStateChangeTouchController; import com.android.launcher3.touch.AllAppsSwipeController; @@ -92,9 +93,9 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr @Override protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) { if (fromState == ALL_APPS && !isDragTowardPositive) { - return NORMAL; - } else if (fromState == OVERVIEW) { - return isDragTowardPositive ? OVERVIEW : NORMAL; + return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get() + ? mLauncher.getStateManager().getLastState() + : NORMAL; } else if (fromState == NORMAL && isDragTowardPositive) { return ALL_APPS; } diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java index f941b02065..9a35bb2ae7 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java @@ -15,12 +15,12 @@ */ package com.android.launcher3.uioverrides.touchcontrollers; +import static com.android.app.animation.Interpolators.ACCELERATE_2; +import static com.android.app.animation.Interpolators.DECELERATE_2; +import static com.android.app.animation.Interpolators.INSTANT; +import static com.android.app.animation.Interpolators.LINEAR; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.QUICK_SWITCH_FROM_HOME; -import static com.android.launcher3.anim.Interpolators.ACCEL_2; -import static com.android.launcher3.anim.Interpolators.DEACCEL_2; -import static com.android.launcher3.anim.Interpolators.INSTANT; -import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND; import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE; @@ -128,14 +128,14 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll } private void setupInterpolators(StateAnimationConfig stateAnimationConfig) { - stateAnimationConfig.setInterpolator(ANIM_WORKSPACE_FADE, DEACCEL_2); - stateAnimationConfig.setInterpolator(ANIM_ALL_APPS_FADE, DEACCEL_2); + stateAnimationConfig.setInterpolator(ANIM_WORKSPACE_FADE, DECELERATE_2); + stateAnimationConfig.setInterpolator(ANIM_ALL_APPS_FADE, DECELERATE_2); if (DisplayController.getNavigationMode(mLauncher) == NavigationMode.NO_BUTTON) { // Overview lives to the left of workspace, so translate down later than over - stateAnimationConfig.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL_2); - stateAnimationConfig.setInterpolator(ANIM_VERTICAL_PROGRESS, ACCEL_2); - stateAnimationConfig.setInterpolator(ANIM_OVERVIEW_SCALE, ACCEL_2); - stateAnimationConfig.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, ACCEL_2); + stateAnimationConfig.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCELERATE_2); + stateAnimationConfig.setInterpolator(ANIM_VERTICAL_PROGRESS, ACCELERATE_2); + stateAnimationConfig.setInterpolator(ANIM_OVERVIEW_SCALE, ACCELERATE_2); + stateAnimationConfig.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, ACCELERATE_2); stateAnimationConfig.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT); } else { stateAnimationConfig.setInterpolator(ANIM_WORKSPACE_TRANSLATE, LINEAR); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index 395833ffea..26ab3d6c52 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -76,7 +76,7 @@ public class StatusBarTouchController implements TouchController { private void dispatchTouchEvent(MotionEvent ev) { if (mSystemUiProxy.isActive()) { mLastAction = ev.getActionMasked(); - mSystemUiProxy.onStatusBarMotionEvent(ev); + mSystemUiProxy.onStatusBarTouchEvent(ev); } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java index eddc50c64f..3d94857848 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java @@ -27,13 +27,13 @@ import android.view.MotionEvent; import android.view.View; import android.view.animation.Interpolator; +import com.android.app.animation.Interpolators; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; -import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.touch.BaseSwipeDetector; import com.android.launcher3.touch.PagedOrientationHandler; |