diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java index 4fbe8cfd26..e8f2496e6e 100644 --- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java +++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java @@ -36,7 +36,6 @@ import com.android.launcher3.Utilities; import com.android.launcher3.allapps.FloatingHeaderRow; import com.android.launcher3.allapps.FloatingHeaderView; import com.android.launcher3.anim.AlphaUpdateListener; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.keyboard.FocusIndicatorHelper; import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper; import com.android.launcher3.model.data.ItemInfo; @@ -65,7 +64,6 @@ public class PredictionRowView private FloatingHeaderView mParent; private boolean mPredictionsEnabled = false; - private @Nullable List mPendingPredictedItems; private OnLongClickListener mOnIconLongClickListener = ItemLongClickListener.INSTANCE_ALL_APPS; public PredictionRowView(@NonNull Context context) { @@ -159,18 +157,10 @@ public class PredictionRowView * we can optimize by swapping them in place. */ public void setPredictedApps(List items) { - if (!FeatureFlags.ENABLE_APP_PREDICTIONS_WHILE_VISIBLE.get() - && !mActivityContext.isBindingItems() - && isShown() - && getWindowVisibility() == View.VISIBLE) { - mPendingPredictedItems = items; - return; - } applyPredictedApps(items); } private void applyPredictedApps(List items) { - mPendingPredictedItems = null; mPredictedApps.clear(); mPredictedApps.addAll(items.stream() .filter(itemInfo -> itemInfo instanceof WorkspaceItemInfo) @@ -265,13 +255,4 @@ public class PredictionRowView return getChildAt(0); } - - @Override - public void onVisibilityAggregated(boolean isVisible) { - super.onVisibilityAggregated(isVisible); - - if (mPendingPredictedItems != null && !isVisible) { - applyPredictedApps(mPendingPredictedItems); - } - } } diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java index 0a2a9b37ba..5c2f6b1418 100644 --- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java @@ -41,7 +41,6 @@ import com.android.launcher3.Hotseat; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.graphics.DragPreviewProvider; @@ -279,32 +278,6 @@ public class HotseatPredictionController implements DragController.DragListener, * Sets or updates the predicted items */ public void setPredictedItems(FixedContainerItems items) { - boolean shouldIgnoreVisibility = FeatureFlags.ENABLE_APP_PREDICTIONS_WHILE_VISIBLE.get() - || mLauncher.isWorkspaceLoading() - || mPredictedItems.equals(items.items) - || mHotseat.getShortcutsAndWidgets().getChildCount() < mHotSeatItemsCount; - if (!shouldIgnoreVisibility - && mHotseat.isShown() - && mHotseat.getWindowVisibility() == View.VISIBLE) { - mHotseat.setOnVisibilityAggregatedCallback((isVisible) -> { - if (isVisible) { - return; - } - mHotseat.setOnVisibilityAggregatedCallback(null); - - applyPredictedItems(items); - }); - } else { - mHotseat.setOnVisibilityAggregatedCallback(null); - - applyPredictedItems(items); - } - } - - /** - * Sets or updates the predicted items only once the hotseat becomes hidden to the user - */ - private void applyPredictedItems(FixedContainerItems items) { mPredictedItems = new ArrayList(items.items); if (mPredictedItems.isEmpty()) { HotseatRestoreHelper.restoreBackup(mLauncher); diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 47a224a123..04c9e56dc8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -15,8 +15,6 @@ */ package com.android.launcher3.taskbar; -import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; - import static com.android.launcher3.QuickstepTransitionManager.TRANSIENT_TASKBAR_TRANSITION_DURATION; import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_EDU_TOOLTIP; import static com.android.launcher3.statemanager.BaseState.FLAG_NON_INTERACTIVE; @@ -55,7 +53,6 @@ import com.android.quickstep.util.GroupTask; import com.android.quickstep.views.RecentsView; import java.io.PrintWriter; -import java.util.Set; /** * A data source which integrates with a Launcher instance @@ -244,8 +241,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController { : mLauncher.getColor(R.color.taskbar_background); TaskTransitionSpec customTaskAnimationSpec = new TaskTransitionSpec( - taskAnimationBackgroundColor, - Set.of(ITYPE_EXTRA_NAVIGATION_BAR) + taskAnimationBackgroundColor ); WindowManagerGlobal.getWindowManagerService() .setTaskTransitionSpec(customTaskAnimationSpec); diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 2251c34e48..951a9b61dc 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -35,7 +35,6 @@ 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.ENABLE_WIDGET_PICKER_DEPTH; 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; @@ -169,7 +168,6 @@ 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; @@ -187,7 +185,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Stream; @@ -254,8 +251,7 @@ public class QuickstepLauncher extends Launcher { mDesktopVisibilityController = new DesktopVisibilityController(this); mHotseatPredictionController = new HotseatPredictionController(this); - mEnableWidgetDepth = ENABLE_WIDGET_PICKER_DEPTH.get() - && SystemProperties.getBoolean("ro.launcher.depth.widget", true); + mEnableWidgetDepth = SystemProperties.getBoolean("ro.launcher.depth.widget", true); getWorkspace().addOverlayCallback(progress -> onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX)); } diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index af63a071eb..7de6b189a9 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -21,8 +21,8 @@ import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY; -import static com.android.launcher3.Utilities.isTrackpadMotionEvent; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN; +import static com.android.quickstep.MotionEventsUtils.isTrackpadMotionEvent; import android.graphics.PointF; import android.util.SparseArray; @@ -91,10 +91,11 @@ public class StatusBarTouchController implements TouchController { if (!mCanIntercept) { return false; } + mDownEvents.clear(); mDownEvents.put(pid, new PointF(ev.getX(), ev.getY())); } else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { - // Check!! should only set it only when threshold is not entered. - mDownEvents.put(pid, new PointF(ev.getX(idx), ev.getY(idx))); + // Check!! should only set it only when threshold is not entered. + mDownEvents.put(pid, new PointF(ev.getX(idx), ev.getY(idx))); } if (!mCanIntercept) { return false; diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 752e748a45..933fb49371 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -369,7 +369,7 @@ public abstract class AbsSwipeUpHandler, mIsTaskbarAllAppsOpen = controller != null && controller.isTaskbarAllAppsOpen(); mTaskbarAppWindowThreshold = res.getDimensionPixelSize(R.dimen.taskbar_app_window_threshold); - boolean swipeWillNotShowTaskbar = mTaskbarAlreadyOpen; + boolean swipeWillNotShowTaskbar = mTaskbarAlreadyOpen || mGestureState.isTrackpadGesture(); mTaskbarHomeOverviewThreshold = swipeWillNotShowTaskbar ? 0 : res.getDimensionPixelSize(R.dimen.taskbar_home_overview_threshold); @@ -2317,7 +2317,7 @@ public abstract class AbsSwipeUpHandler, return displacement; } - if (mTaskbarAlreadyOpen || mIsTaskbarAllAppsOpen) { + if (mTaskbarAlreadyOpen || mIsTaskbarAllAppsOpen || mGestureState.isTrackpadGesture()) { return displacement; } diff --git a/quickstep/src/com/android/quickstep/MotionEventsUtils.java b/quickstep/src/com/android/quickstep/MotionEventsUtils.java new file mode 100644 index 0000000000..142febf829 --- /dev/null +++ b/quickstep/src/com/android/quickstep/MotionEventsUtils.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.quickstep; + +import static android.view.MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE; + +import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE; + +import android.annotation.TargetApi; +import android.os.Build; +import android.view.MotionEvent; + +/** Handles motion events from trackpad. */ +public class MotionEventsUtils { + + /** {@link MotionEvent#CLASSIFICATION_MULTI_FINGER_SWIPE} is hidden. */ + public static final int CLASSIFICATION_MULTI_FINGER_SWIPE = 4; + + @TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) + public static boolean isTrackpadScroll(MotionEvent event) { + return ENABLE_TRACKPAD_GESTURE.get() + && event.getClassification() == CLASSIFICATION_TWO_FINGER_SWIPE; + } + + @TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) + public static boolean isTrackpadMultiFingerSwipe(MotionEvent event) { + return ENABLE_TRACKPAD_GESTURE.get() + && event.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE; + } + + public static boolean isTrackpadMotionEvent(MotionEvent event) { + return isTrackpadScroll(event) || isTrackpadMultiFingerSwipe(event); + } +} diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java index b9390b854b..7500e79118 100644 --- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java +++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java @@ -18,7 +18,6 @@ package com.android.quickstep; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Surface.ROTATION_0; -import static com.android.launcher3.Utilities.isTrackpadMotionEvent; import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN; import static com.android.launcher3.util.DisplayController.CHANGE_ALL; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; @@ -26,6 +25,8 @@ import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION; import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS; +import static com.android.quickstep.MotionEventsUtils.isTrackpadMotionEvent; +import static com.android.quickstep.MotionEventsUtils.isTrackpadMultiFingerSwipe; import android.content.Context; import android.content.res.Resources; @@ -233,10 +234,7 @@ public class RotationTouchHelper implements DisplayInfoChangeListener { * @return whether the coordinates of the {@param event} is in the swipe up gesture region. */ public boolean isInSwipeUpTouchRegion(MotionEvent event, BaseActivityInterface activity) { - if (isTrackpadMotionEvent(event)) { - return !activity.isResumed(); - } - return mOrientationTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY()); + return isInSwipeUpTouchRegion(event, 0, activity); } /** @@ -246,7 +244,7 @@ public class RotationTouchHelper implements DisplayInfoChangeListener { public boolean isInSwipeUpTouchRegion(MotionEvent event, int pointerIndex, BaseActivityInterface activity) { if (isTrackpadMotionEvent(event)) { - return !activity.isResumed(); + return isTrackpadMultiFingerSwipe(event) && !activity.isResumed(); } return mOrientationTouchTransformer.touchInValidSwipeRegions(event.getX(pointerIndex), event.getY(pointerIndex)); diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java index e58845a231..255b9107b9 100644 --- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java +++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java @@ -18,7 +18,6 @@ package com.android.quickstep; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_SELECTIONS; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP; import android.app.Activity; @@ -393,10 +392,7 @@ public interface TaskShortcutFactory { taskContainer.getThumbnailView().getTaskOverlay() .getModalStateSystemShortcut( taskContainer.getItemInfo(), taskContainer.getTaskView()); - if (ENABLE_OVERVIEW_SELECTIONS.get()) { - return createSingletonShortcutList(modalStateSystemShortcut); - } - return null; + return createSingletonShortcutList(modalStateSystemShortcut); } }; } diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index d44a5b87ad..85bf761f12 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -18,12 +18,14 @@ package com.android.quickstep; import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; +import static android.view.MotionEvent.ACTION_POINTER_DOWN; +import static android.view.MotionEvent.ACTION_POINTER_UP; import static android.view.MotionEvent.ACTION_UP; -import static com.android.launcher3.Utilities.isTrackpadMotionEvent; import static com.android.launcher3.config.FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.GestureState.DEFAULT_STATE; +import static com.android.quickstep.MotionEventsUtils.isTrackpadMultiFingerSwipe; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_DOWN; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_UP; @@ -189,6 +191,12 @@ public class TouchInteractionService extends Service sIsInitialized = true; } + @BinderThread + @Override + public void onTaskbarToggled() { + // To be implemented. + } + @BinderThread public void onOverviewToggle() { TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onOverviewToggle"); @@ -622,7 +630,7 @@ public class TouchInteractionService extends Service Object traceToken = TraceHelper.INSTANCE.beginFlagsOverride( TraceHelper.FLAG_ALLOW_BINDER_TRACKING); - final int action = event.getAction(); + final int action = event.getActionMasked(); if (action == ACTION_DOWN) { mRotationTouchHelper.setOrientationTransformIfNeeded(event); @@ -633,7 +641,7 @@ public class TouchInteractionService extends Service // onConsumerInactive and wipe the previous gesture state GestureState prevGestureState = new GestureState(mGestureState); GestureState newGestureState = createGestureState(mGestureState, - isTrackpadMotionEvent(event)); + isTrackpadMultiFingerSwipe(event)); newGestureState.setSwipeUpStartTimeMs(SystemClock.uptimeMillis()); mConsumer.onConsumerAboutToBeSwitched(); mGestureState = newGestureState; @@ -641,7 +649,8 @@ public class TouchInteractionService extends Service mUncheckedConsumer = mConsumer; } else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode() && mDeviceState.canTriggerAssistantAction(event)) { - mGestureState = createGestureState(mGestureState, isTrackpadMotionEvent(event)); + mGestureState = createGestureState(mGestureState, + isTrackpadMultiFingerSwipe(event)); // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we // should not interrupt it. QuickSwitch assumes that interruption can only // happen if the next gesture is also quick switch. @@ -688,7 +697,12 @@ public class TouchInteractionService extends Service if (cancelGesture) { event.setAction(ACTION_CANCEL); } - mUncheckedConsumer.onMotionEvent(event); + + // Skip ACTION_POINTER_DOWN and ACTION_POINTER_UP events from trackpad. + if (!mGestureState.isTrackpadGesture() || (action != ACTION_POINTER_DOWN + && action != ACTION_POINTER_UP)) { + mUncheckedConsumer.onMotionEvent(event); + } if (cleanUpConsumer) { reset(); diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java index 992618a147..8ccbf1e46a 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java @@ -17,9 +17,9 @@ package com.android.quickstep.inputconsumers; import static android.view.MotionEvent.INVALID_POINTER_ID; -import static com.android.launcher3.Utilities.isTrackpadMotionEvent; import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_TOUCHING; +import static com.android.quickstep.MotionEventsUtils.isTrackpadMotionEvent; import android.content.Context; import android.content.res.Resources; diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt index 0da70a9249..428bd95159 100644 --- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt +++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt @@ -75,6 +75,7 @@ class TaskMenuViewWithArrow : ArrowPopup { clipToOutline = true shouldScaleArrow = true + mIsArrowRotated = true // This synchronizes the arrow and menu to open at the same time OPEN_CHILD_FADE_START_DELAY = OPEN_FADE_START_DELAY OPEN_CHILD_FADE_DURATION = OPEN_FADE_DURATION diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index bf492a9313..03afba11c1 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -27,10 +27,6 @@ import android.view.ViewDebug; import android.view.ViewGroup; import android.widget.FrameLayout; -import androidx.annotation.Nullable; - -import java.util.function.Consumer; - /** * View class that represents the bottom row of the home screen. */ @@ -43,8 +39,6 @@ public class Hotseat extends CellLayout implements Insettable { private boolean mHasVerticalHotseat; private Workspace mWorkspace; private boolean mSendTouchToWorkspace; - @Nullable - private Consumer mOnVisibilityAggregatedCallback; private final View mQsb; @@ -150,20 +144,6 @@ public class Hotseat extends CellLayout implements Insettable { return false; } - @Override - public void onVisibilityAggregated(boolean isVisible) { - super.onVisibilityAggregated(isVisible); - - if (mOnVisibilityAggregatedCallback != null) { - mOnVisibilityAggregatedCallback.accept(isVisible); - } - } - - /** Sets a callback to be called onVisibilityAggregated */ - public void setOnVisibilityAggregatedCallback(@Nullable Consumer callback) { - mOnVisibilityAggregatedCallback = callback; - } - @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 2fb0fa6207..4ac7f078bf 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -18,7 +18,6 @@ package com.android.launcher3; import static com.android.launcher3.LauncherPrefs.GRID_NAME; import static com.android.launcher3.Utilities.dpiFromPx; -import static com.android.launcher3.config.FeatureFlags.ENABLE_DEVICE_PROFILE_LOGGING; import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME; import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; @@ -70,8 +69,6 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -680,18 +677,6 @@ public class InvariantDeviceProfile { float screenHeight = config.screenHeightDp * res.getDisplayMetrics().density; int rotation = WindowManagerProxy.INSTANCE.get(context).getRotation(context); - if (Utilities.IS_DEBUG_DEVICE && ENABLE_DEVICE_PROFILE_LOGGING.get()) { - StringWriter stringWriter = new StringWriter(); - PrintWriter printWriter = new PrintWriter(stringWriter); - DisplayController.INSTANCE.get(context).dump(printWriter); - printWriter.flush(); - Log.d("b/253338238", "getDeviceProfile -" - + "\nconfig: " + config - + "\ndisplayMetrics: " + res.getDisplayMetrics() - + "\nrotation: " + rotation - + "\n" + stringWriter, - new Exception()); - } return getBestMatch(screenWidth, screenHeight, rotation); } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 8e5310172c..06ea72c7ee 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -19,7 +19,6 @@ package com.android.launcher3; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.content.pm.ActivityInfo.CONFIG_UI_MODE; -import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO; import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; @@ -86,7 +85,6 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.database.sqlite.SQLiteDatabase; -import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Rect; import android.graphics.RectF; @@ -117,7 +115,6 @@ import android.view.ViewTreeObserver.OnPreDrawListener; import android.view.WindowManager.LayoutParams; import android.view.accessibility.AccessibilityEvent; import android.view.animation.OvershootInterpolator; -import android.widget.ImageView; import android.widget.Toast; import androidx.annotation.CallSuper; @@ -151,7 +148,6 @@ import com.android.launcher3.dragndrop.LauncherDragController; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderGridOrganizer; import com.android.launcher3.folder.FolderIcon; -import com.android.launcher3.icons.BitmapRenderer; import com.android.launcher3.icons.IconCache; import com.android.launcher3.keyboard.ViewGroupFocusHelper; import com.android.launcher3.logger.LauncherAtom; @@ -306,8 +302,6 @@ public class Launcher extends StatefulActivity private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5; @Thunk @VisibleForTesting public static final int NEW_APPS_ANIMATION_DELAY = 500; - private static final int THEME_CROSS_FADE_ANIMATION_DURATION = 375; - private static final String DISPLAY_WORKSPACE_TRACE_METHOD_NAME = "DisplayWorkspaceFirstFrame"; private static final String DISPLAY_ALL_APPS_TRACE_METHOD_NAME = "DisplayAllApps"; public static final int DISPLAY_WORKSPACE_TRACE_COOKIE = 0; @@ -504,7 +498,6 @@ public class Launcher extends StatefulActivity mAppWidgetHolder.startListening(); setupViews(); - crossFadeWithPreviousAppearance(); mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots); boolean internalStateHandled = ACTIVITY_TRACKER.handleCreate(this); @@ -1579,16 +1572,6 @@ public class Launcher extends StatefulActivity public Object onRetainNonConfigurationInstance() { NonConfigInstance instance = new NonConfigInstance(); instance.config = new Configuration(mOldConfig); - - int width = mDragLayer.getWidth(); - int height = mDragLayer.getHeight(); - - if (FeatureFlags.ENABLE_LAUNCHER_ACTIVITY_THEME_CROSSFADE.get() - && width > 0 - && height > 0) { - instance.snapshot = - BitmapRenderer.createHardwareBitmap(width, height, mDragLayer::draw); - } return instance; } @@ -3285,41 +3268,6 @@ public class Launcher extends StatefulActivity return (T) activityContext; } - /** - * Cross-fades the launcher's updated appearance with its previous appearance. - * - * This method is used to cross-fade UI updates on activity creation, specifically dark mode - * updates. - */ - private void crossFadeWithPreviousAppearance() { - NonConfigInstance lastInstance = (NonConfigInstance) getLastNonConfigurationInstance(); - - if (lastInstance == null || lastInstance.snapshot == null) { - return; - } - - ImageView crossFadeHelper = new ImageView(this); - crossFadeHelper.setImageBitmap(lastInstance.snapshot); - crossFadeHelper.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); - - InsettableFrameLayout.LayoutParams layoutParams = new InsettableFrameLayout.LayoutParams( - InsettableFrameLayout.LayoutParams.MATCH_PARENT, - InsettableFrameLayout.LayoutParams.MATCH_PARENT); - - layoutParams.ignoreInsets = true; - - crossFadeHelper.setLayoutParams(layoutParams); - - getRootView().addView(crossFadeHelper); - - crossFadeHelper - .animate() - .setDuration(THEME_CROSS_FADE_ANIMATION_DURATION) - .alpha(0f) - .withEndAction(() -> getRootView().removeView(crossFadeHelper)) - .start(); - } - public boolean supportsAdaptiveIconAnimation(View clickedView) { return false; } @@ -3351,7 +3299,6 @@ public class Launcher extends StatefulActivity private static class NonConfigInstance { public Configuration config; - public Bitmap snapshot; } @Override diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 379d1e5432..13efa674f3 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -16,9 +16,6 @@ package com.android.launcher3; -import static android.view.InputDevice.SOURCE_TOUCHSCREEN; - -import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE; import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED; import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_ICON_BADGED; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; @@ -725,13 +722,6 @@ public final class Utilities { )); } - public static boolean isTrackpadMotionEvent(MotionEvent event) { - // TODO: ideally should use event.getClassification(), but currently only the move - // events get assigned the correct classification. - return ENABLE_TRACKPAD_GESTURE.get() - && (event.getSource() & SOURCE_TOUCHSCREEN) != SOURCE_TOUCHSCREEN; - } - /** Logs the Scale and Translate properties of a matrix. Ignores skew and perspective. */ public static void logMatrix(String label, Matrix matrix) { float[] matrixValues = new float[9]; diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index d902d0359e..a9e3d8d4bd 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -65,98 +65,109 @@ public final class FeatureFlags { * Declare a new ToggleableFlag below. Give it a unique key (e.g. "QSB_ON_FIRST_SCREEN"), * and set a default value for the flag. This will be the default value on Debug builds. */ + // b/270390028 public static final BooleanFlag ENABLE_INPUT_CONSUMER_REASON_LOGGING = getDebugFlag( "ENABLE_INPUT_CONSUMER_REASON_LOGGING", true, "Log the reason why an Input Consumer was selected for a gesture."); + // b/270389990 public static final BooleanFlag ENABLE_GESTURE_ERROR_DETECTION = getDebugFlag( "ENABLE_GESTURE_ERROR_DETECTION", true, "Analyze gesture events and log detected errors"); // When enabled the promise icon is visible in all apps while installation an app. + // b/270390012 public static final BooleanFlag PROMISE_APPS_IN_ALL_APPS = getDebugFlag( "PROMISE_APPS_IN_ALL_APPS", false, "Add promise icon in all-apps"); + // b/270390904 public static final BooleanFlag KEYGUARD_ANIMATION = getDebugFlag( "KEYGUARD_ANIMATION", false, "Enable animation for keyguard going away on wallpaper"); + // b/270390907 public static final BooleanFlag ENABLE_DEVICE_SEARCH = new DeviceFlag( "ENABLE_DEVICE_SEARCH", true, "Allows on device search in all apps"); + // b/270390286 public static final BooleanFlag ENABLE_FLOATING_SEARCH_BAR = new DeviceFlag("ENABLE_FLOATING_SEARCH_BAR", false, "Keep All Apps search bar at the bottom (but above keyboard if open)"); + // b/270390930 public static final BooleanFlag ENABLE_HIDE_HEADER = new DeviceFlag("ENABLE_HIDE_HEADER", true, "Hide header on keyboard before typing in all apps"); + // b/270390779 public static final BooleanFlag ENABLE_EXPANDING_PAUSE_WORK_BUTTON = getDebugFlag( "ENABLE_EXPANDING_PAUSE_WORK_BUTTON", true, "Expand and collapse pause work button while scrolling"); + // b/270390950 public static final BooleanFlag ENABLE_RECENT_BLOCK = getDebugFlag("ENABLE_RECENT_BLOCK", false, "Show recently tapped search target block in zero state"); + // b/270391455 public static final BooleanFlag COLLECT_SEARCH_HISTORY = new DeviceFlag( "COLLECT_SEARCH_HISTORY", false, "Allow launcher to collect search history for log"); + // b/270390937 public static final BooleanFlag ENABLE_TWOLINE_ALLAPPS = getDebugFlag( "ENABLE_TWOLINE_ALLAPPS", false, "Enables two line label inside all apps."); + // b/270391397 public static final BooleanFlag ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING = new DeviceFlag( "ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING", false, "Allows on device search in all apps logging"); + // b/270391693 public static final BooleanFlag IME_STICKY_SNACKBAR_EDU = getDebugFlag( "IME_STICKY_SNACKBAR_EDU", true, "Show sticky IME edu in AllApps"); + // b/270391653 public static final BooleanFlag ENABLE_PEOPLE_TILE_PREVIEW = getDebugFlag( "ENABLE_PEOPLE_TILE_PREVIEW", false, "Experimental: Shows conversation shortcuts on home screen as search results"); + // b/270391638 public static final BooleanFlag FOLDER_NAME_MAJORITY_RANKING = getDebugFlag( "FOLDER_NAME_MAJORITY_RANKING", true, "Suggests folder names based on majority based ranking."); + // b/270391706 public static final BooleanFlag INJECT_FALLBACK_APP_CORPUS_RESULTS = new DeviceFlag( "INJECT_FALLBACK_APP_CORPUS_RESULTS", false, "Inject " + "fallback app corpus result when AiAi fails to return it."); + // b/270391641 public static final BooleanFlag ASSISTANT_GIVES_LAUNCHER_FOCUS = getDebugFlag( "ASSISTANT_GIVES_LAUNCHER_FOCUS", false, "Allow Launcher to handle nav bar gestures while Assistant is running over it"); + // b/270392203 public static final BooleanFlag ENABLE_BULK_WORKSPACE_ICON_LOADING = getDebugFlag( "ENABLE_BULK_WORKSPACE_ICON_LOADING", true, "Enable loading workspace icons in bulk."); + // b/270392465 public static final BooleanFlag ENABLE_BULK_ALL_APPS_ICON_LOADING = getDebugFlag( "ENABLE_BULK_ALL_APPS_ICON_LOADING", true, "Enable loading all apps icons in bulk."); - // Keep as DeviceFlag for remote disable in emergency. - public static final BooleanFlag ENABLE_OVERVIEW_SELECTIONS = new DeviceFlag( - "ENABLE_OVERVIEW_SELECTIONS", true, "Show Select Mode button in Overview Actions"); - - public static final BooleanFlag ENABLE_WIDGETS_PICKER_AIAI_SEARCH = new DeviceFlag( - "ENABLE_WIDGETS_PICKER_AIAI_SEARCH", true, "Enable AiAi search in the widgets picker"); - - public static final BooleanFlag ENABLE_OVERVIEW_SHARING_TO_PEOPLE = getDebugFlag( - "ENABLE_OVERVIEW_SHARING_TO_PEOPLE", true, - "Show indicators for content on Overview to share with top people. "); - + // b/270392706 public static final BooleanFlag ENABLE_DATABASE_RESTORE = getDebugFlag( "ENABLE_DATABASE_RESTORE", false, "Enable database restore when new restore session is created"); + // b/270391664 public static final BooleanFlag ENABLE_SMARTSPACE_DISMISS = getDebugFlag( "ENABLE_SMARTSPACE_DISMISS", true, "Adds a menu option to dismiss the current Enhanced Smartspace card."); + // b/270392629 public static final BooleanFlag ENABLE_OVERLAY_CONNECTION_OPTIM = getDebugFlag( "ENABLE_OVERLAY_CONNECTION_OPTIM", false, @@ -165,254 +176,299 @@ public final class FeatureFlags { /** * Enables region sampling for text color: Needs system health assessment before turning on */ + // b/270391669 public static final BooleanFlag ENABLE_REGION_SAMPLING = getDebugFlag( "ENABLE_REGION_SAMPLING", false, "Enable region sampling to determine color of text on screen."); + // b/270393096 public static final BooleanFlag ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS = getDebugFlag( "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false, "Always use hardware optimization for folder animations."); + // b/270392980 public static final BooleanFlag SEPARATE_RECENTS_ACTIVITY = getDebugFlag( "SEPARATE_RECENTS_ACTIVITY", false, "Uses a separate recents activity instead of using the integrated recents+Launcher UI"); + // b/270392984 public static final BooleanFlag ENABLE_MINIMAL_DEVICE = getDebugFlag( "ENABLE_MINIMAL_DEVICE", false, "Allow user to toggle minimal device mode in launcher."); - // TODO: b/172467144 Remove ENABLE_LAUNCHER_ACTIVITY_THEME_CROSSFADE feature flag. - public static final BooleanFlag ENABLE_LAUNCHER_ACTIVITY_THEME_CROSSFADE = new DeviceFlag( - "ENABLE_LAUNCHER_ACTIVITY_THEME_CROSSFADE", false, "Enables a " - + "crossfade animation when the system these changes."); - - // TODO: b/174174514 Remove ENABLE_APP_PREDICTIONS_WHILE_VISIBLE feature flag. - public static final BooleanFlag ENABLE_APP_PREDICTIONS_WHILE_VISIBLE = new DeviceFlag( - "ENABLE_APP_PREDICTIONS_WHILE_VISIBLE", true, "Allows app " - + "predictions to be updated while they are visible to the user."); - + // b/270392477 public static final BooleanFlag ENABLE_TASKBAR_POPUP_MENU = getDebugFlag( "ENABLE_TASKBAR_POPUP_MENU", true, "Enables long pressing taskbar icons to show the" + " popup menu."); + // b/270392643 public static final BooleanFlag ENABLE_TWO_PANEL_HOME = getDebugFlag( "ENABLE_TWO_PANEL_HOME", true, "Uses two panel on home screen. Only applicable on large screen devices."); + // b/270393276 public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag( "ENABLE_SCRIM_FOR_APP_LAUNCH", false, "Enables scrim during app launch animation."); + // b/270393258 public static final BooleanFlag ENABLE_ENFORCED_ROUNDED_CORNERS = new DeviceFlag( "ENABLE_ENFORCED_ROUNDED_CORNERS", true, "Enforce rounded corners on all App Widgets"); + // b/270393108 public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag("NOTIFY_CRASHES", false, "Sends a notification whenever launcher encounters an uncaught exception."); + // b/270393604 public static final BooleanFlag ENABLE_WALLPAPER_SCRIM = getDebugFlag( "ENABLE_WALLPAPER_SCRIM", false, "Enables scrim over wallpaper for text protection."); + // b/270393268 public static final BooleanFlag WIDGETS_IN_LAUNCHER_PREVIEW = getDebugFlag( "WIDGETS_IN_LAUNCHER_PREVIEW", true, "Enables widgets in Launcher preview for the Wallpaper app."); + // b/270393112 public static final BooleanFlag QUICK_WALLPAPER_PICKER = getDebugFlag( "QUICK_WALLPAPER_PICKER", true, "Shows quick wallpaper picker in long-press menu"); + // b/270393426 public static final BooleanFlag ENABLE_BACK_SWIPE_HOME_ANIMATION = getDebugFlag( "ENABLE_BACK_SWIPE_HOME_ANIMATION", true, "Enables home animation to icon when user swipes back."); + // b/270393294 public static final BooleanFlag ENABLE_ICON_LABEL_AUTO_SCALING = getDebugFlag( "ENABLE_ICON_LABEL_AUTO_SCALING", true, "Enables scaling/spacing for icon labels to make more characters visible"); + // b/270393897 public static final BooleanFlag ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT = getDebugFlag( "ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT", false, "Enables displaying the all apps button in the hotseat."); + // b/270393900 public static final BooleanFlag ENABLE_ALL_APPS_ONE_SEARCH_IN_TASKBAR = getDebugFlag( "ENABLE_ALL_APPS_ONE_SEARCH_IN_TASKBAR", false, "Enables One Search box in Taskbar All Apps."); + // b/270393449 public static final BooleanFlag ENABLE_TASKBAR_IN_OVERVIEW = getDebugFlag( "ENABLE_TASKBAR_IN_OVERVIEW", true, "Enables accessing the system Taskbar in overview."); + // b/270393906 public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE = getDebugFlag( "ENABLE_SPLIT_FROM_WORKSPACE", true, "Enable initiating split screen from workspace."); + // b/270394122 public static final BooleanFlag ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS = getDebugFlag("ENABLE_SPLIT_FROM_FULLSCREEN_SHORTCUT", true, "Enable splitting from fullscreen app with keyboard shortcuts"); + // b/270393453 public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE = getDebugFlag( "ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE", false, "Enable initiating split screen from workspace to workspace."); + // b/270393455 public static final BooleanFlag ENABLE_NEW_MIGRATION_LOGIC = getDebugFlag( "ENABLE_NEW_MIGRATION_LOGIC", true, "Enable the new grid migration logic, keeping pages when src < dest"); + // b/270394384 public static final BooleanFlag ENABLE_WIDGET_HOST_IN_BACKGROUND = getDebugFlag( "ENABLE_WIDGET_HOST_IN_BACKGROUND", false, "Enable background widget updates listening for widget holder"); + // b/270394223 public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = new DeviceFlag( "ENABLE_ONE_SEARCH_MOTION", true, "Enables animations in OneSearch."); + // b/270394041 public static final BooleanFlag ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES = new DeviceFlag( "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", false, "Enable option to replace decorator-based search result backgrounds with drawables"); + // b/270394392 public static final BooleanFlag ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION = new DeviceFlag( "ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION", false, "Enable option to launch search results using the new view container transitions"); + // b/270394225 public static final BooleanFlag TWO_PREDICTED_ROWS_ALL_APPS_SEARCH = new DeviceFlag( "TWO_PREDICTED_ROWS_ALL_APPS_SEARCH", false, "Use 2 rows of app predictions in All Apps search zero-state"); + // b/270394468 public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag( "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true, "Enable option to show keyboard when going to all-apps"); + // b/270394973 public static final BooleanFlag USE_LOCAL_ICON_OVERRIDES = getDebugFlag( "USE_LOCAL_ICON_OVERRIDES", true, "Use inbuilt monochrome icons if app doesn't provide one"); + // b/270394476 public static final BooleanFlag ENABLE_DISMISS_PREDICTION_UNDO = getDebugFlag( "ENABLE_DISMISS_PREDICTION_UNDO", false, "Show an 'Undo' snackbar when users dismiss a predicted hotseat item"); + // b/270395008 public static final BooleanFlag ENABLE_CACHED_WIDGET = getDebugFlag( "ENABLE_CACHED_WIDGET", true, "Show previously cached widgets as opposed to deferred widget where available"); + // b/270395010 public static final BooleanFlag USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES = getDebugFlag( "USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES", false, "Use local overrides for search request timeout"); + // b/270395171 public static final BooleanFlag CONTINUOUS_VIEW_TREE_CAPTURE = getDebugFlag( "CONTINUOUS_VIEW_TREE_CAPTURE", false, "Capture View tree every frame"); + // b/270395140 public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag( "SECONDARY_DRAG_N_DROP_TO_PIN", false, "Enable dragging and dropping to pin apps within secondary display"); + // b/270395070 public static final BooleanFlag FOLDABLE_WORKSPACE_REORDER = getDebugFlag( "FOLDABLE_WORKSPACE_REORDER", false, "In foldables, when reordering the icons and widgets, is now going to use both sides"); - public static final BooleanFlag ENABLE_WIDGET_PICKER_DEPTH = new DeviceFlag( - "ENABLE_WIDGET_PICKER_DEPTH", true, "Enable changing depth in widget picker."); - + // b/270395073 public static final BooleanFlag ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH = getDebugFlag( "ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH", false, "Allow bottom sheet depth to be smaller than 1 for multi-display devices."); + // b/270395177 public static final BooleanFlag SCROLL_TOP_TO_RESET = new DeviceFlag( "SCROLL_TOP_TO_RESET", true, "Bring up IME and focus on " + "input when scroll to top if 'Always show keyboard' is enabled or in prefix state"); + // b/270395516 public static final BooleanFlag ENABLE_MATERIAL_U_POPUP = getDebugFlag( "ENABLE_MATERIAL_U_POPUP", false, "Switch popup UX to use material U"); + // b/270395269 public static final BooleanFlag ENABLE_SEARCH_UNINSTALLED_APPS = new DeviceFlag( "ENABLE_SEARCH_UNINSTALLED_APPS", false, "Search uninstalled app results."); + // b/270395183 public static final BooleanFlag SHOW_HOME_GARDENING = getDebugFlag( "SHOW_HOME_GARDENING", false, "Show the new home gardening mode"); + // b/270395133 public static final BooleanFlag HOME_GARDENING_WORKSPACE_BUTTONS = getDebugFlag( "HOME_GARDENING_WORKSPACE_BUTTONS", false, "Change workspace edit buttons to reflect home gardening"); + // b/270395134 public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V2 = new DeviceFlag( "ENABLE_DOWNLOAD_APP_UX_V2", true, "Updates the download app UX" + " to have better visuals"); + // b/270395186 public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V3 = getDebugFlag( "ENABLE_DOWNLOAD_APP_UX_V3", false, "Updates the download app UX" + " to have better visuals, improve contrast, and color"); + // b/270395077 public static final BooleanFlag FORCE_PERSISTENT_TASKBAR = getDebugFlag( "FORCE_PERSISTENT_TASKBAR", false, "Forces taskbar to be persistent, even in gesture" + " nav mode and when transient taskbar is enabled."); + // b/270395274 public static final BooleanFlag FOLDABLE_SINGLE_PAGE = getDebugFlag( "FOLDABLE_SINGLE_PAGE", false, "Use a single page for the workspace"); + // b/270395798 public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag( "ENABLE_TRANSIENT_TASKBAR", true, "Enables transient taskbar."); public static final BooleanFlag ENABLE_TRACKPAD_GESTURE = getDebugFlag( "ENABLE_TRACKPAD_GESTURE", false, "Enables trackpad gesture."); + // b/270395143 public static final BooleanFlag ENABLE_ICON_IN_TEXT_HEADER = getDebugFlag( "ENABLE_ICON_IN_TEXT_HEADER", false, "Show icon in textheader"); + // b/270395087 public static final BooleanFlag ENABLE_APP_ICON_FOR_INLINE_SHORTCUTS = getDebugFlag( "ENABLE_APP_ICON_IN_INLINE_SHORTCUTS", false, "Show app icon for inline shortcut"); + // b/270395278 public static final BooleanFlag SHOW_DOT_PAGINATION = getDebugFlag( "SHOW_DOT_PAGINATION", false, "Enable showing dot pagination in workspace"); + // b/270395809 public static final BooleanFlag LARGE_SCREEN_WIDGET_PICKER = getDebugFlag( "LARGE_SCREEN_WIDGET_PICKER", false, "Enable new widget picker that takes " + "advantage of large screen format"); + // b/270396257 public static final BooleanFlag ENABLE_NEW_GESTURE_NAV_TUTORIAL = getDebugFlag( "ENABLE_NEW_GESTURE_NAV_TUTORIAL", false, "Enable the redesigned gesture navigation tutorial"); - public static final BooleanFlag ENABLE_DEVICE_PROFILE_LOGGING = new DeviceFlag( - "ENABLE_DEVICE_PROFILE_LOGGING", false, "Allows DeviceProfile logging"); - + // b/270395567 public static final BooleanFlag ENABLE_LAUNCH_FROM_STAGED_APP = getDebugFlag( "ENABLE_LAUNCH_FROM_STAGED_APP", true, "Enable the ability to tap a staged app during split select to launch it in full screen" ); + + // b/270396358 public static final BooleanFlag ENABLE_HAPTICS_ALL_APPS = getDebugFlag( "ENABLE_HAPTICS_ALL_APPS", false, "Enables haptics opening/closing All apps"); + // b/270396209 public static final BooleanFlag ENABLE_FORCED_MONO_ICON = getDebugFlag( "ENABLE_FORCED_MONO_ICON", false, "Enable the ability to generate monochromatic icons, if it is not provided by the app" ); + // b/270396364 public static final BooleanFlag ENABLE_DREAM_TRANSITION = getDebugFlag( "ENABLE_DREAM_TRANSITION", true, "Enable the launcher transition when the device enters a dream"); + // b/270396268 public static final BooleanFlag ENABLE_TASKBAR_EDU_TOOLTIP = getDebugFlag( "ENABLE_TASKBAR_EDU_TOOLTIP", true, "Enable the tooltip version of the Taskbar education flow."); + // b/270396680 public static final BooleanFlag ENABLE_MULTI_INSTANCE = getDebugFlag( "ENABLE_MULTI_INSTANCE", false, "Enables creation and filtering of multiple task instances in overview"); + // b/270396583 public static final BooleanFlag ENABLE_TASKBAR_PINNING = getDebugFlag( "ENABLE_TASKBAR_PINNING", false, "Enables taskbar pinning to allow user to switch between transient and persistent " + "taskbar flavors"); + // b/270397206 public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag( "ENABLE_GRID_ONLY_OVERVIEW", false, "Enable a grid-only overview without a focused task."); + // b/270397209 public static final BooleanFlag RECEIVE_UNFOLD_EVENTS_FROM_SYSUI = getDebugFlag( "RECEIVE_UNFOLD_EVENTS_FROM_SYSUI", true, "Enables receiving unfold animation events from sysui instead of calculating " + "them in launcher process using hinge sensor values."); + // b/270396844 public static final BooleanFlag ENABLE_KEYBOARD_QUICK_SWITCH = getDebugFlag( "ENABLE_KEYBOARD_QUICK_SWITCH", true, "Enables keyboard quick switching"); diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index c23ea8aa4f..a0f21dc297 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -20,6 +20,8 @@ import static androidx.core.content.ContextCompat.getColorStateList; import static com.android.launcher3.anim.Interpolators.ACCELERATED_EASE; import static com.android.launcher3.anim.Interpolators.DECELERATED_EASE; +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.LINEAR; import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP; @@ -37,11 +39,13 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.util.AttributeSet; import android.util.Pair; +import android.util.Property; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Interpolator; +import android.view.animation.PathInterpolator; import android.widget.FrameLayout; import androidx.annotation.Nullable; @@ -81,6 +85,19 @@ public abstract class ArrowPopup protected int CLOSE_CHILD_FADE_START_DELAY = 0; protected int CLOSE_CHILD_FADE_DURATION = 140; + private static final int OPEN_DURATION_U = 200; + private static final int OPEN_FADE_START_DELAY_U = 0; + private static final int OPEN_FADE_DURATION_U = 83; + private static final int OPEN_CHILD_FADE_START_DELAY_U = 0; + private static final int OPEN_CHILD_FADE_DURATION_U = 83; + private static final int OPEN_OVERSHOOT_DURATION_U = 200; + + private static final int CLOSE_DURATION_U = 233; + private static final int CLOSE_FADE_START_DELAY_U = 150; + private static final int CLOSE_FADE_DURATION_U = 83; + private static final int CLOSE_CHILD_FADE_START_DELAY_U = 150; + private static final int CLOSE_CHILD_FADE_DURATION_U = 83; + protected final Rect mTempRect = new Rect(); protected final LayoutInflater mInflater; @@ -104,6 +121,7 @@ public abstract class ArrowPopup protected AnimatorSet mOpenCloseAnimator; protected boolean mDeferContainerRemoval; protected boolean shouldScaleArrow = false; + protected boolean mIsArrowRotated = false; private final GradientDrawable mRoundedTop; private final GradientDrawable mRoundedBottom; @@ -591,10 +609,24 @@ public abstract class ArrowPopup protected void animateOpen() { setVisibility(View.VISIBLE); + mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get() + ? getMaterialUOpenCloseAnimator( + true, + OPEN_DURATION_U, + OPEN_FADE_START_DELAY_U, + OPEN_FADE_DURATION_U, + OPEN_CHILD_FADE_START_DELAY_U, + OPEN_CHILD_FADE_DURATION_U, + EMPHASIZED_DECELERATE) + : getOpenCloseAnimator( + true, + OPEN_DURATION, + OPEN_FADE_START_DELAY, + OPEN_FADE_DURATION, + OPEN_CHILD_FADE_START_DELAY, + OPEN_CHILD_FADE_DURATION, + DECELERATED_EASE); - mOpenCloseAnimator = getOpenCloseAnimator(true, OPEN_DURATION, OPEN_FADE_START_DELAY, - OPEN_FADE_DURATION, OPEN_CHILD_FADE_START_DELAY, OPEN_CHILD_FADE_DURATION, - DECELERATED_EASE); onCreateOpenAnimation(mOpenCloseAnimator); mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() { @Override @@ -680,6 +712,24 @@ public abstract class ArrowPopup mOpenCloseAnimator = getOpenCloseAnimator(false, CLOSE_DURATION, CLOSE_FADE_START_DELAY, CLOSE_FADE_DURATION, CLOSE_CHILD_FADE_START_DELAY, CLOSE_CHILD_FADE_DURATION, ACCELERATED_EASE); + + mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get() + ? getMaterialUOpenCloseAnimator( + false, + CLOSE_DURATION_U, + CLOSE_FADE_START_DELAY_U, + CLOSE_FADE_DURATION_U, + CLOSE_CHILD_FADE_START_DELAY_U, + CLOSE_CHILD_FADE_DURATION_U, + EMPHASIZED_ACCELERATE) + : getOpenCloseAnimator(false, + CLOSE_DURATION, + CLOSE_FADE_START_DELAY, + CLOSE_FADE_DURATION, + CLOSE_CHILD_FADE_START_DELAY, + CLOSE_CHILD_FADE_DURATION, + ACCELERATED_EASE); + onCreateCloseAnimation(mOpenCloseAnimator); mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() { @Override @@ -695,6 +745,59 @@ public abstract class ArrowPopup mOpenCloseAnimator.start(); } + protected AnimatorSet getMaterialUOpenCloseAnimator(boolean isOpening, int scaleDuration, + int fadeStartDelay, int fadeDuration, int childFadeStartDelay, int childFadeDuration, + Interpolator interpolator) { + + int arrowCenter = mArrowOffsetHorizontal + mArrowWidth / 2; + if (mIsArrowRotated) { + setPivotX(mIsLeftAligned ? 0f : getMeasuredWidth()); + setPivotY(arrowCenter); + } else { + setPivotX(mIsLeftAligned ? arrowCenter : getMeasuredWidth() - arrowCenter); + setPivotY(mIsAboveIcon ? getMeasuredHeight() : 0f); + } + + float[] alphaValues = isOpening ? new float[] {0, 1} : new float[] {1, 0}; + float[] scaleValues = isOpening ? new float[] {0.5f, 1.02f} : new float[] {1f, 0.5f}; + Animator alpha = getAnimatorOfFloat(this, View.ALPHA, fadeDuration, fadeStartDelay, + LINEAR, alphaValues); + Animator arrowAlpha = getAnimatorOfFloat(mArrow, View.ALPHA, fadeDuration, fadeStartDelay, + LINEAR, alphaValues); + Animator scaleY = getAnimatorOfFloat(this, View.SCALE_Y, scaleDuration, 0, interpolator, + scaleValues); + Animator scaleX = getAnimatorOfFloat(this, View.SCALE_X, scaleDuration, 0, interpolator, + scaleValues); + + final AnimatorSet animatorSet = new AnimatorSet(); + if (isOpening) { + float[] scaleValuesOvershoot = new float[] {1.02f, 1f}; + PathInterpolator overshootInterpolator = new PathInterpolator(0.3f, 0, 0.33f, 1f); + Animator overshootY = getAnimatorOfFloat(this, View.SCALE_Y, + OPEN_OVERSHOOT_DURATION_U, scaleDuration, overshootInterpolator, + scaleValuesOvershoot); + Animator overshootX = getAnimatorOfFloat(this, View.SCALE_X, + OPEN_OVERSHOOT_DURATION_U, scaleDuration, overshootInterpolator, + scaleValuesOvershoot); + + animatorSet.playTogether(alpha, arrowAlpha, scaleY, scaleX, overshootX, overshootY); + } else { + animatorSet.playTogether(alpha, arrowAlpha, scaleY, scaleX); + } + + fadeInChildViews(this, alphaValues, childFadeStartDelay, childFadeDuration, animatorSet); + return animatorSet; + } + + private Animator getAnimatorOfFloat(View view, Property property, + int duration, int startDelay, Interpolator interpolator, float... values) { + Animator animator = ObjectAnimator.ofFloat(view, property, values); + animator.setDuration(duration); + animator.setInterpolator(interpolator); + animator.setStartDelay(startDelay); + return animator; + } + /** * Called when creating the open transition allowing subclass can add additional animations. */ diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsQsb.java b/tests/tapl/com/android/launcher3/tapl/AllAppsQsb.java new file mode 100644 index 0000000000..0931cd46b0 --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/AllAppsQsb.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 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.tapl; + +import androidx.test.uiautomator.UiObject2; + +/** + * Operations on AllApp screen qsb. + */ +class AllAppsQsb extends Qsb { + + private final UiObject2 mAllAppsContainer; + + AllAppsQsb(LauncherInstrumentation launcher, UiObject2 allAppsContainer) { + super(launcher); + mAllAppsContainer = allAppsContainer; + waitForQsbObject(); + } + + @Override + protected UiObject2 waitForQsbObject() { + return mLauncher.waitForObjectInContainer(mAllAppsContainer, "search_container_all_apps"); + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java index e0c4c19679..44de65a43e 100644 --- a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java @@ -109,4 +109,13 @@ public class HomeAllApps extends AllApps { } } } + + /** + * Return the QSB UI object on the AllApps screen. + * @return the QSB UI object. + */ + @NonNull + public Qsb getQsb() { + return new AllAppsQsb(mLauncher, verifyActiveContainer()); + } } diff --git a/tests/tapl/com/android/launcher3/tapl/HomeQsb.java b/tests/tapl/com/android/launcher3/tapl/HomeQsb.java index c365708d46..20d09a1e16 100644 --- a/tests/tapl/com/android/launcher3/tapl/HomeQsb.java +++ b/tests/tapl/com/android/launcher3/tapl/HomeQsb.java @@ -15,69 +15,23 @@ */ package com.android.launcher3.tapl; -import androidx.annotation.NonNull; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; /** - * Operations on home screen qsb. + * Operations on Home screen qsb. */ -public class HomeQsb { +class HomeQsb extends Qsb { - private final LauncherInstrumentation mLauncher; - private static final String ASSISTANT_APP_PACKAGE = "com.google.android.googlequicksearchbox"; - private static final String ASSISTANT_ICON_RES_ID = "mic_icon"; + private final UiObject2 mHotSeat; - - HomeQsb(LauncherInstrumentation launcher) { - mLauncher = launcher; - mLauncher.waitForLauncherObject("search_container_hotseat"); + HomeQsb(LauncherInstrumentation launcher, UiObject2 hotseat) { + super(launcher); + mHotSeat = hotseat; + waitForQsbObject(); } - /** - * Launch assistant app by tapping mic icon on qsb. - */ - @NonNull - public LaunchedAppState launchAssistant() { - try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( - "want to click assistant mic icon button"); - LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) { - UiObject2 assistantIcon = mLauncher.waitForLauncherObject(ASSISTANT_ICON_RES_ID); - - LauncherInstrumentation.log("HomeQsb.launchAssistant before click " - + assistantIcon.getVisibleCenter() + " in " - + mLauncher.getVisibleBounds(assistantIcon)); - - mLauncher.clickLauncherObject(assistantIcon); - - try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) { - // assert Assistant App Launched - BySelector selector = By.pkg(ASSISTANT_APP_PACKAGE); - mLauncher.assertTrue( - "assistant app didn't start: (" + selector + ")", - mLauncher.getDevice().wait(Until.hasObject(selector), - LauncherInstrumentation.WAIT_TIME_MS) - ); - return new LaunchedAppState(mLauncher); - } - } - } - - /** - * Show search result page from tapping qsb. - */ - public SearchResultFromQsb showSearchResult() { - try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( - "want to open search result page"); - LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) { - mLauncher.clickLauncherObject( - mLauncher.waitForLauncherObject("search_container_hotseat")); - try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer( - "clicked qsb to open search result page")) { - return new SearchResultFromQsb(mLauncher); - } - } + @Override + protected UiObject2 waitForQsbObject() { + return mLauncher.waitForObjectInContainer(mHotSeat, "search_container_hotseat"); } } diff --git a/tests/tapl/com/android/launcher3/tapl/Qsb.java b/tests/tapl/com/android/launcher3/tapl/Qsb.java new file mode 100644 index 0000000000..6bc4f2109c --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/Qsb.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2022 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.tapl; + +import androidx.annotation.NonNull; +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.BySelector; +import androidx.test.uiautomator.UiObject2; +import androidx.test.uiautomator.Until; + +/** + * Operations on qsb from either Home screen or AllApp screen. + */ +public abstract class Qsb { + + private static final String ASSISTANT_APP_PACKAGE = "com.google.android.googlequicksearchbox"; + private static final String ASSISTANT_ICON_RES_ID = "mic_icon"; + protected final LauncherInstrumentation mLauncher; + + protected Qsb(LauncherInstrumentation launcher) { + mLauncher = launcher; + } + + // Waits for the quick search box. + protected abstract UiObject2 waitForQsbObject(); + /** + * Launch assistant app by tapping mic icon on qsb. + */ + + @NonNull + public LaunchedAppState launchAssistant() { + try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( + "want to click assistant mic icon button"); + LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) { + UiObject2 assistantIcon = mLauncher.waitForLauncherObject(ASSISTANT_ICON_RES_ID); + + LauncherInstrumentation.log("Qsb.launchAssistant before click " + + assistantIcon.getVisibleCenter() + " in " + + mLauncher.getVisibleBounds(assistantIcon)); + + mLauncher.clickLauncherObject(assistantIcon); + + try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) { + // assert Assistant App Launched + BySelector selector = By.pkg(ASSISTANT_APP_PACKAGE); + mLauncher.assertTrue( + "assistant app didn't start: (" + selector + ")", + mLauncher.getDevice().wait(Until.hasObject(selector), + LauncherInstrumentation.WAIT_TIME_MS) + ); + return new LaunchedAppState(mLauncher); + } + } + } + + /** + * Show search result page from tapping qsb. + */ + public SearchResultFromQsb showSearchResult() { + try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( + "want to open search result page"); + LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) { + mLauncher.clickLauncherObject(waitForQsbObject()); + // wait for the result rendering to complete + mLauncher.waitForIdle(); + try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer( + "clicked qsb to open search result page")) { + return new SearchResultFromQsb(mLauncher); + } + } + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java index 80e4116406..80176e993f 100644 --- a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java +++ b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java @@ -23,7 +23,7 @@ import androidx.test.uiautomator.UiObject2; import java.util.ArrayList; /** - * Operations on search result page opened from home screen qsb. + * Operations on search result page opened from qsb. */ public class SearchResultFromQsb { // The input resource id in the search box. diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index 0197a11383..1939dc6a52 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -119,10 +119,11 @@ public final class Workspace extends Home { * * The qsb must already be visible when calling this method. */ - public HomeQsb getQsb() { + @NonNull + public Qsb getQsb() { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to get the home qsb")) { - return new HomeQsb(mLauncher); + return new HomeQsb(mLauncher, mHotseat); } }