From 921f9fd2547695f3b418440a3df8d0004cae1a16 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 27 Apr 2020 12:38:02 -0700 Subject: [PATCH 01/65] Support for counting activity creations Bug: 139137636 Change-Id: Ib999fd3c82eb2997662578ec35e1d9e1e75e3cbb --- .../android/launcher3/ui/AbstractLauncherUiTest.java | 2 +- .../com/android/launcher3/ui/ActivityLeakTracker.java | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 9c8e278cf5..160daef636 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -101,7 +101,7 @@ public abstract class AbstractLauncherUiTest { private static String sStrictmodeDetectedActivityLeak; private static boolean sActivityLeakReported; private static final String SYSTEMUI_PACKAGE = "com.android.systemui"; - private static final ActivityLeakTracker ACTIVITY_LEAK_TRACKER = new ActivityLeakTracker(); + protected static final ActivityLeakTracker ACTIVITY_LEAK_TRACKER = new ActivityLeakTracker(); protected LooperExecutor mMainThreadExecutor = MAIN_EXECUTOR; protected final UiDevice mDevice = UiDevice.getInstance(getInstrumentation()); diff --git a/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java b/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java index e9258e94d2..202dcb181f 100644 --- a/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java +++ b/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java @@ -26,9 +26,11 @@ import com.android.launcher3.tapl.TestHelpers; import java.util.WeakHashMap; -class ActivityLeakTracker implements Application.ActivityLifecycleCallbacks { +public class ActivityLeakTracker implements Application.ActivityLifecycleCallbacks { private final WeakHashMap mActivities = new WeakHashMap<>(); + private int mActivitiesCreated; + ActivityLeakTracker() { if (!TestHelpers.isInLauncherProcess()) return; final Application app = @@ -36,9 +38,14 @@ class ActivityLeakTracker implements Application.ActivityLifecycleCallbacks { app.registerActivityLifecycleCallbacks(this); } + public int getActivitiesCreated() { + return mActivitiesCreated; + } + @Override public void onActivityCreated(Activity activity, Bundle bundle) { mActivities.put(activity, true); + ++mActivitiesCreated; } @Override @@ -77,7 +84,7 @@ class ActivityLeakTracker implements Application.ActivityLifecycleCallbacks { } } - if (liveActivities > 2) return false; + if (liveActivities > 2) return false; // It's OK to have 1 leaked activity if no active activities exist. return liveActivities == 0 ? destroyedActivities <= 1 : destroyedActivities == 0; From 2e6fdd7d93c7f480d88c77c717ab3359677943b0 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 27 Apr 2020 13:08:50 -0700 Subject: [PATCH 02/65] Optimization: reducing number of getNavigationModeMismatchError calls They are relatively expensive Change-Id: I34de56884ec3f88e69c709026d3b72e62c787681 --- .../android/launcher3/tapl/LauncherInstrumentation.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index debc736ac2..d46845f118 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -535,13 +535,14 @@ public final class LauncherInstrumentation { mExpectedRotation, mDevice.getDisplayRotation()); // b/148422894 + String error = null; for (int i = 0; i != 600; ++i) { - if (getNavigationModeMismatchError() == null) break; + error = getNavigationModeMismatchError(); + if (error == null) break; sleep(100); } - - final String error = getNavigationModeMismatchError(); assertTrue(error, error == null); + log("verifyContainerType: " + containerType); final UiObject2 container = verifyVisibleObjects(containerType); From 63dd9e0b3386e803dacab279bea62f8e21a33ab0 Mon Sep 17 00:00:00 2001 From: Sreyas Date: Mon, 27 Apr 2020 14:08:56 -0700 Subject: [PATCH 03/65] Removing old unused code from PageView Change-Id: I12da53189ddbb2484149d384d5ef20a4aa0535e5 --- src/com/android/launcher3/PagedView.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 5343424dfc..bbdadeea0b 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -257,13 +257,6 @@ public abstract class PagedView extends ViewGrou forceFinishScroller(true); } - /** - * Returns left offset of a page. This is the gap between pages and prevents overlap. - */ - public int scrollOffsetLeft() { - return mInsets.left + getPaddingLeft(); - } - private void abortScrollerAnimation(boolean resetNextPage) { mScroller.abortAnimation(); // We need to clean up the next page here to avoid computeScrollHelper from From a39544d562625270ce75a76cbdde1e69a83f9351 Mon Sep 17 00:00:00 2001 From: Zak Cohen Date: Mon, 27 Apr 2020 16:26:55 -0700 Subject: [PATCH 04/65] OverviewActions - Use launcher state to track modal state. Test:local Change-Id: I44e25b95095b9a7aac4b4172c9c91fbfbf4d9ec7 --- .../uioverrides/QuickstepLauncher.java | 8 +- .../RecentsViewStateController.java | 6 + .../states/OverviewModalTaskState.java | 69 ++++++++++++ .../uioverrides/states/OverviewState.java | 7 ++ .../NavBarToHomeTouchController.java | 5 +- .../TaskViewTouchController.java | 5 +- .../android/quickstep/TaskOverlayFactory.java | 7 -- .../fallback/RecentsTaskController.java | 5 + .../quickstep/views/LauncherRecentsView.java | 3 +- .../android/quickstep/views/RecentsView.java | 68 +++++++----- .../com/android/quickstep/views/TaskView.java | 105 +++++------------- .../BaseRecentsViewStateController.java | 9 ++ src/com/android/launcher3/LauncherState.java | 13 ++- src/com/android/launcher3/Utilities.java | 24 ++++ .../states/StateAnimationConfig.java | 4 +- .../launcher3/testing/TestProtocol.java | 11 +- .../uioverrides/states/OverviewState.java | 7 ++ 17 files changed, 236 insertions(+), 120 deletions(-) create mode 100644 quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 87ca2b688a..e074b03c09 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -17,6 +17,7 @@ package com.android.launcher3.uioverrides; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import android.content.Intent; @@ -219,7 +220,12 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { @Override protected boolean isRecentsInteractive() { - return mActivity.isInState(OVERVIEW); + return mActivity.isInState(OVERVIEW) || mActivity.isInState(OVERVIEW_MODAL_TASK); + } + + @Override + protected boolean isRecentsModal() { + return mActivity.isInState(OVERVIEW_MODAL_TASK); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 2f55fda8f0..a1cc60ec71 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -19,6 +19,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW_BUTTONS; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; +import static com.android.quickstep.views.RecentsView.TASK_MODALNESS; import android.annotation.TargetApi; import android.os.Build; @@ -87,6 +88,11 @@ public final class RecentsViewStateController extends MultiValueAlpha.VALUE, buttonAlpha, LINEAR); } + @Override + FloatProperty getTaskModalnessProperty() { + return TASK_MODALNESS; + } + @Override FloatProperty getContentAlphaProperty() { return CONTENT_ALPHA; diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java new file mode 100644 index 0000000000..b238200799 --- /dev/null +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.uioverrides.states; + +import android.content.res.Resources; +import android.graphics.Rect; + +import com.android.launcher3.Launcher; +import com.android.launcher3.R; +import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; +import com.android.quickstep.views.RecentsView; + +/** + * An Overview state that shows the current task in a modal fashion. Modal state is where the + * current task is shown on its own without other tasks visible. + */ +public class OverviewModalTaskState extends OverviewState { + + private static final int STATE_FLAGS = + FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY; + + public OverviewModalTaskState(int id) { + super(id, ContainerType.OVERVIEW, STATE_FLAGS); + } + + @Override + public int getTransitionDuration(Launcher launcher) { + return 100; + } + + @Override + public int getVisibleElements(Launcher launcher) { + return OVERVIEW_BUTTONS; + } + + @Override + public float[] getOverviewScaleAndOffset(Launcher launcher) { + Resources res = launcher.getBaseContext().getResources(); + + Rect out = new Rect(); + launcher.getOverviewPanel().getTaskSize(out); + int taskHeight = out.height(); + + float topMargin = res.getDimension(R.dimen.task_thumbnail_top_margin); + float bottomMargin = res.getDimension(R.dimen.task_thumbnail_bottom_margin_with_actions); + float newHeight = taskHeight + topMargin + bottomMargin; + float scale = newHeight / taskHeight; + + return new float[] {scale, 0}; + } + + @Override + public float getOverviewModalness() { + return 1.0f; + } +} diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java index e44f59fd71..fad9ea5817 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -259,4 +259,11 @@ public class OverviewState extends LauncherState { public static OverviewState newSwitchState(int id) { return new QuickSwitchState(id); } + + /** + * New Overview substate that represents the overview in modal mode (one task shown on its own) + */ + public static OverviewState newModalTaskState(int id) { + return new OverviewModalTaskState(id); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 2b456ecec8..06a481b90d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -17,7 +17,6 @@ package com.android.launcher3.uioverrides.touchcontrollers; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; -import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS; import static com.android.launcher3.anim.Interpolators.DEACCEL_3; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; @@ -99,7 +98,7 @@ public class NavBarToHomeTouchController implements TouchController, if (!cameFromNavBar) { return false; } - if (mStartState == OVERVIEW || mStartState == ALL_APPS) { + if (mStartState.overviewUi || mStartState == ALL_APPS) { return true; } if (AbstractFloatingView.getTopOpenView(mLauncher) != null) { @@ -129,7 +128,7 @@ public class NavBarToHomeTouchController implements TouchController, private void initCurrentAnimation() { long accuracy = (long) (getShiftRange() * 2); final PendingAnimation builder = new PendingAnimation(accuracy); - if (mStartState == OVERVIEW) { + if (mStartState.overviewUi) { RecentsView recentsView = mLauncher.getOverviewPanel(); builder.setFloat(recentsView, ADJACENT_PAGE_OFFSET, -mPullbackDistance / recentsView.getPageOffsetScale(), PULLBACK_INTERPOLATOR); diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java index f6f892b44b..1f3b82cd98 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java @@ -96,6 +96,9 @@ public abstract class TaskViewTouchController protected abstract boolean isRecentsInteractive(); + /** Is recents view showing a single task in a modal way. */ + protected abstract boolean isRecentsModal(); + protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) { } @@ -134,7 +137,7 @@ public abstract class TaskViewTouchController if (mRecentsView.isTaskViewVisible(view) && mActivity.getDragLayer() .isEventOverView(view, ev)) { // Disable swiping up and down if the task overlay is modal. - if (view.isTaskOverlayModal()) { + if (isRecentsModal()) { mTaskBeingDragged = null; break; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java index 147f9330c7..b44d6df26e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java @@ -130,13 +130,6 @@ public class TaskOverlayFactory implements ResourceBasedOverride { public void reset() { } - /** - * Whether the overlay is modal, which means only tapping is enabled, but no swiping. - */ - public boolean isOverlayModal() { - return false; - } - /** * Gets the task snapshot as it is displayed on the screen. * diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java index a113604caa..d7458d2ad9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java @@ -28,4 +28,9 @@ public class RecentsTaskController extends TaskViewTouchController // Clean-up logic that occurs when recents is no longer in use/visible. reset(); } - setOverlayEnabled(finalState == OVERVIEW); + setOverlayEnabled(finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK); setFreezeViewVisibility(false); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 6041917f67..cd3abed042 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -70,7 +70,6 @@ import android.text.StaticLayout; import android.text.TextPaint; import android.util.AttributeSet; import android.util.FloatProperty; -import android.util.Log; import android.util.Property; import android.util.SparseBooleanArray; import android.view.HapticFeedbackConstants; @@ -173,13 +172,26 @@ public abstract class RecentsView extends PagedView impl } }; + public static final FloatProperty TASK_MODALNESS = + new FloatProperty("taskModalness") { + @Override + public void setValue(RecentsView recentsView, float v) { + recentsView.setTaskModalness(v); + } + + @Override + public Float get(RecentsView recentsView) { + return recentsView.mTaskModalness; + } + }; + public static final FloatProperty ADJACENT_PAGE_OFFSET = new FloatProperty("adjacentPageOffset") { @Override public void setValue(RecentsView recentsView, float v) { if (recentsView.mAdjacentPageOffset != v) { recentsView.mAdjacentPageOffset = v; - recentsView.updateAdjacentPageOffset(); + recentsView.updatePageOffsets(); } } @@ -327,6 +339,12 @@ public abstract class RecentsView extends PagedView impl protected float mContentAlpha = 1; @ViewDebug.ExportedProperty(category = "launcher") protected float mFullscreenProgress = 0; + /** + * How modal is the current task to be displayed, 1 means the task is fully modal and no other + * tasks are show. 0 means the task is displays in context in the list with other tasks. + */ + @ViewDebug.ExportedProperty(category = "launcher") + protected float mTaskModalness = 0; // Keeps track of task id whose visual state should not be reset private int mIgnoreResetTaskId = -1; @@ -647,7 +665,7 @@ public abstract class RecentsView extends PagedView impl @Override protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) { // Enables swiping to the left or right only if the task overlay is not modal. - if (getCurrentPageTaskView() == null || !getCurrentPageTaskView().isTaskOverlayModal()) { + if (mTaskModalness == 0f) { super.determineScrollingStart(ev, touchSlopScale); } } @@ -735,25 +753,6 @@ public abstract class RecentsView extends PagedView impl return taskViewCount; } - /** - * Updates UI for a modal task, including hiding other tasks. - */ - public void updateUiForModalTask(TaskView taskView, boolean isTaskOverlayModal) { - int currentIndex = indexOfChild(taskView); - TaskView previousTask = getTaskViewAt(currentIndex - 1); - TaskView nextTask = getTaskViewAt(currentIndex + 1); - float alpha = isTaskOverlayModal ? 0.0f : 1.0f; - if (previousTask != null) { - previousTask.animate().alpha(alpha) - .translationX(isTaskOverlayModal ? previousTask.getWidth() / 2 : 0); - } - if (nextTask != null) { - nextTask.animate().alpha(alpha) - .translationX(isTaskOverlayModal ? -nextTask.getWidth() / 2 : 0); - - } - } - protected void onTaskStackUpdated() { } public void resetTaskVisuals() { @@ -776,6 +775,7 @@ public abstract class RecentsView extends PagedView impl updateCurveProperties(); // Update the set of visible task's data loadVisibleTaskData(); + setTaskModalness(0); } public void setFullscreenProgress(float fullscreenProgress) { @@ -1653,21 +1653,27 @@ public abstract class RecentsView extends PagedView impl mTempRect, mActivity.getDeviceProfile(), mTempPointF); setPivotX(mTempPointF.x); setPivotY(mTempPointF.y); - updateAdjacentPageOffset(); + updatePageOffsets(); } - private void updateAdjacentPageOffset() { + private void updatePageOffsets() { float offset = mAdjacentPageOffset * getWidth(); + float modalOffset = mTaskModalness * getWidth(); if (mIsRtl) { offset = -offset; + modalOffset = -modalOffset; } int count = getChildCount(); TaskView runningTask = mRunningTaskId == -1 ? null : getTaskView(mRunningTaskId); int midPoint = runningTask == null ? -1 : indexOfChild(runningTask); + int currentPage = getCurrentPage(); for (int i = 0; i < count; i++) { - getChildAt(i).setTranslationX(i == midPoint ? 0 : (i < midPoint ? -offset : offset)); + float translation = i == midPoint ? 0 : (i < midPoint ? -offset : offset); + float modalTranslation = + i == currentPage ? 0 : (i < currentPage ? -modalOffset : modalOffset); + getChildAt(i).setTranslationX(translation + modalTranslation); } updateCurveProperties(); } @@ -2113,6 +2119,18 @@ public abstract class RecentsView extends PagedView impl } } + /** + * The current task is fully modal (modalness = 1) when it is shown on its own in a modal + * way. Modalness 0 means the task is shown in context with all the other tasks. + */ + private void setTaskModalness(float modalness) { + mTaskModalness = modalness; + updatePageOffsets(); + if (getCurrentPageTaskView() != null) { + getCurrentPageTaskView().setModalness(modalness); + } + } + @Nullable protected DepthController getDepthController() { return null; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java index 4275933ae0..aea5b8e0ea 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java @@ -25,6 +25,7 @@ import static android.view.Gravity.TOP; import static android.widget.Toast.LENGTH_SHORT; import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION; +import static com.android.launcher3.Utilities.comp; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR; @@ -165,10 +166,10 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private ObjectAnimator mIconAndDimAnimator; private float mIconScaleAnimStartProgress = 0; private float mFocusTransitionProgress = 1; + private float mModalness = 0; private float mStableAlpha = 1; private boolean mShowScreenshot; - private boolean mRunningModalAnimation = false; // The current background requests to load the task thumbnail and icon private TaskThumbnailCache.ThumbnailLoadRequest mThumbnailLoadRequest; @@ -239,59 +240,24 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mIconView = findViewById(R.id.icon); } - public boolean isTaskOverlayModal() { - return mSnapshotView.getTaskOverlay().isOverlayModal(); - } - - /** Updates UI based on whether the task is modal. */ - public void updateUiForModalTask() { - boolean isOverlayModal = isTaskOverlayModal(); - mRunningModalAnimation = true; - if (getRecentsView() != null) { - getRecentsView().updateUiForModalTask(this, isOverlayModal); + /** + * The modalness of this view is how it should be displayed when it is shown on its own in the + * modal state of overview. + * + * @param modalness [0, 1] 0 being in context with other tasks, 1 being shown on its own. + */ + public void setModalness(float modalness) { + mModalness = modalness; + mIconView.setAlpha(comp(modalness)); + if (mContextualChip != null) { + mContextualChip.setScaleX(comp(modalness)); + mContextualChip.setScaleY(comp(modalness)); + } + if (mContextualChipWrapper != null) { + mContextualChipWrapper.setAlpha(comp(modalness)); } - // Hides footers and icon when overlay is modal. - if (isOverlayModal) { - for (FooterWrapper footer : mFooters) { - if (footer != null) { - footer.animateHide(); - } - } - if (mContextualChipWrapper != null) { - mContextualChipWrapper.animate().alpha(0f).setDuration(300); - } - if (mContextualChip != null) { - mContextualChip.animate().scaleX(0f).scaleY(0f).setDuration(300); - } - - mIconView.animate().alpha(0.0f); - } else { - if (mContextualChip != null) { - mContextualChip.animate().scaleX(1f).scaleY(1f).setDuration(300); - } - if (mContextualChipWrapper != null) { - mContextualChipWrapper.animate().alpha(1f).setDuration(300); - } - mIconView.animate().alpha(1.0f); - } - - // Sets animations for modal UI. We will remove the margins to zoom in the snapshot. - float topMargin = getResources().getDimension(R.dimen.task_thumbnail_top_margin); - float bottomMargin = - getResources().getDimension(R.dimen.task_thumbnail_bottom_margin_with_actions); - float newHeight = mSnapshotView.getHeight() + topMargin + bottomMargin; - float scale = isOverlayModal ? newHeight / mSnapshotView.getHeight() : 1.0f; - float centerDifference = (bottomMargin - topMargin) / 2; - float translationY = isOverlayModal ? centerDifference : 0; - this.animate().scaleX(scale).scaleY(scale).translationY(translationY) - .withEndAction(new Runnable() { - @Override - public void run() { - setCurveScale(scale); - mRunningModalAnimation = false; - } - }); + updateFooterVerticalOffset(mFooterVerticalOffset); } public TaskMenuView getMenuView() { @@ -535,12 +501,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mIconView.setScaleX(scale); mIconView.setScaleY(scale); - mFooterVerticalOffset = 1.0f - scale; - for (FooterWrapper footer : mFooters) { - if (footer != null) { - footer.updateFooterOffset(); - } - } + updateFooterVerticalOffset(1.0f - scale); } public void setIconScaleAnimStartProgress(float startProgress) { @@ -586,6 +547,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { public void resetVisualProperties() { resetViewTransforms(); setFullscreenProgress(0); + setModalness(0); } public void setStableAlpha(float parentAlpha) { @@ -606,7 +568,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { @Override public void onPageScroll(ScrollState scrollState) { // Don't do anything if it's modal. - if (mRunningModalAnimation || isTaskOverlayModal()) { + if (mModalness > 0) { return; } @@ -759,6 +721,12 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mStackHeight += footer.mView.getHeight(); } } + updateFooterVerticalOffset(0); + } + + private void updateFooterVerticalOffset(float offset) { + mFooterVerticalOffset = offset; + for (FooterWrapper footer : mFooters) { if (footer != null) { footer.updateFooterOffset(); @@ -857,7 +825,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } void updateFooterOffset() { - mAnimationOffset = Math.round(mStackHeight * mFooterVerticalOffset); + float offset = Utilities.or(mFooterVerticalOffset, mModalness); + mAnimationOffset = Math.round(mStackHeight * offset); mView.setTranslationY(mAnimationOffset + mEntryAnimationOffset + mCurrentFullscreenParams.mCurrentDrawnInsets.bottom + mCurrentFullscreenParams.mCurrentDrawnInsets.top); @@ -880,22 +849,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { animator.setDuration(100); animator.start(); } - - void animateHide() { - ValueAnimator animator = ValueAnimator.ofFloat(0.0f, 1.0f); - animator.addUpdateListener(anim -> { - mFooterVerticalOffset = anim.getAnimatedFraction(); - updateFooterOffset(); - }); - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - removeView(mView); - } - }); - animator.setDuration(100); - animator.start(); - } } private int getExpectedViewHeight(View view) { diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java index 33011acb09..ac50d6db8a 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java @@ -21,6 +21,7 @@ import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS; 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_SCRIM_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X; @@ -66,6 +67,7 @@ public abstract class BaseRecentsViewStateController getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0); OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim(); SCRIM_PROGRESS.set(scrim, state.getOverviewScrimAlpha(mLauncher)); + getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness()); } @Override @@ -101,8 +103,15 @@ public abstract class BaseRecentsViewStateController OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim(); setter.setFloat(scrim, SCRIM_PROGRESS, toState.getOverviewScrimAlpha(mLauncher), config.getInterpolator(ANIM_OVERVIEW_SCRIM_FADE, LINEAR)); + + setter.setFloat( + mRecentsView, getTaskModalnessProperty(), + toState.getOverviewModalness(), + config.getInterpolator(ANIM_OVERVIEW_MODAL, AGGRESSIVE_EASE_IN_OUT)); } + abstract FloatProperty getTaskModalnessProperty(); + /** * Get property for content alpha for the recents view. * diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 54d8f0d8bc..e2b867e138 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -36,6 +36,7 @@ import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.OVERVIEW_MODAL_TASK_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.OVERVIEW_PEEK_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL; import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL; @@ -101,7 +102,7 @@ public abstract class LauncherState { } }; - private static final LauncherState[] sAllStates = new LauncherState[8]; + private static final LauncherState[] sAllStates = new LauncherState[9]; /** * TODO: Create a separate class for NORMAL state. @@ -128,6 +129,8 @@ public abstract class LauncherState { public static final LauncherState OVERVIEW = new OverviewState(OVERVIEW_STATE_ORDINAL); public static final LauncherState OVERVIEW_PEEK = OverviewState.newPeekState(OVERVIEW_PEEK_STATE_ORDINAL); + public static final LauncherState OVERVIEW_MODAL_TASK = OverviewState.newModalTaskState( + OVERVIEW_MODAL_TASK_STATE_ORDINAL); public static final LauncherState QUICK_SWITCH = OverviewState.newSwitchState(QUICK_SWITCH_STATE_ORDINAL); public static final LauncherState BACKGROUND_APP = @@ -279,6 +282,14 @@ public abstract class LauncherState { return 0; } + /** + * For this state, how modal should over view been shown. 0 modalness means all tasks drawn, + * 1 modalness means the current task is show on its own. + */ + public float getOverviewModalness() { + return 0; + } + /** * The amount of blur and wallpaper zoom to apply to the background of either the app * or Launcher surface in this state. Should be a number between 0 and 1, inclusive. diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 3c3ab6cc62..d95ccb43be 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -339,6 +339,30 @@ public final class Utilities { return min + (value * (max - min)); } + /** + * Bounds parameter to the range [0, 1] + */ + public static float saturate(float a) { + return boundToRange(a, 0, 1.0f); + } + + /** + * Returns the compliment (1 - a) of the parameter. + */ + public static float comp(float a) { + return 1 - a; + } + + /** + * Returns the "probabilistic or" of a and b. (a + b - ab). + * Useful beyond probability, can be used to combine two unit progresses for example. + */ + public static float or(float a, float b) { + float satA = saturate(a); + float satB = saturate(b); + return satA + satB - (satA * satB); + } + /** * Trims the string, removing all whitespace at the beginning and end of the string. * Non-breaking whitespaces are also removed. diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java index 8dccbd3207..1c4986728f 100644 --- a/src/com/android/launcher3/states/StateAnimationConfig.java +++ b/src/com/android/launcher3/states/StateAnimationConfig.java @@ -69,6 +69,7 @@ public class StateAnimationConfig { ANIM_ALL_APPS_FADE, ANIM_OVERVIEW_SCRIM_FADE, ANIM_ALL_APPS_HEADER_FADE, + ANIM_OVERVIEW_MODAL }) @Retention(RetentionPolicy.SOURCE) public @interface AnimType {} @@ -85,8 +86,9 @@ public class StateAnimationConfig { public static final int ANIM_ALL_APPS_FADE = 10; public static final int ANIM_OVERVIEW_SCRIM_FADE = 11; public static final int ANIM_ALL_APPS_HEADER_FADE = 12; // e.g. predictions + public static final int ANIM_OVERVIEW_MODAL = 13; - private static final int ANIM_TYPES_COUNT = 13; + private static final int ANIM_TYPES_COUNT = 14; private final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT]; diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index a5a06b409c..fba6269097 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -28,10 +28,11 @@ public final class TestProtocol { public static final int SPRING_LOADED_STATE_ORDINAL = 1; public static final int OVERVIEW_STATE_ORDINAL = 2; public static final int OVERVIEW_PEEK_STATE_ORDINAL = 3; - public static final int QUICK_SWITCH_STATE_ORDINAL = 4; - public static final int ALL_APPS_STATE_ORDINAL = 5; - public static final int BACKGROUND_APP_STATE_ORDINAL = 6; - public static final int HINT_STATE_ORDINAL = 7; + public static final int OVERVIEW_MODAL_TASK_STATE_ORDINAL = 4; + public static final int QUICK_SWITCH_STATE_ORDINAL = 5; + public static final int ALL_APPS_STATE_ORDINAL = 6; + public static final int BACKGROUND_APP_STATE_ORDINAL = 7; + public static final int HINT_STATE_ORDINAL = 8; public static final String TAPL_EVENTS_TAG = "TaplEvents"; public static final String SEQUENCE_MAIN = "Main"; public static final String SEQUENCE_TIS = "TIS"; @@ -47,6 +48,8 @@ public final class TestProtocol { return "Overview"; case OVERVIEW_PEEK_STATE_ORDINAL: return "OverviewPeek"; + case OVERVIEW_MODAL_TASK_STATE_ORDINAL: + return "OverviewModalState"; case QUICK_SWITCH_STATE_ORDINAL: return "QuickSwitch"; case ALL_APPS_STATE_ORDINAL: diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java index e20b2ca1d2..507ff59b31 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java @@ -44,4 +44,11 @@ public class OverviewState extends LauncherState { public static OverviewState newSwitchState(int id) { return new OverviewState(id); } + + /** + * New Overview substate that represents the overview in modal mode (one task shown on its own) + */ + public static OverviewState newModalTaskState(int id) { + return new OverviewState(id); + } } From 48ea9e9502dde3db2de94a9f07e9bbe59ead4464 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Sun, 19 Apr 2020 19:21:29 -0700 Subject: [PATCH 05/65] Use appropriate start padding for clear all button This still shows up a bit strange with notched phones because we are using RecentsView padding to give ClearAll the right amount of spacing. However, we're only adding padding to the left and right and not the top/bottom. That's captured here: b/154436527 Fixes: 150389833 Test: Tested landscape/portrait/seascape launcher, w/ RTL as well Change-Id: I49defd58048e609a1f7a821abb97374bcbb94b9f --- .../com/android/quickstep/views/ClearAllButton.java | 3 ++- .../launcher3/touch/LandscapePagedViewHandler.java | 5 +++++ .../launcher3/touch/PagedOrientationHandler.java | 1 + .../launcher3/touch/PortraitPagedViewHandler.java | 5 +++++ .../launcher3/touch/SeascapePagedViewHandler.java | 11 +++++++++++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/ClearAllButton.java index e455939f0e..1018211ed2 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/ClearAllButton.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/ClearAllButton.java @@ -56,7 +56,8 @@ public class ClearAllButton extends Button implements PageCallbacks { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - mScrollOffset = mIsRtl ? mParent.getPaddingRight() / 2 : - mParent.getPaddingLeft() / 2; + PagedOrientationHandler orientationHandler = mParent.getPagedOrientationHandler(); + mScrollOffset = orientationHandler.getClearAllScrollOffset(mParent, mIsRtl); } @Override diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java index dc500536d3..86d3c615e8 100644 --- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java @@ -125,6 +125,11 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { return rect.height(); } + @Override + public int getClearAllScrollOffset(View view, boolean isRtl) { + return (isRtl ? view.getPaddingBottom() : - view.getPaddingTop()) / 2; + } + @Override public int getSecondaryDimension(View view) { return view.getWidth(); diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java index cc15f99127..02a020f61a 100644 --- a/src/com/android/launcher3/touch/PagedOrientationHandler.java +++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java @@ -62,6 +62,7 @@ public interface PagedOrientationHandler { float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId); int getMeasuredSize(View view); float getPrimarySize(RectF rect); + int getClearAllScrollOffset(View view, boolean isRtl); int getSecondaryDimension(View view); FloatProperty getPrimaryViewTranslate(); FloatProperty getSecondaryViewTranslate(); diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index 7c30e29aa4..b253e7d764 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -122,6 +122,11 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { return rect.width(); } + @Override + public int getClearAllScrollOffset(View view, boolean isRtl) { + return (isRtl ? view.getPaddingRight() : - view.getPaddingLeft()) / 2; + } + @Override public int getSecondaryDimension(View view) { return view.getHeight(); diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java index 7beb7f7466..e86ec3b6af 100644 --- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java @@ -75,4 +75,15 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler { public float getTaskMenuY(float y, View thumbnailView) { return y + thumbnailView.getMeasuredHeight(); } + + @Override + public int getClearAllScrollOffset(View view, boolean isRtl) { + return (isRtl ? view.getPaddingTop() : - view.getPaddingBottom()) / 2; + } + + @Override + public void setPrimaryAndResetSecondaryTranslate(View view, float translation) { + view.setTranslationX(0); + view.setTranslationY(-translation); + } } From 898bd99116e9e51a9d7e4515c48137ba9cfaf9e3 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Mon, 27 Apr 2020 21:57:02 -0700 Subject: [PATCH 06/65] Force all apps content to be alpha 0 when plugin is in place Bug: 155114822 Change-Id: I9b2d10d5c009c3bb4fb2cf4cb4d9ff50153eba39 --- .../android/launcher3/allapps/AllAppsTransitionController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 071c03d23a..ab556f297c 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -230,6 +230,8 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil hasAllAppsContent, setter, headerFade, allAppsFade); } else { setter.setViewAlpha(mPluginContent, hasAllAppsContent ? 1 : 0, allAppsFade); + setter.setViewAlpha(mAppsView.getContentView(), 0, allAppsFade); + setter.setViewAlpha(mAppsView.getScrollBar(), 0, allAppsFade); } mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade); From 72c9da7647c8111144a2f291fa797d80ce40aaae Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Tue, 28 Apr 2020 12:53:07 -0700 Subject: [PATCH 07/65] Bias rotation to remain in existing rotation Change-Id: I3457dc7946838eb7e0e68a879091941ce4674a7a --- .../quickstep/util/RecentsOrientedState.java | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index 74daeca33f..12e057f070 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -17,6 +17,7 @@ package com.android.quickstep.util; import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE; +import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; @@ -135,7 +136,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre mOrientationListener = new OrientationEventListener(context) { @Override public void onOrientationChanged(int degrees) { - int newRotation = getRotationForUserDegreesRotated(degrees); + int newRotation = getRotationForUserDegreesRotated(degrees, mPreviousRotation); if (newRotation != mPreviousRotation) { mPreviousRotation = newRotation; rotationChangeListener.accept(newRotation); @@ -392,17 +393,48 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre } @SurfaceRotation - public static int getRotationForUserDegreesRotated(float degrees) { - int threshold = 70; - if (degrees >= (360 - threshold) || degrees < (threshold)) { - return ROTATION_0; - } else if (degrees < (90 + threshold)) { - return ROTATION_270; - } else if (degrees < 180 + threshold) { - return ROTATION_180; - } else { - return ROTATION_90; + public static int getRotationForUserDegreesRotated(float degrees, int currentRotation) { + if (degrees == ORIENTATION_UNKNOWN) { + return currentRotation; } + + int threshold = 70; + switch (currentRotation) { + case ROTATION_0: + if (degrees > 180 && degrees < (360 - threshold)) { + return ROTATION_90; + } + if (degrees < 180 && degrees > threshold) { + return ROTATION_270; + } + break; + case ROTATION_270: + if (degrees < (90 - threshold)) { + return ROTATION_0; + } + if (degrees > (90 + threshold)) { + return ROTATION_180; + } + break; + case ROTATION_180: + if (degrees < (180 - threshold)) { + return ROTATION_270; + } + if (degrees > (180 + threshold)) { + return ROTATION_90; + } + break; + case ROTATION_90: + if (degrees < (270 - threshold)) { + return ROTATION_180; + } + if (degrees > (270 + threshold)) { + return ROTATION_0; + } + break; + } + + return currentRotation; } public boolean isDisplayPhoneNatural() { From 3f3cc3e96e453edea3b77a3909063c5da590412a Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 27 Apr 2020 22:30:58 -0700 Subject: [PATCH 08/65] Enable edge back gesture on app launch We don't clear state on EdgeBackGestureHandler when we go to Recents or Home. A more robust solution is in the works with WM team and will probably be built on top of this. Needs ag/11273364 to work. Bug: 154580671 Test: Launch app directly in landscape, should be able to swipe home on first try. Change-Id: Ia4c685e16645d0237f278a611f6c61f252f3b79c --- .../quickstep/OrientationTouchTransformer.java | 15 +++++++++------ .../quickstep/RecentsAnimationDeviceState.java | 14 ++++++-------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java index 2a9f32daf5..879fd1d64f 100644 --- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java +++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java @@ -55,6 +55,8 @@ class OrientationTouchTransformer { private static final boolean DEBUG = false; private static final int MAX_ORIENTATIONS = 4; + private static final int QUICKSTEP_ROTATION_UNINITIALIZED = -1; + private final Matrix mTmpMatrix = new Matrix(); private final float[] mTmpPoint = new float[2]; @@ -69,9 +71,10 @@ class OrientationTouchTransformer { private QuickStepContractInfo mContractInfo; /** - * Represents if we're currently in a swipe "session" of sorts. If value is -1, then user - * has not tapped on an active nav region. Otherwise it will be the rotation of the display - * when the user first interacted with the active nav bar region. + * Represents if we're currently in a swipe "session" of sorts. If value is + * QUICKSTEP_ROTATION_UNINITIALIZED, then user has not tapped on an active nav region. + * Otherwise it will be the rotation of the display when the user first interacted with the + * active nav bar region. * The "session" ends when {@link #enableMultipleRegions(boolean, DefaultDisplay.Info)} is * called - usually from a timeout or if user starts interacting w/ the foreground app. * @@ -79,7 +82,7 @@ class OrientationTouchTransformer { * the rect is purely used for tracking touch interactions and usually this "session" will * outlast the touch interaction. */ - private int mQuickStepStartingRotation = -1; + private int mQuickStepStartingRotation = QUICKSTEP_ROTATION_UNINITIALIZED; /** For testability */ interface QuickStepContractInfo { @@ -116,7 +119,7 @@ class OrientationTouchTransformer { */ void createOrAddTouchRegion(DefaultDisplay.Info info) { mCurrentDisplayRotation = info.rotation; - if (mQuickStepStartingRotation > -1 + if (mQuickStepStartingRotation > QUICKSTEP_ROTATION_UNINITIALIZED && mCurrentDisplayRotation == mQuickStepStartingRotation) { // User already was swiping and the current screen is same rotation as the starting one // Remove active nav bars in other rotations except for the one we started out in @@ -146,7 +149,7 @@ class OrientationTouchTransformer { mEnableMultipleRegions = enableMultipleRegions && mMode != SysUINavigationMode.Mode.TWO_BUTTONS; if (!enableMultipleRegions) { - mQuickStepStartingRotation = -1; + mQuickStepStartingRotation = QUICKSTEP_ROTATION_UNINITIALIZED; resetSwipeRegions(info); } } diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java index a6ce2b5340..ef14e2888d 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java @@ -511,14 +511,12 @@ public class RecentsAnimationDeviceState implements void enableMultipleRegions(boolean enable) { mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo()); - if (enable) { - UI_HELPER_EXECUTOR.execute(() -> { - int quickStepStartingRotation = - mOrientationTouchTransformer.getQuickStepStartingRotation(); - SystemUiProxy.INSTANCE.get(mContext) - .onQuickSwitchToNewTask(quickStepStartingRotation); - }); - } + UI_HELPER_EXECUTOR.execute(() -> { + int quickStepStartingRotation = + mOrientationTouchTransformer.getQuickStepStartingRotation(); + SystemUiProxy.INSTANCE.get(mContext) + .onQuickSwitchToNewTask(quickStepStartingRotation); + }); } public int getCurrentActiveRotation() { From c6060e6e2a973a36eb065cd4377adf2294c0172d Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Mon, 27 Apr 2020 13:05:34 -0700 Subject: [PATCH 09/65] Refactor usage of getting GRID_OPTIONS_PREFERENCE_KEY value into whether GridOptionsProvider is enabled Bug: 154154093 Test: manual testing of the feature Change-Id: Ibe78a75b061aad20e8fa0e229589400b65016ff4 --- .../launcher3/InvariantDeviceProfile.java | 13 ++---- src/com/android/launcher3/Utilities.java | 41 +++++++++++++++++++ .../launcher3/settings/SettingsActivity.java | 2 +- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 63b90ae4f8..8951674879 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -19,7 +19,6 @@ package com.android.launcher3; import static com.android.launcher3.Utilities.getDevicePrefs; import static com.android.launcher3.Utilities.getPointString; import static com.android.launcher3.config.FeatureFlags.APPLY_CONFIG_AT_RUNTIME; -import static com.android.launcher3.settings.SettingsActivity.GRID_OPTIONS_PREFERENCE_KEY; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter; @@ -29,7 +28,6 @@ import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; @@ -216,9 +214,8 @@ public class InvariantDeviceProfile { } public static String getCurrentGridName(Context context) { - SharedPreferences prefs = Utilities.getPrefs(context); - return prefs.getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false) - ? prefs.getString(KEY_IDP_GRID_NAME, null) : null; + return Utilities.isGridOptionsEnabled(context) + ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) : null; } /** @@ -263,7 +260,7 @@ public class InvariantDeviceProfile { iconTextSize = displayOption.iconTextSize; fillResIconDpi = getLauncherIconDensity(iconBitmapSize); - if (Utilities.getPrefs(context).getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false)) { + if (Utilities.isGridOptionsEnabled(context)) { allAppsIconSize = displayOption.allAppsIconSize; allAppsIconTextSize = displayOption.allAppsIconTextSize; } else { @@ -344,9 +341,7 @@ public class InvariantDeviceProfile { InvariantDeviceProfile oldProfile = new InvariantDeviceProfile(this); // Re-init grid - String gridName = Utilities.getPrefs(context).getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false) - ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) - : null; + String gridName = getCurrentGridName(context); initGrid(context, gridName); int changeFlags = 0; diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 3c3ab6cc62..53563895a3 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -24,10 +24,13 @@ import android.app.ActivityManager; import android.app.Person; import android.app.WallpaperManager; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; import android.content.res.Resources; @@ -62,6 +65,7 @@ import android.view.animation.Interpolator; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.FolderAdaptiveIcon; +import com.android.launcher3.graphics.GridOptionsProvider; import com.android.launcher3.graphics.TintedDrawableSpan; import com.android.launcher3.icons.IconProvider; import com.android.launcher3.icons.LauncherIcons; @@ -76,6 +80,7 @@ import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.widget.PendingAddShortcutInfo; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; @@ -485,6 +490,42 @@ public final class Utilities { || e.getCause() instanceof DeadObjectException; } + public static boolean isGridOptionsEnabled(Context context) { + return isComponentEnabled(context.getPackageManager(), + context.getPackageName(), + GridOptionsProvider.class.getName()); + } + + private static boolean isComponentEnabled(PackageManager pm, String pkgName, String clsName) { + ComponentName componentName = new ComponentName(pkgName, clsName); + int componentEnabledSetting = pm.getComponentEnabledSetting(componentName); + + switch (componentEnabledSetting) { + case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: + return false; + case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: + return true; + case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: + default: + // We need to get the application info to get the component's default state + try { + PackageInfo packageInfo = pm.getPackageInfo(pkgName, + PackageManager.GET_PROVIDERS | PackageManager.GET_DISABLED_COMPONENTS); + + if (packageInfo.providers != null) { + return Arrays.stream(packageInfo.providers).anyMatch( + pi -> pi.name.equals(clsName) && pi.isEnabled()); + } + + // the component is not declared in the AndroidManifest + return false; + } catch (PackageManager.NameNotFoundException e) { + // the package isn't installed on the device + return false; + } + } + } + /** * Utility method to post a runnable on the handler, skipping the synchronization barriers. */ diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java index 12085c8b46..b94c6df3ed 100644 --- a/src/com/android/launcher3/settings/SettingsActivity.java +++ b/src/com/android/launcher3/settings/SettingsActivity.java @@ -71,7 +71,7 @@ public class SettingsActivity extends FragmentActivity private static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600; public static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted"; - public static final String GRID_OPTIONS_PREFERENCE_KEY = "pref_grid_options"; + private static final String GRID_OPTIONS_PREFERENCE_KEY = "pref_grid_options"; @Override protected void onCreate(Bundle savedInstanceState) { From c2140bcadd63e3ddc3764524f4fb678212b7ac57 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 28 Apr 2020 14:38:54 -0700 Subject: [PATCH 10/65] Change horizontal spring stiffness to 250. Change-Id: I453190b9c402aebdd723b23bcc08fea928da13c5 --- res/values/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/config.xml b/res/values/config.xml index 41bb909a1d..4f21315fab 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -132,7 +132,7 @@ 800 0.8 - 400 + 250 0.75 200 From 9dd8f411e52bc077803b805550a4c964d1edb9b0 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Tue, 28 Apr 2020 15:33:30 -0700 Subject: [PATCH 11/65] Remove grid options pref key Fixes: 154154093 Test: manual testing of the feature Change-Id: I48fa2788c163ebfe4b925e05d1526c0c1f3e3926 --- AndroidManifest-common.xml | 1 - .../launcher3/settings/SettingsActivity.java | 31 +------------------ 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index d7191b4b40..ff5bf0d1e5 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -156,7 +156,6 @@ - + "कार्यालयको प्रोफाइल अस्थायी रूपमा रोक्का गरिएको छ। कामसम्बन्धी एपहरूले तपाईंलाई सूचना पठाउन, तपाईंको यन्त्रको ब्याट्री प्रयोग गर्न वा तपाईंको स्थान हेर्न सक्दैनन्" "कामसम्बन्धी एप र सूचनाहरू अस्थायी रूपमा रोक्का गर्नुहोस्" "कार्य पूरा गर्न सकिएन: %1$s" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index b2cf426184..e548b8703d 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -139,7 +139,7 @@ "ବୁଝିଗଲି" "ୱାର୍କ ପ୍ରୋଫାଇଲକୁ ବିରତ କରାଯାଇଛି" "କାର୍ଯ୍ୟସ୍ଥଳୀ ଆପ୍ ଆପଣଙ୍କୁ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପଠାଇପାରିବ ନାହିଁ, ଆପଣଙ୍କ ବ୍ୟାଟେରୀକୁ ବ୍ୟବହାର କରିପାରିବ ନାହିଁ କିମ୍ବା ଆପଣଙ୍କ ଲୋକେସନକୁ ଆକ୍ସେସ୍ କରିପାରିବ ନାହିଁ" - "ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ବିରତ କରାଯାଇଛି। କାର୍ଯ୍ୟସ୍ଥଳୀ ଆପ୍ ଆପଣଙ୍କୁ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପଠାଇପାରିବ ନାହିଁ, ଆପଣଙ୍କ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରନ୍ତୁ କିମ୍ବା ଆପଣଙ୍କ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରନ୍ତୁ" + "ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ବିରତ କରାଯାଇଛି। କାର୍ଯ୍ୟସ୍ଥଳୀ ଆପ୍ ଆପଣଙ୍କୁ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପଠାଇପାରିବ ନାହିଁ, ଆପଣଙ୍କ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରନ୍ତୁ କିମ୍ବା ଆପଣଙ୍କ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରନ୍ତୁ" "କାର୍ଯ୍ୟସ୍ଥଳୀ ଆପ୍ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରନ୍ତୁ" "ବିଫଳ ହୋଇଛି: %1$s" From 0addbf0512aca0b075f6b7238c2f6c171291bd91 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 28 Apr 2020 14:17:35 -0700 Subject: [PATCH 20/65] Various multi-window fixes > Fixing scale up calculator for swipe-down > Offsetting pivot so that the preview is aligned to bottom-right > Allowing insets to be available in multi-window mode as well > Offsetting taskViewSimulator appropriately in multi-window mode Change-Id: I7da4c145efca72ef219a5ffcaf23d726812df270 --- .../states/BackgroundAppState.java | 19 +- .../android/quickstep/BaseSwipeUpHandler.java | 4 +- .../quickstep/FallbackActivityInterface.java | 4 +- .../quickstep/LauncherActivityInterface.java | 3 +- .../quickstep/LauncherSwipeHandler.java | 5 +- .../android/quickstep/RecentsActivity.java | 2 +- .../fallback/FallbackRecentsView.java | 23 +-- .../quickstep/util/TaskViewSimulator.java | 33 ++-- .../quickstep/views/LauncherRecentsView.java | 10 +- .../android/quickstep/views/RecentsView.java | 37 ++-- .../quickstep/views/TaskThumbnailView.java | 42 +++-- .../com/android/quickstep/views/TaskView.java | 9 +- .../android/quickstep/util/LayoutUtils.java | 120 +------------ .../quickstep/util/RecentsOrientedState.java | 49 +++-- .../quickstep/util/WindowSizeStrategy.java | 169 ++++++++++++++++++ .../launcher3/BaseDraggingActivity.java | 14 ++ src/com/android/launcher3/DeviceProfile.java | 29 ++- src/com/android/launcher3/Launcher.java | 10 +- .../android/launcher3/LauncherRootView.java | 11 +- src/com/android/launcher3/Utilities.java | 4 + 20 files changed, 329 insertions(+), 268 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/util/WindowSizeStrategy.java diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index e57e84184e..4718c81305 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -23,7 +23,6 @@ import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.views.RecentsView; -import com.android.quickstep.views.TaskView; /** * State indicating that the Launcher is behind an app @@ -66,23 +65,7 @@ public class BackgroundAppState extends OverviewState { } private float getOverviewScale(Launcher launcher) { - // Initialize the recents view scale to what it would be when starting swipe up - RecentsView recentsView = launcher.getOverviewPanel(); - int taskCount = recentsView.getTaskViewCount(); - if (taskCount == 0) return 1; - - TaskView dummyTask; - if (recentsView.getCurrentPage() >= recentsView.getTaskViewStartIndex()) { - if (recentsView.getCurrentPage() <= taskCount - 1) { - dummyTask = recentsView.getCurrentPageTaskView(); - } else { - dummyTask = recentsView.getTaskViewAt(taskCount - 1); - } - } else { - dummyTask = recentsView.getTaskViewAt(0); - } - return recentsView.getTempAppWindowAnimationHelper() - .updateForFullscreenOverview(dummyTask).getSrcToTargetScale(); + return ((RecentsView) launcher.getOverviewPanel()).getMaxScaleForFullScreen(); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index d22e5afcc5..9540ccf791 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -26,7 +26,6 @@ import android.animation.Animator; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; -import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; @@ -265,8 +264,7 @@ public abstract class BaseSwipeUpHandler mTaskAnimationManager = taskAnimationManager; mTouchTimeMs = touchTimeMs; mContinuingLastGesture = continuingLastGesture; - mTaskViewSimulator = new TaskViewSimulator( - context, LayoutUtils::calculateLauncherTaskSize, true); + mTaskViewSimulator = new TaskViewSimulator(context, LAUNCHER_ACTIVITY_SIZE_STRATEGY); initAfterSubclassConstructor(); initStateCallbacks(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index 52a25589a6..ff47f2c60e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -121,7 +121,7 @@ public final class RecentsActivity extends BaseRecentsActivity { protected DeviceProfile createDeviceProfile() { DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); return (mRecentsRootView != null) && isInMultiWindowMode() - ? dp.getMultiWindowProfile(this, mRecentsRootView.getLastKnownSize()) + ? dp.getMultiWindowProfile(this, getMultiWindowDisplaySize()) : super.createDeviceProfile(); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java index 3cf9b2cf5b..559004c3e4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -16,22 +16,19 @@ package com.android.quickstep.fallback; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; +import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.graphics.Canvas; -import android.graphics.Rect; import android.util.AttributeSet; import android.util.FloatProperty; import android.view.View; -import com.android.launcher3.DeviceProfile; import com.android.launcher3.Utilities; import com.android.quickstep.RecentsActivity; -import com.android.quickstep.util.LayoutUtils; 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.recents.model.Task.TaskKey; @@ -65,7 +62,7 @@ public class FallbackRecentsView extends RecentsView { } public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr, false); + super(context, attrs, defStyleAttr, FALLBACK_RECENTS_SIZE_STRATEGY); } @Override @@ -104,11 +101,6 @@ public class FallbackRecentsView extends RecentsView { resetViewUI(); } - @Override - protected void getTaskSize(DeviceProfile dp, Rect outRect) { - LayoutUtils.calculateFallbackTaskSize(getContext(), dp, outRect); - } - @Override public boolean shouldUseMultiWindowTaskSizeStrategy() { // Just use the activity task size for multi-window as well. @@ -140,16 +132,7 @@ public class FallbackRecentsView extends RecentsView { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - - if (getTaskViewCount() == 0) { - mZoomScale = 1f; - } else { - TaskView dummyTask = getTaskViewAt(0); - mZoomScale = getTempAppWindowAnimationHelper() - .updateForFullscreenOverview(dummyTask) - .getSrcToTargetScale(); - } - + mZoomScale = getMaxScaleForFullScreen(); setZoomProgress(mZoomInProgress); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java index 9781300117..17284b0e05 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java @@ -61,7 +61,7 @@ public class TaskViewSimulator { private final RecentsOrientedState mOrientationState; private final Context mContext; - private final TaskSizeProvider mSizeProvider; + private final WindowSizeStrategy mSizeStrategy; private final Rect mTaskRect = new Rect(); private final PointF mPivot = new PointF(); @@ -95,14 +95,12 @@ public class TaskViewSimulator { private boolean mLayoutValid = false; private boolean mScrollValid = false; - public TaskViewSimulator(Context context, TaskSizeProvider sizeProvider, - boolean rotationSupportedByActivity) { + public TaskViewSimulator(Context context, WindowSizeStrategy sizeStrategy) { mContext = context; - mSizeProvider = sizeProvider; + mSizeStrategy = sizeStrategy; mPositionHelper = new PreviewPositionHelper(context); - mOrientationState = new RecentsOrientedState(context, rotationSupportedByActivity, - i -> { }); + mOrientationState = new RecentsOrientedState(context, sizeStrategy, i -> { }); // We do not need to attach listeners as the simulator is created just for the gesture // duration, and any settings are unlikely to change during this mOrientationState.initWithoutListeners(); @@ -116,6 +114,7 @@ public class TaskViewSimulator { */ public void setDp(DeviceProfile dp, boolean isOpening) { mDp = dp; + mOrientationState.setMultiWindowMode(mDp.isMultiWindowMode); mBoostModeTargetLayers = isOpening ? MODE_OPENING : MODE_CLOSING; mLayoutValid = false; } @@ -143,7 +142,7 @@ public class TaskViewSimulator { if (mDp == null) { return 1; } - mSizeProvider.calculateTaskSize(mContext, mDp, mTaskRect); + mSizeStrategy.calculateTaskSize(mContext, mDp, mTaskRect); return mOrientationState.getFullScreenScaleAndPivot(mTaskRect, mDp, mPivot); } @@ -161,8 +160,7 @@ public class TaskViewSimulator { mThumbnailPosition.set(runningTarget.screenSpaceBounds); // TODO: Should sourceContainerBounds already have this offset? - mThumbnailPosition.offsetTo(mRunningTarget.position.x, mRunningTarget.position.y); - + mThumbnailPosition.offset(-mRunningTarget.position.x, -mRunningTarget.position.y); mLayoutValid = false; } @@ -198,7 +196,7 @@ public class TaskViewSimulator { ? mOrientationState.getDisplayRotation() : mPositionHelper.getCurrentRotation(); mPositionHelper.updateThumbnailMatrix(mThumbnailPosition, mThumbnailData, - mDp.isMultiWindowMode, mTaskRect.width(), mTaskRect.height()); + mTaskRect.width(), mTaskRect.height(), mDp); mPositionHelper.getMatrix().invert(mInversePositionMatrix); @@ -209,6 +207,7 @@ public class TaskViewSimulator { mScrollValid = false; } + if (!mScrollValid) { mScrollValid = true; int start = mOrientationState.getOrientationHandler() @@ -243,6 +242,8 @@ public class TaskViewSimulator { postDisplayRotation(deltaRotation( mOrientationState.getLauncherRotation(), mOrientationState.getDisplayRotation()), mDp.widthPx, mDp.heightPx, mMatrix); + mMatrix.postTranslate(mDp.windowX - mRunningTarget.position.x, + mDp.windowY - mRunningTarget.position.y); // Crop rect is the inverse of thumbnail matrix mTempRectF.set(-insets.left, -insets.top, @@ -298,16 +299,4 @@ public class TaskViewSimulator { // Ideally we should use square-root. This is an optimization as one of the dimension is 0. return Math.max(Math.abs(mTempPoint[0]), Math.abs(mTempPoint[1])); } - - /** - * Interface for calculating taskSize - */ - public interface TaskSizeProvider { - - /** - * Sets the outRect to the expected taskSize - */ - void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect); - } - } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java index 9005651fcf..aafad0c79e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java @@ -25,6 +25,7 @@ import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.QuickstepAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN; import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; +import static com.android.quickstep.util.WindowSizeStrategy.LAUNCHER_ACTIVITY_SIZE_STRATEGY; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; @@ -39,7 +40,6 @@ import android.view.View; import android.widget.FrameLayout; import com.android.launcher3.BaseQuickstepLauncher; -import com.android.launcher3.DeviceProfile; import com.android.launcher3.Hotseat; import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.StateListener; @@ -53,7 +53,6 @@ import com.android.launcher3.views.ScrimView; import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.util.AppWindowAnimationHelper; import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams; -import com.android.quickstep.util.LayoutUtils; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.RecentsExtraCard; @@ -96,7 +95,7 @@ public class LauncherRecentsView extends RecentsView } public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr, true); + super(context, attrs, defStyleAttr, LAUNCHER_ACTIVITY_SIZE_STRATEGY); mActivity.getStateManager().addStateListener(this); } @@ -178,11 +177,6 @@ public class LauncherRecentsView extends RecentsView return anim; } - @Override - protected void getTaskSize(DeviceProfile dp, Rect outRect) { - LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect); - } - @Override protected void onTaskLaunchAnimationUpdate(float progress, TaskView tv) { if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index cd3abed042..411f057bc6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -122,6 +122,7 @@ import com.android.quickstep.TaskUtils; import com.android.quickstep.ViewUtils; import com.android.quickstep.util.AppWindowAnimationHelper; import com.android.quickstep.util.RecentsOrientedState; +import com.android.quickstep.util.WindowSizeStrategy; import com.android.systemui.plugins.ResourceProvider; import com.android.systemui.shared.recents.IPinnedStackAnimationListener; import com.android.systemui.shared.recents.model.Task; @@ -202,6 +203,7 @@ public abstract class RecentsView extends PagedView impl }; protected final RecentsOrientedState mOrientationState; + protected final WindowSizeStrategy mSizeStrategy; protected RecentsAnimationController mRecentsAnimationController; protected RecentsAnimationTargets mRecentsAnimationTargets; protected AppWindowAnimationHelper mAppWindowAnimationHelper; @@ -225,7 +227,6 @@ public abstract class RecentsView extends PagedView impl private final ClearAllButton mClearAllButton; private final Rect mClearAllButtonDeadZoneRect = new Rect(); private final Rect mTaskViewDeadZoneRect = new Rect(); - protected final AppWindowAnimationHelper mTempAppWindowAnimationHelper; private final ScrollState mScrollState = new ScrollState(); // Keeps track of the previously known visible tasks for purposes of loading/unloading task data @@ -373,20 +374,19 @@ public abstract class RecentsView extends PagedView impl }; public RecentsView(Context context, AttributeSet attrs, int defStyleAttr, - boolean rotationSupportedByActivity) { + WindowSizeStrategy sizeStrategy) { super(context, attrs, defStyleAttr); setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing)); setEnableFreeScroll(true); + mSizeStrategy = sizeStrategy; mOrientationState = new RecentsOrientedState( - context, rotationSupportedByActivity, this::animateRecentsRotationInPlace); + context, mSizeStrategy, this::animateRecentsRotationInPlace); mFastFlingVelocity = getResources() .getDimensionPixelSize(R.dimen.recents_fast_fling_velocity); mActivity = BaseActivity.fromContext(context); mModel = RecentsModel.INSTANCE.get(context); mIdp = InvariantDeviceProfile.INSTANCE.get(context); - mTempAppWindowAnimationHelper = - new AppWindowAnimationHelper(getPagedViewOrientedState(), context); mClearAllButton = (ClearAllButton) LayoutInflater.from(context) .inflate(R.layout.overview_clear_all_button, this, false); @@ -712,7 +712,7 @@ public abstract class RecentsView extends PagedView impl final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex; final Task task = tasks.get(i); final TaskView taskView = (TaskView) getChildAt(pageIndex); - taskView.bind(task, mOrientationState, mActivity.getDeviceProfile().isMultiWindowMode); + taskView.bind(task, mOrientationState); } if (mNextPage == INVALID_PAGE) { @@ -802,7 +802,8 @@ public abstract class RecentsView extends PagedView impl public void setInsets(Rect insets) { mInsets.set(insets); DeviceProfile dp = mActivity.getDeviceProfile(); - getTaskSize(dp, mTempRect); + mOrientationState.setMultiWindowMode(dp.isMultiWindowMode); + getTaskSize(mTempRect); mTaskWidth = mTempRect.width(); mTaskHeight = mTempRect.height(); @@ -812,10 +813,8 @@ public abstract class RecentsView extends PagedView impl dp.heightPx - mInsets.bottom - mTempRect.bottom); } - protected abstract void getTaskSize(DeviceProfile dp, Rect outRect); - public void getTaskSize(Rect outRect) { - getTaskSize(mActivity.getDeviceProfile(), outRect); + mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect); } @Override @@ -1068,8 +1067,7 @@ public abstract class RecentsView extends PagedView impl new ComponentName(getContext(), getClass()), 0, 0), null, null, "", "", 0, 0, false, true, false, false, new ActivityManager.TaskDescription(), 0, new ComponentName("", ""), false); - taskView.bind(mTmpRunningTask, mOrientationState, - mActivity.getDeviceProfile().isMultiWindowMode); + taskView.bind(mTmpRunningTask, mOrientationState); } boolean runningTaskTileHidden = mRunningTaskTileHidden; @@ -1764,7 +1762,7 @@ public abstract class RecentsView extends PagedView impl int centerTaskIndex = getCurrentPage(); boolean launchingCenterTask = taskIndex == centerTaskIndex; - float toScale = appWindowAnimationHelper.getSrcToTargetScale(); + float toScale = getMaxScaleForFullScreen(); if (launchingCenterTask) { RecentsView recentsView = tv.getRecentsView(); anim.play(ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY, toScale)); @@ -1786,6 +1784,15 @@ public abstract class RecentsView extends PagedView impl return anim; } + /** + * Returns the scale up required on the view, so that it coves the screen completely + */ + public float getMaxScaleForFullScreen() { + getTaskSize(mTempRect); + return getPagedViewOrientedState().getFullScreenScaleAndPivot( + mTempRect, mActivity.getDeviceProfile(), mTempPointF); + } + public PendingAnimation createTaskLaunchAnimation( TaskView tv, long duration, Interpolator interpolator) { if (FeatureFlags.IS_STUDIO_BUILD && mPendingAnimation != null) { @@ -2079,10 +2086,6 @@ public abstract class RecentsView extends PagedView impl return mAppWindowAnimationHelper; } - public AppWindowAnimationHelper getTempAppWindowAnimationHelper() { - return mTempAppWindowAnimationHelper; - } - public AppWindowAnimationHelper.TransformParams getLiveTileParams( boolean mightNeedToRefill) { return null; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java index e525842db0..aa08e86f22 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java @@ -36,12 +36,12 @@ import android.graphics.RectF; import android.graphics.Shader; import android.util.AttributeSet; import android.util.FloatProperty; -import android.util.Log; import android.util.Property; import android.view.Surface; import android.view.View; import com.android.launcher3.BaseActivity; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper; @@ -104,7 +104,6 @@ public class TaskThumbnailView extends View implements PluginListener 0 || insets.right > 0 || insets.bottom > 0)) { - mConsumedInsets.left = insets.left; - mConsumedInsets.right = insets.right; - mConsumedInsets.bottom = insets.bottom; - insets.set(0, insets.top, 0, 0); - drawInsetBar = true; - } else if ((insets.right > 0 || insets.left > 0) && - getContext().getSystemService(ActivityManager.class).isLowRamDevice()) { + if ((insets.right > 0 || insets.left > 0) + && getContext().getSystemService(ActivityManager.class).isLowRamDevice()) { mConsumedInsets.left = insets.left; mConsumedInsets.right = insets.right; insets.set(0, insets.top, 0, insets.bottom); diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 7baee9509f..8e33406ed5 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -63,6 +63,8 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.animation.Interpolator; +import androidx.core.os.BuildCompat; + import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.FolderAdaptiveIcon; import com.android.launcher3.graphics.GridOptionsProvider; @@ -104,6 +106,8 @@ public final class Utilities { public static final String[] EMPTY_STRING_ARRAY = new String[0]; public static final Person[] EMPTY_PERSON_ARRAY = new Person[0]; + public static final boolean ATLEAST_R = BuildCompat.isAtLeastR(); + public static final boolean ATLEAST_Q = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; public static final boolean ATLEAST_P = From a5877307d159f4773fb26146e798b98540e7ac17 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Wed, 29 Apr 2020 12:12:44 -0700 Subject: [PATCH 21/65] Dump RecentsOrientationState for bug reports Bug: 154951045 Test: New output shows up when running "adb shell dumpsys activity com.google.android.apps.nexuslauncher.NexusLauncherActivity [--all]" Change-Id: I5e9ace7d370eb0e9d278d7d9f7f9156674ca1a50 --- .../uioverrides/QuickstepLauncher.java | 11 +++++++++++ .../quickstep/util/RecentsOrientedState.java | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 87ca2b688a..634eb4980d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -56,6 +56,8 @@ import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.views.RecentsView; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.stream.Stream; @@ -227,4 +229,13 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { mActivity.getStateManager().setCurrentUserControlledAnimation(animController); } } + + @Override + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + RecentsView recentsView = getOverviewPanel(); + writer.println("\nQuickstepLauncher:"); + writer.println(prefix + "\tmOrientationState: " + (recentsView == null ? "recentsNull" : + recentsView.getPagedViewOrientedState())); + } } diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index 74daeca33f..97424fba53 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -44,6 +44,7 @@ import android.view.OrientationEventListener; import android.view.Surface; import androidx.annotation.IntDef; +import androidx.annotation.NonNull; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Utilities; @@ -64,7 +65,7 @@ import java.util.function.IntConsumer; public final class RecentsOrientedState implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = "RecentsOrientedState"; - private static final boolean DEBUG = false; + private static final boolean DEBUG = true; private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform"; @@ -440,4 +441,19 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre return Settings.Global.getInt( context.getContentResolver(), FIXED_ROTATION_TRANSFORM_SETTING_NAME, 1) == 1; } + + @NonNull + @Override + public String toString() { + boolean systemRotationOn = (mFlags & FLAG_SYSTEM_ROTATION_ALLOWED) != 0; + return "[" + + "mDisplayRotation=" + mDisplayRotation + + " mTouchRotation=" + mTouchRotation + + " mLauncherRotation=" + mLauncherRotation + + " mHomeRotation=" + isHomeRotationAllowed() + + " mSystemRotation=" + systemRotationOn + + " mFlags=" + mFlags + + " mOrientationHandler=" + mOrientationHandler + + "]"; + } } From a1f0a106624012bba5ae6d060b051e84e27b9a23 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 29 Apr 2020 14:22:46 -0700 Subject: [PATCH 22/65] Removing tracking activity start/stop events They were not especially useful in investigations; besides, these events can be sent by the system asynchronously for actions that happened before entering TAPL, causing flakes. Change-Id: I72b5aad5521c6c0969f5b657b3db3e4d855f1d64 --- src/com/android/launcher3/Launcher.java | 3 --- .../com/android/launcher3/tapl/Background.java | 18 ------------------ .../com/android/launcher3/tapl/Launchable.java | 7 ++----- .../tapl/LauncherInstrumentation.java | 8 -------- .../launcher3/tapl/OptionsPopupMenuItem.java | 8 -------- .../android/launcher3/tapl/OverviewTask.java | 2 -- .../com/android/launcher3/tapl/Workspace.java | 4 ---- 7 files changed, 2 insertions(+), 48 deletions(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 070a3926c4..e556bd6b98 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -921,8 +921,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } }); } - - TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Activity.onStop"); } @Override @@ -936,7 +934,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mAppWidgetHost.setListenIfResumed(true); TraceHelper.INSTANCE.endSection(traceToken); - TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Activity.onStart"); } private void handleDeferredResume() { diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 80b8e89601..94ab780649 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -71,7 +71,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer { } protected void goToOverviewUnchecked() { - final boolean launcherWasVisible = mLauncher.isLauncherVisible(); switch (mLauncher.getNavigationModel()) { case ZERO_BUTTON: { final int centerX = mLauncher.getDevice().getDisplayWidth() / 2; @@ -138,11 +137,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer { break; } expectSwitchToOverviewEvents(); - - if (!launcherWasVisible) { - mLauncher.expectEvent( - TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START_ACTIVITY); - } } private void expectSwitchToOverviewEvents() { @@ -192,11 +186,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer { } final boolean isZeroButton = mLauncher.getNavigationModel() == LauncherInstrumentation.NavigationModel.ZERO_BUTTON; - if (!launcherWasVisible) { - mLauncher.expectEvent( - TestProtocol.SEQUENCE_MAIN, - LauncherInstrumentation.EVENT_START_ACTIVITY); - } mLauncher.swipeToState(startX, startY, endX, endY, 20, expectedState, launcherWasVisible && isZeroButton ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE @@ -208,11 +197,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer { // Double press the recents button. UiObject2 recentsButton = mLauncher.waitForSystemUiObject("recent_apps"); mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT); - if (!launcherWasVisible) { - mLauncher.expectEvent( - TestProtocol.SEQUENCE_MAIN, - LauncherInstrumentation.EVENT_START_ACTIVITY); - } mLauncher.runToState(() -> recentsButton.click(), OVERVIEW_STATE_ORDINAL); mLauncher.getOverview(); mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT); @@ -220,8 +204,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer { break; } mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT); - mLauncher.expectEvent( - TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_STOP_ACTIVITY); } protected String getSwipeHeightRequestName() { diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java index df7436ce8f..13ecfb8589 100644 --- a/tests/tapl/com/android/launcher3/tapl/Launchable.java +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -25,8 +25,6 @@ import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.Until; -import com.android.launcher3.testing.TestProtocol; - /** * Ancestor for AppIcon and AppMenuItem. */ @@ -64,8 +62,6 @@ abstract class Launchable { event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED, () -> "Launching an app didn't open a new window: " + mObject.getText()); expectActivityStartEvents(); - mLauncher.expectEvent( - TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_STOP_ACTIVITY); mLauncher.assertTrue( "App didn't start: " + selector, @@ -76,7 +72,8 @@ abstract class Launchable { /** * Drags an object to the center of homescreen. - * @param startsActivity whether it's expected to start an activity. + * + * @param startsActivity whether it's expected to start an activity. * @param isWidgetShortcut whether we drag a widget shortcut */ public void dragToWorkspace(boolean startsActivity, boolean isWidgetShortcut) { diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index d46845f118..bad8be5133 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -97,8 +97,6 @@ public final class LauncherInstrumentation { private static final Pattern EVENT_TOUCH_UP = getTouchEventPattern("ACTION_UP"); private static final Pattern EVENT_TOUCH_CANCEL = getTouchEventPattern("ACTION_CANCEL"); private static final Pattern EVENT_PILFER_POINTERS = Pattern.compile("pilferPointers"); - static final Pattern EVENT_START_ACTIVITY = Pattern.compile("Activity\\.onStart"); - static final Pattern EVENT_STOP_ACTIVITY = Pattern.compile("Activity\\.onStop"); static final Pattern EVENT_START = Pattern.compile("start:"); static final Pattern EVENT_TOUCH_DOWN_TIS = getTouchEventPatternTIS("ACTION_DOWN"); @@ -680,14 +678,8 @@ public final class LauncherInstrumentation { ? GestureScope.INSIDE_TO_OUTSIDE : GestureScope.OUTSIDE); } - if (!launcherWasVisible) { - expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_START_ACTIVITY); - } } } else { - if (!launcherWasVisible) { - expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_START_ACTIVITY); - } log("Hierarchy before clicking home:"); dumpViewHierarchy(); log(action = "clicking home button from " + getVisibleStateMessage()); diff --git a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java index d1268ccc2c..42b6bc9b3a 100644 --- a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java +++ b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java @@ -15,8 +15,6 @@ */ package com.android.launcher3.tapl; -import android.os.Build; - import androidx.annotation.NonNull; import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiObject2; @@ -44,12 +42,6 @@ public class OptionsPopupMenuItem { + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject)); mLauncher.clickLauncherObject(mObject); mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START); - if (!Build.MODEL.contains("Cuttlefish") || - Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q && - !"R".equals(Build.VERSION.CODENAME)) { - mLauncher.expectEvent( - TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_STOP_ACTIVITY); - } mLauncher.assertTrue( "App didn't start: " + By.pkg(expectedPackageName), mLauncher.getDevice().wait(Until.hasObject(By.pkg(expectedPackageName)), diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java index fae5f19126..b2359190ba 100644 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java +++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java @@ -79,8 +79,6 @@ public final class OverviewTask { () -> "Launching task didn't open a new window: " + mTask.getParent().getContentDescription()); mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT); - mLauncher.expectEvent( - TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_STOP_ACTIVITY); } return new Background(mLauncher); } diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index 0d91dc2db8..9f809173b7 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -229,10 +229,6 @@ public final class Workspace extends Home { if (startsActivity || isWidgetShortcut) { launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START); } - if (startsActivity) { - launcher.expectEvent( - TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_STOP_ACTIVITY); - } LauncherInstrumentation.log("dragIconToWorkspace: end"); launcher.waitUntilGone("drop_target_bar"); } From d75c1da9c7b2a3c98be0be9c9f06cbf1af772e10 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 29 Apr 2020 15:25:40 -0700 Subject: [PATCH 23/65] Allow synchronous modification of update listeners list We create a copy of the listeners before notifying update, so that the original list can be changed Bug: 154879110 Change-Id: If9de06682b189d199a40a9171d7d3cfb23eea062 --- .../android/launcher3/allapps/AllAppsStore.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java index d2dcfd2c37..b11312ca20 100644 --- a/src/com/android/launcher3/allapps/AllAppsStore.java +++ b/src/com/android/launcher3/allapps/AllAppsStore.java @@ -18,7 +18,6 @@ package com.android.launcher3.allapps; import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR; import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY; -import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -32,6 +31,7 @@ import com.android.launcher3.util.PackageUserKey; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; import java.util.function.Predicate; @@ -50,14 +50,12 @@ public class AllAppsStore { private AppInfo[] mApps = EMPTY_ARRAY; - private final List mUpdateListeners = new ArrayList<>(); + private final List mUpdateListeners = new CopyOnWriteArrayList<>(); private final ArrayList mIconContainers = new ArrayList<>(); private int mDeferUpdatesFlags = 0; private boolean mUpdatePending = false; - private boolean mListenerUpdateInProgress = false; - public AppInfo[] getApps() { return mApps; } @@ -102,12 +100,9 @@ public class AllAppsStore { mUpdatePending = true; return; } - mListenerUpdateInProgress = true; - int count = mUpdateListeners.size(); - for (int i = 0; i < count; i++) { - mUpdateListeners.get(i).onAppsUpdated(); + for (OnUpdateListener listener : mUpdateListeners) { + listener.onAppsUpdated(); } - mListenerUpdateInProgress = false; } public void addUpdateListener(OnUpdateListener listener) { @@ -115,9 +110,6 @@ public class AllAppsStore { } public void removeUpdateListener(OnUpdateListener listener) { - if (mListenerUpdateInProgress) { - Log.e("AllAppsStore", "Trying to remove listener during update", new Exception()); - } mUpdateListeners.remove(listener); } From 8f96546e79c79b1f1f26939c5df6f66b72aff2d0 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 23 Apr 2020 19:00:36 -0700 Subject: [PATCH 24/65] Generalizing LauncherState definition so that it can be used in RecentsActivity > Removing 'Launcher' as parameter from state methods called by StateManager > Converting state properties to methods for easier abstraction > Moving state handling drom state definition to activity class Change-Id: I997627df606a7e0bb3bf32688d045a942a47fc94 --- .../uioverrides/QuickstepLauncher.java | 53 +++++++ .../states/BackgroundAppState.java | 11 +- .../states/OverviewModalTaskState.java | 5 +- .../uioverrides/states/OverviewState.java | 25 +--- .../uioverrides/states/QuickSwitchState.java | 27 +--- .../quickstep/LauncherActivityInterface.java | 2 +- .../launcher3/BaseQuickstepLauncher.java | 3 +- .../statehandlers/BackButtonAlphaHandler.java | 4 +- .../uioverrides/states/AllAppsState.java | 17 +-- src/com/android/launcher3/Launcher.java | 46 +++++- src/com/android/launcher3/LauncherState.java | 136 +++++------------- .../launcher3/LauncherStateManager.java | 16 +-- src/com/android/launcher3/Workspace.java | 12 +- .../WorkspaceStateTransitionAnimation.java | 8 +- .../android/launcher3/states/HintState.java | 20 +-- .../launcher3/states/SpringLoadedState.java | 33 +---- .../android/launcher3/views/WorkEduView.java | 15 +- .../uioverrides/states/AllAppsState.java | 18 +-- .../uioverrides/states/OverviewState.java | 5 +- 19 files changed, 198 insertions(+), 258 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index ee642db69c..ceb71669af 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -15,9 +15,16 @@ */ package com.android.launcher3.uioverrides; +import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED; + import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK; +import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent; +import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL; +import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import android.content.Intent; @@ -31,6 +38,8 @@ import com.android.launcher3.BaseQuickstepLauncher; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; +import com.android.launcher3.Workspace; +import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.Folder; @@ -56,6 +65,7 @@ import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.TaskView; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -175,6 +185,49 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } } + @Override + public void onStateSetEnd(LauncherState state) { + super.onStateSetEnd(state); + + switch (state.ordinal) { + case HINT_STATE_ORDINAL: { + Workspace workspace = getWorkspace(); + boolean willMoveScreens = workspace.getNextPage() != Workspace.DEFAULT_PAGE; + getStateManager().goToState(NORMAL, true, + willMoveScreens ? null : getScrimView()::startDragHandleEducationAnim); + if (willMoveScreens) { + workspace.post(workspace::moveToDefaultScreen); + } + break; + } + case OVERVIEW_STATE_ORDINAL: { + DiscoveryBounce.showForOverviewIfNeeded(this); + RecentsView rv = getOverviewPanel(); + sendCustomAccessibilityEvent( + rv.getPageAt(rv.getCurrentPage()), TYPE_VIEW_FOCUSED, null); + break; + } + case QUICK_SWITCH_STATE_ORDINAL: { + RecentsView rv = getOverviewPanel(); + TaskView tasktolaunch = rv.getTaskViewAt(0); + if (tasktolaunch != null) { + tasktolaunch.launchTask(false, success -> { + if (!success) { + getStateManager().goToState(OVERVIEW); + tasktolaunch.notifyTaskLaunchFailed(TAG); + } else { + getStateManager().moveToRestState(); + } + }, MAIN_EXECUTOR.getHandler()); + } else { + getStateManager().goToState(NORMAL); + } + break; + } + + } + } + @Override public TouchController[] createTouchControllers() { Mode mode = SysUINavigationMode.getMode(this); diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index 4718c81305..357e9ecd6f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -17,7 +17,6 @@ package com.android.launcher3.uioverrides.states; import android.content.Context; -import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Launcher; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.userevent.nano.LauncherLogProto; @@ -29,9 +28,8 @@ import com.android.quickstep.views.RecentsView; */ public class BackgroundAppState extends OverviewState { - private static final int STATE_FLAGS = - FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY - | FLAG_DISABLE_INTERACTION; + private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI + | FLAG_WORKSPACE_INACCESSIBLE | FLAG_NON_INTERACTIVE | FLAG_CLOSE_POPUPS; public BackgroundAppState(int id) { this(id, LauncherLogProto.ContainerType.TASKSWITCHER); @@ -41,11 +39,6 @@ public class BackgroundAppState extends OverviewState { super(id, logContainer, STATE_FLAGS); } - @Override - public void onStateEnabled(Launcher launcher) { - AbstractFloatingView.closeAllOpenViews(launcher, false); - } - @Override public float getVerticalProgress(Launcher launcher) { if (launcher.getDeviceProfile().isVerticalBarLayout()) { diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java index 868273a7bc..4e868b0c1b 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java @@ -15,6 +15,7 @@ */ package com.android.launcher3.uioverrides.states; +import android.content.Context; import android.content.res.Resources; import android.graphics.Rect; @@ -30,14 +31,14 @@ import com.android.quickstep.views.RecentsView; public class OverviewModalTaskState extends OverviewState { private static final int STATE_FLAGS = - FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY; + FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_WORKSPACE_INACCESSIBLE; public OverviewModalTaskState(int id) { super(id, ContainerType.OVERVIEW, STATE_FLAGS); } @Override - public int getTransitionDuration(Launcher launcher) { + public int getTransitionDuration(Context launcher) { return 300; } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java index fad9ea5817..6f572819a1 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -37,17 +37,13 @@ import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview; import android.content.Context; import android.graphics.Rect; import android.view.View; -import android.view.accessibility.AccessibilityEvent; import android.view.animation.Interpolator; -import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.Workspace; -import com.android.launcher3.allapps.DiscoveryBounce; -import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; @@ -67,7 +63,8 @@ public class OverviewState extends LauncherState { protected static final Rect sTempRect = new Rect(); private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED - | FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY; + | FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_WORKSPACE_INACCESSIBLE + | FLAG_CLOSE_POPUPS; public OverviewState(int id) { this(id, STATE_FLAGS); @@ -82,9 +79,9 @@ public class OverviewState extends LauncherState { } @Override - public int getTransitionDuration(Launcher launcher) { + public int getTransitionDuration(Context context) { // In no-button mode, overview comes in all the way from the left, so give it more time. - boolean isNoButtonMode = SysUINavigationMode.INSTANCE.get(launcher).getMode() == NO_BUTTON; + boolean isNoButtonMode = SysUINavigationMode.INSTANCE.get(context).getMode() == NO_BUTTON; return isNoButtonMode && ENABLE_OVERVIEW_ACTIONS.get() ? 380 : 250; } @@ -136,20 +133,6 @@ public class OverviewState extends LauncherState { return super.getQsbScaleAndTranslation(launcher); } - @Override - public void onStateEnabled(Launcher launcher) { - AbstractFloatingView.closeAllOpenViews(launcher); - } - - @Override - public void onStateTransitionEnd(Launcher launcher) { - DiscoveryBounce.showForOverviewIfNeeded(launcher); - RecentsView recentsView = launcher.getOverviewPanel(); - AccessibilityManagerCompat.sendCustomAccessibilityEvent( - recentsView.getPageAt(recentsView.getCurrentPage()), - AccessibilityEvent.TYPE_VIEW_FOCUSED, null); - } - @Override public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) { return new PageAlphaProvider(DEACCEL_2) { diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java index 7b4bb0274a..2c7373e206 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java @@ -15,24 +15,16 @@ */ package com.android.launcher3.uioverrides.states; -import android.os.Handler; -import android.os.Looper; - import com.android.launcher3.Launcher; import com.android.launcher3.userevent.nano.LauncherLogProto; -import com.android.quickstep.GestureState; -import com.android.quickstep.views.RecentsView; -import com.android.quickstep.views.TaskView; /** * State to indicate we are about to launch a recent task. Note that this state is only used when * quick switching from launcher; quick switching from an app uses LauncherSwipeHandler. - * @see GestureState.GestureEndTarget#NEW_TASK + * @see com.android.quickstep.GestureState.GestureEndTarget#NEW_TASK */ public class QuickSwitchState extends BackgroundAppState { - private static final String TAG = "QuickSwitchState"; - public QuickSwitchState(int id) { super(id, LauncherLogProto.ContainerType.APP); } @@ -49,21 +41,4 @@ public class QuickSwitchState extends BackgroundAppState { public int getVisibleElements(Launcher launcher) { return NONE; } - - @Override - public void onStateTransitionEnd(Launcher launcher) { - TaskView tasktolaunch = launcher.getOverviewPanel().getTaskViewAt(0); - if (tasktolaunch != null) { - tasktolaunch.launchTask(false, success -> { - if (!success) { - launcher.getStateManager().goToState(OVERVIEW); - tasktolaunch.notifyTaskLaunchFailed(TAG); - } else { - launcher.getStateManager().moveToRestState(); - } - }, new Handler(Looper.getMainLooper())); - } else { - launcher.getStateManager().goToState(NORMAL); - } - } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java index 07fbcd27a8..726322b0c5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java @@ -212,7 +212,7 @@ public final class LauncherActivityInterface implements BaseActivityInterface