diff options
Diffstat (limited to 'quickstep/src')
33 files changed, 441 insertions, 254 deletions
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index 8fb085dd16..6f0f993ed4 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -26,7 +26,6 @@ import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID; import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition; import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; -import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON; import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS; import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; @@ -38,7 +37,6 @@ import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.content.IntentSender; -import android.graphics.Insets; import android.hardware.SensorManager; import android.hardware.devicestate.DeviceStateManager; import android.os.Bundle; @@ -46,7 +44,6 @@ import android.os.CancellationSignal; import android.os.IBinder; import android.view.Display; import android.view.View; -import android.view.WindowInsets; import android.window.SplashScreen; import androidx.annotation.Nullable; @@ -295,8 +292,8 @@ public abstract class BaseQuickstepLauncher extends Launcher { mActionsView = findViewById(R.id.overview_actions_view); RecentsView overviewPanel = (RecentsView) getOverviewPanel(); SplitSelectStateController controller = - new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this), - getStateManager(), getDepthController()); + new SplitSelectStateController(this, mHandler, getStateManager(), + getDepthController()); overviewPanel.init(mActionsView, controller); mActionsView.setDp(getDeviceProfile()); mActionsView.updateVerticalMargin(DisplayController.getNavigationMode(this)); @@ -614,17 +611,4 @@ public abstract class BaseQuickstepLauncher extends Launcher { mDepthController.dump(prefix, writer); } } - - @Override - public void updateWindowInsets(WindowInsets.Builder updatedInsetsBuilder, - WindowInsets oldInsets) { - // Override the tappable insets to be 0 on the bottom for gesture nav (otherwise taskbar - // would count towards it). This is used for the bottom protection in All Apps for example. - if (DisplayController.getNavigationMode(this) == NO_BUTTON) { - Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement()); - Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top, - oldTappableInsets.right, 0); - updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets); - } - } } diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 8644a1238f..e5910df9bd 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -579,8 +579,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } } - // Pause page indicator animations as they lead to layer trashing. - mLauncher.getWorkspace().getPageIndicator().pauseAnimations(); + // Pause expensive view updates as they can lead to layer thrashing and skipped frames. + mLauncher.pauseExpensiveViewUpdates(); endListener = () -> { viewsToAnimate.forEach(view -> { @@ -590,7 +590,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener if (scrimEnabled) { mLauncher.getScrimView().setBackgroundColor(Color.TRANSPARENT); } - mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd(); + mLauncher.resumeExpensiveViewUpdates(); }; } @@ -1186,6 +1186,19 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener return false; } + private boolean hasMultipleTargetsWithMode(RemoteAnimationTargetCompat[] targets, int mode) { + int numTargets = 0; + for (RemoteAnimationTargetCompat target : targets) { + if (target.mode == mode) { + numTargets++; + } + if (numTargets > 1) { + return true; + } + } + return false; + } + /** * @return Runner that plays when user goes to Launcher * ie. pressing home, swiping up from nav bar. @@ -1580,7 +1593,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener View launcherView = findLauncherView(appTargets); boolean playFallBackAnimation = (launcherView == null && launcherIsForceInvisibleOrOpening) - || mLauncher.getWorkspace().isOverlayShown(); + || mLauncher.getWorkspace().isOverlayShown() + || hasMultipleTargetsWithMode(appTargets, MODE_CLOSING); boolean playWorkspaceReveal = true; boolean skipAllAppsScale = false; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index e949b23b57..5387b1ac83 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -49,6 +49,7 @@ import android.view.Gravity; import android.view.RoundedCorner; import android.view.View; import android.view.WindowManager; +import android.view.WindowManagerGlobal; import android.widget.FrameLayout; import android.widget.Toast; @@ -185,8 +186,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { new TaskbarDragLayerController(this, mDragLayer), new TaskbarViewController(this, taskbarView), new TaskbarScrimViewController(this, taskbarScrimView), - new TaskbarUnfoldAnimationController(unfoldTransitionProgressProvider, - mWindowManager), + new TaskbarUnfoldAnimationController(this, unfoldTransitionProgressProvider, + mWindowManager, WindowManagerGlobal.getWindowManagerService()), new TaskbarKeyguardController(this), new StashedHandleViewController(this, stashedHandleView), new TaskbarStashController(this), diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java index 991bcec376..56648eac38 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java @@ -1,5 +1,6 @@ package com.android.launcher3.taskbar; +import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING; @@ -14,6 +15,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import com.android.launcher3.AbstractFloatingView; import com.android.systemui.shared.system.QuickStepContract; import java.io.PrintWriter; @@ -39,6 +41,7 @@ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTas @Override public void onReceive(Context context, Intent intent) { mIsScreenOff = true; + AbstractFloatingView.closeOpenViews(mContext, false, TYPE_ALL); } }; @@ -71,6 +74,10 @@ public class TaskbarKeyguardController implements TaskbarControllers.LoggableTas mNavbarButtonsViewController.setKeyguardVisible(keyguardShowing || dozing, keyguardOccluded); updateIconsForBouncer(); + + if (keyguardShowing) { + AbstractFloatingView.closeOpenViews(mContext, true, TYPE_ALL); + } } public boolean isScreenOff() { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index ebe6a04611..235a156fb5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -29,13 +29,16 @@ import androidx.annotation.NonNull; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseQuickstepLauncher; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherState; +import com.android.launcher3.Utilities; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.util.MultiValueAlpha; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.RecentsAnimationCallbacks; import com.android.quickstep.RecentsAnimationController; import com.android.quickstep.views.RecentsView; +import com.android.systemui.animation.ViewRootSync; import com.android.systemui.shared.recents.model.ThumbnailData; import java.util.HashMap; @@ -76,6 +79,9 @@ import java.util.function.Supplier; private boolean mShouldDelayLauncherStateAnim; + // We skip any view synchronizations during init/destroy. + private boolean mCanSyncViews; + private final StateManager.StateListener<LauncherState> mStateListener = new StateManager.StateListener<LauncherState>() { @@ -102,6 +108,8 @@ import java.util.function.Supplier; }; public void init(TaskbarControllers controllers, BaseQuickstepLauncher launcher) { + mCanSyncViews = false; + mControllers = controllers; mLauncher = launcher; @@ -121,9 +129,13 @@ import java.util.function.Supplier; updateStateForFlag(FLAG_RESUMED, launcher.hasBeenResumed()); mLauncherState = launcher.getStateManager().getState(); applyState(0); + + mCanSyncViews = true; } public void onDestroy() { + mCanSyncViews = false; + mIconAlignmentForResumedState.finishAnimation(); mIconAlignmentForGestureState.finishAnimation(); mIconAlignmentForLauncherState.finishAnimation(); @@ -131,6 +143,8 @@ import java.util.function.Supplier; mIconAlphaForHome.setConsumer(null); mLauncher.getHotseat().setIconsAlpha(1f); mLauncher.getStateManager().removeStateListener(mStateListener); + + mCanSyncViews = true; } public Animator createAnimToLauncher(@NonNull LauncherState toState, @@ -380,6 +394,27 @@ import java.util.function.Supplier; return; } float alignment = alignmentSupplier.get(); + float currentValue = mIconAlphaForHome.getValue(); + boolean taskbarWillBeVisible = alignment < 1; + boolean firstFrameVisChanged = (taskbarWillBeVisible && Float.compare(currentValue, 1) != 0) + || (!taskbarWillBeVisible && Float.compare(currentValue, 0) != 0); + + // Sync the first frame where we swap taskbar and hotseat. + if (firstFrameVisChanged && mCanSyncViews && !Utilities.IS_RUNNING_IN_TEST_HARNESS) { + DeviceProfile dp = mLauncher.getDeviceProfile(); + + // Do all the heavy work before the sync. + mControllers.taskbarViewController.createIconAlignmentControllerIfNotExists(dp); + + ViewRootSync.synchronizeNextDraw(mLauncher.getHotseat(), + mControllers.taskbarActivityContext.getDragLayer(), + () -> updateIconAlignment(alignment)); + } else { + updateIconAlignment(alignment); + } + } + + private void updateIconAlignment(float alignment) { mControllers.taskbarViewController.setLauncherIconAlignment( alignment, mLauncher.getDeviceProfile()); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index cc462c1bf1..5ce4fa7fa3 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -42,6 +42,7 @@ import com.android.launcher3.BaseQuickstepLauncher; import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.statemanager.StatefulActivity; +import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.SettingsCache; @@ -74,8 +75,11 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen private final SimpleBroadcastReceiver mShutdownReceiver; // The source for this provider is set when Launcher is available + // We use 'non-destroyable' version here so the original provider won't be destroyed + // as it is tied to the activity lifecycle, not the taskbar lifecycle. + // It's destruction/creation will be managed by the activity. private final ScopedUnfoldTransitionProgressProvider mUnfoldProgressProvider = - new ScopedUnfoldTransitionProgressProvider(); + new NonDestroyableScopedUnfoldTransitionProgressProvider(); private TaskbarActivityContext mTaskbarActivityContext; private StatefulActivity mActivity; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 6bc4c0a019..473be9ea7e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -250,7 +250,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * Returns whether the taskbar is currently visible and in an app. */ public boolean isInAppAndNotStashed() { - return !mIsStashed && (mState & FLAG_IN_APP) != 0; + return !mIsStashed && isInApp(); + } + + private boolean isInApp() { + return hasAnyFlag(FLAG_IN_APP); } /** @@ -266,8 +270,15 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba return mUnstashedHeight; } boolean isAnimating = mAnimator != null && mAnimator.isStarted(); - return mControllers.stashedHandleViewController.isStashedHandleVisible() || isAnimating - ? mStashedHeight : 0; + if (!mControllers.stashedHandleViewController.isStashedHandleVisible() + && isInApp() + && !isAnimating) { + // We are in a settled state where we're not showing the handle even though taskbar + // is stashed. This can happen for example when home button is disabled (see + // StashedHandleViewController#setIsHomeButtonDisabled()). + return 0; + } + return mStashedHeight; } return mUnstashedHeight; } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUnfoldAnimationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUnfoldAnimationController.java index d5ea570613..64a4fa79df 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUnfoldAnimationController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUnfoldAnimationController.java @@ -15,12 +15,14 @@ */ package com.android.launcher3.taskbar; +import android.view.IWindowManager; import android.view.View; import android.view.WindowManager; import com.android.quickstep.util.LauncherViewsMoveFromCenterTranslationApplier; import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator; import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener; +import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider; import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider; import java.io.PrintWriter; @@ -31,14 +33,18 @@ import java.io.PrintWriter; public class TaskbarUnfoldAnimationController implements TaskbarControllers.LoggableTaskbarController { - private final ScopedUnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider; + private final ScopedUnfoldTransitionProgressProvider mScopedUnfoldTransitionProgressProvider; + private final NaturalRotationUnfoldProgressProvider mNaturalUnfoldTransitionProgressProvider; private final UnfoldMoveFromCenterAnimator mMoveFromCenterAnimator; private final TransitionListener mTransitionListener = new TransitionListener(); private TaskbarViewController mTaskbarViewController; - public TaskbarUnfoldAnimationController(ScopedUnfoldTransitionProgressProvider - unfoldTransitionProgressProvider, WindowManager windowManager) { - mUnfoldTransitionProgressProvider = unfoldTransitionProgressProvider; + public TaskbarUnfoldAnimationController(BaseTaskbarContext context, + ScopedUnfoldTransitionProgressProvider source, + WindowManager windowManager, IWindowManager iWindowManager) { + mScopedUnfoldTransitionProgressProvider = source; + mNaturalUnfoldTransitionProgressProvider = + new NaturalRotationUnfoldProgressProvider(context, iWindowManager, source); mMoveFromCenterAnimator = new UnfoldMoveFromCenterAnimator(windowManager, new LauncherViewsMoveFromCenterTranslationApplier()); } @@ -48,18 +54,21 @@ public class TaskbarUnfoldAnimationController implements * @param taskbarControllers references to all other taskbar controllers */ public void init(TaskbarControllers taskbarControllers) { + mNaturalUnfoldTransitionProgressProvider.init(); mTaskbarViewController = taskbarControllers.taskbarViewController; mTaskbarViewController.addOneTimePreDrawListener(() -> - mUnfoldTransitionProgressProvider.setReadyToHandleTransition(true)); - mUnfoldTransitionProgressProvider.addCallback(mTransitionListener); + mScopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(true)); + mNaturalUnfoldTransitionProgressProvider.addCallback(mTransitionListener); } /** * Destroys the controller */ public void onDestroy() { - mUnfoldTransitionProgressProvider.setReadyToHandleTransition(false); - mUnfoldTransitionProgressProvider.removeCallback(mTransitionListener); + mScopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(false); + mNaturalUnfoldTransitionProgressProvider.removeCallback(mTransitionListener); + mNaturalUnfoldTransitionProgressProvider.destroy(); + mTaskbarViewController = null; } @Override diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 6e34ee03b4..1320060202 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -20,13 +20,14 @@ import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.quickstep.AnimatedFloat.VALUE; +import android.annotation.NonNull; import android.graphics.Rect; import android.util.FloatProperty; import android.util.Log; import android.view.MotionEvent; import android.view.View; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnPreDrawListener; + +import androidx.core.view.OneShotPreDrawListener; import com.android.launcher3.BubbleTextView; import com.android.launcher3.DeviceProfile; @@ -143,18 +144,8 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar * drawing a frame and invoked only once * @param listener callback that will be invoked before drawing the next frame */ - public void addOneTimePreDrawListener(Runnable listener) { - mTaskbarView.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() { - @Override - public boolean onPreDraw() { - final ViewTreeObserver viewTreeObserver = mTaskbarView.getViewTreeObserver(); - if (viewTreeObserver.isAlive()) { - listener.run(); - viewTreeObserver.removeOnPreDrawListener(this); - } - return true; - } - }); + public void addOneTimePreDrawListener(@NonNull Runnable listener) { + OneShotPreDrawListener.add(mTaskbarView, listener); } public Rect getIconLayoutBounds() { @@ -192,15 +183,23 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar } /** + * Creates the icon alignment controller if it does not already exist. + * @param launcherDp Launcher device profile. + */ + public void createIconAlignmentControllerIfNotExists(DeviceProfile launcherDp) { + if (mIconAlignControllerLazy == null) { + mIconAlignControllerLazy = createIconAlignmentController(launcherDp); + } + } + + /** * Sets the taskbar icon alignment relative to Launcher hotseat icons * @param alignmentRatio [0, 1] * 0 => not aligned * 1 => fully aligned */ public void setLauncherIconAlignment(float alignmentRatio, DeviceProfile launcherDp) { - if (mIconAlignControllerLazy == null) { - mIconAlignControllerLazy = createIconAlignmentController(launcherDp); - } + createIconAlignmentControllerIfNotExists(launcherDp); mIconAlignControllerLazy.setPlayFraction(alignmentRatio); if (alignmentRatio <= 0 || alignmentRatio >= 1) { // Cleanup lazy controller so that it is created again in next animation diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java index b36b9f1ffd..37cd753ba4 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java @@ -25,6 +25,9 @@ import android.view.WindowInsets; import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.allapps.AllAppsGridAdapter; +import com.android.launcher3.allapps.AlphabeticalAppsList; +import com.android.launcher3.allapps.BaseAdapterProvider; +import com.android.launcher3.allapps.BaseAllAppsAdapter; import com.android.launcher3.allapps.BaseAllAppsContainerView; import com.android.launcher3.allapps.search.SearchAdapterProvider; @@ -79,4 +82,11 @@ public class TaskbarAllAppsContainerView extends BaseAllAppsContainerView<Taskba setInsets(insets.getInsets(WindowInsets.Type.systemBars()).toRect()); return super.onApplyWindowInsets(insets); } + + @Override + protected BaseAllAppsAdapter getAdapter(AlphabeticalAppsList<TaskbarAllAppsContext> mAppsList, + BaseAdapterProvider[] adapterProviders) { + return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), mAppsList, + adapterProviders); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/unfold/NonDestroyableScopedUnfoldTransitionProgressProvider.java b/quickstep/src/com/android/launcher3/taskbar/unfold/NonDestroyableScopedUnfoldTransitionProgressProvider.java new file mode 100644 index 0000000000..f9da4e4e74 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/unfold/NonDestroyableScopedUnfoldTransitionProgressProvider.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar.unfold; + +import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider; + +/** + * ScopedUnfoldTransitionProgressProvider that doesn't propagate destroy method + */ +public class NonDestroyableScopedUnfoldTransitionProgressProvider extends + ScopedUnfoldTransitionProgressProvider { + + @Override + public void destroy() { + // no-op + } +} diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java index 9240fb86a7..2f8e4d9dde 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java +++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java @@ -20,7 +20,6 @@ import android.app.Person; import android.content.Context; import android.content.pm.ShortcutInfo; import android.content.res.Resources; -import android.view.Display; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -37,20 +36,6 @@ public class ApiWrapper { } /** - * Returns true if the display is an internal displays - */ - public static boolean isInternalDisplay(Display display) { - return display.getType() == Display.TYPE_INTERNAL; - } - - /** - * Returns a unique ID representing the display - */ - public static String getUniqueId(Display display) { - return display.getUniqueId(); - } - - /** * Returns the minimum space that should be left empty at the end of hotseat */ public static int getHotseatEndOffset(Context context) { diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 32ce1c40d7..947d3e26da 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -118,8 +118,8 @@ public final class RecentsViewStateController extends if (isSplitSelectionState(currentState, toState)) { // Animation to "dismiss" selected taskView - PendingAnimation splitSelectInitAnimation = - mRecentsView.createSplitSelectInitAnimation(); + PendingAnimation splitSelectInitAnimation = mRecentsView.createSplitSelectInitAnimation( + toState.getTransitionDuration(mLauncher)); // Add properties to shift remaining taskViews to get out of placeholder view splitSelectInitAnimation.setFloat(mRecentsView, taskViewsFloat.first, toState.getSplitSelectTranslation(mLauncher), LINEAR); diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java index e5c7b0e46b..895cf89382 100644 --- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java +++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java @@ -35,11 +35,11 @@ import com.android.launcher3.R; import com.android.launcher3.ResourceUtils; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.DisplayController.NavigationMode; +import com.android.launcher3.util.window.CachedDisplayInfo; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; -import java.util.Objects; /** * Maintains state for supporting nav bars and tracking their gestures in multiple orientations. @@ -51,55 +51,17 @@ import java.util.Objects; */ class OrientationTouchTransformer { - private static class CurrentDisplay { - public Point size; - public int rotation; - - CurrentDisplay() { - this.size = new Point(0, 0); - this.rotation = 0; - } - - CurrentDisplay(Point size, int rotation) { - this.size = size; - this.rotation = rotation; - } - - @Override - public String toString() { - return "CurrentDisplay:" - + " rotation: " + rotation - + " size: " + size; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CurrentDisplay display = (CurrentDisplay) o; - if (rotation != display.rotation) return false; - - return Objects.equals(size, display.size); - } - - @Override - public int hashCode() { - return Objects.hash(size, rotation); - } - }; - private static final String TAG = "OrientationTouchTransformer"; private static final boolean DEBUG = false; private static final int QUICKSTEP_ROTATION_UNINITIALIZED = -1; - private final Map<CurrentDisplay, OrientationRectF> mSwipeTouchRegions = - new HashMap<CurrentDisplay, OrientationRectF>(); + private final Map<CachedDisplayInfo, OrientationRectF> mSwipeTouchRegions = + new HashMap<CachedDisplayInfo, OrientationRectF>(); private final RectF mAssistantLeftRegion = new RectF(); private final RectF mAssistantRightRegion = new RectF(); private final RectF mOneHandedModeRegion = new RectF(); - private CurrentDisplay mCurrentDisplay = new CurrentDisplay(); + private CachedDisplayInfo mCachedDisplayInfo = new CachedDisplayInfo(); private int mNavBarGesturalHeight; private final int mNavBarLargerGesturalHeight; private boolean mEnableMultipleRegions; @@ -184,22 +146,22 @@ class OrientationTouchTransformer { * @see #enableMultipleRegions(boolean, Info) */ void createOrAddTouchRegion(Info info) { - mCurrentDisplay = new CurrentDisplay(info.currentSize, info.rotation); + mCachedDisplayInfo = new CachedDisplayInfo(info.currentSize, info.rotation); if (mQuickStepStartingRotation > QUICKSTEP_ROTATION_UNINITIALIZED - && mCurrentDisplay.rotation == mQuickStepStartingRotation) { + && mCachedDisplayInfo.rotation == 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 resetSwipeRegions(info); return; } - OrientationRectF region = mSwipeTouchRegions.get(mCurrentDisplay); + OrientationRectF region = mSwipeTouchRegions.get(mCachedDisplayInfo); if (region != null) { return; } if (mEnableMultipleRegions) { - mSwipeTouchRegions.put(mCurrentDisplay, createRegionForDisplay(info)); + mSwipeTouchRegions.put(mCachedDisplayInfo, createRegionForDisplay(info)); } else { resetSwipeRegions(info); } @@ -245,31 +207,31 @@ class OrientationTouchTransformer { */ private void resetSwipeRegions(Info region) { if (DEBUG) { - Log.d(TAG, "clearing all regions except rotation: " + mCurrentDisplay.rotation); + Log.d(TAG, "clearing all regions except rotation: " + mCachedDisplayInfo.rotation); } - mCurrentDisplay = new CurrentDisplay(region.currentSize, region.rotation); - OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCurrentDisplay); + mCachedDisplayInfo = new CachedDisplayInfo(region.currentSize, region.rotation); + OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCachedDisplayInfo); if (regionToKeep == null) { regionToKeep = createRegionForDisplay(region); } mSwipeTouchRegions.clear(); - mSwipeTouchRegions.put(mCurrentDisplay, regionToKeep); + mSwipeTouchRegions.put(mCachedDisplayInfo, regionToKeep); updateAssistantRegions(regionToKeep); } private void resetSwipeRegions() { - OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCurrentDisplay); + OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCachedDisplayInfo); mSwipeTouchRegions.clear(); if (regionToKeep != null) { - mSwipeTouchRegions.put(mCurrentDisplay, regionToKeep); + mSwipeTouchRegions.put(mCachedDisplayInfo, regionToKeep); updateAssistantRegions(regionToKeep); } } private OrientationRectF createRegionForDisplay(Info display) { if (DEBUG) { - Log.d(TAG, "creating rotation region for: " + mCurrentDisplay.rotation + Log.d(TAG, "creating rotation region for: " + mCachedDisplayInfo.rotation + " with mode: " + mMode + " displayRotation: " + display.rotation); } @@ -368,7 +330,7 @@ class OrientationTouchTransformer { true); } } else { - mLastRectTouched.applyTransformFromRotation(event, mCurrentDisplay.rotation, + mLastRectTouched.applyTransformFromRotation(event, mCachedDisplayInfo.rotation, true); } break; @@ -387,7 +349,7 @@ class OrientationTouchTransformer { true); } } else { - mLastRectTouched.applyTransformFromRotation(event, mCurrentDisplay.rotation, + mLastRectTouched.applyTransformFromRotation(event, mCachedDisplayInfo.rotation, true); } mLastRectTouched = null; @@ -403,11 +365,12 @@ class OrientationTouchTransformer { if (rect == null) { continue; } - if (rect.applyTransformFromRotation(event, mCurrentDisplay.rotation, false)) { + if (rect.applyTransformFromRotation( + event, mCachedDisplayInfo.rotation, false)) { mLastRectTouched = rect; mActiveTouchRotation = rect.getRotation(); if (mEnableMultipleRegions - && mCurrentDisplay.rotation == mActiveTouchRotation) { + && mCachedDisplayInfo.rotation == mActiveTouchRotation) { // TODO(b/154580671) might make this block unnecessary // Start a touch session for the default nav region for the display mQuickStepStartingRotation = mLastRectTouched.getRotation(); @@ -430,7 +393,7 @@ class OrientationTouchTransformer { pw.println(" lastTouchedRegion=" + mLastRectTouched); pw.println(" multipleRegionsEnabled=" + mEnableMultipleRegions); StringBuilder regions = new StringBuilder(" currentTouchableRotations="); - for (CurrentDisplay key: mSwipeTouchRegions.keySet()) { + for (CachedDisplayInfo key: mSwipeTouchRegions.keySet()) { OrientationRectF rectF = mSwipeTouchRegions.get(key); regions.append(rectF).append(" "); } diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java index db92e339cd..3e7ad62233 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -135,8 +135,8 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> { SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f); SplitSelectStateController controller = - new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this), - getStateManager(), null /*depthController*/); + new SplitSelectStateController(this, mHandler, getStateManager(), + null /* depthController */); mDragLayer.recreateControllers(); mFallbackRecentsView.init(mActionsView, controller); diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index 783c868a19..57b42f8246 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -49,9 +49,9 @@ import java.util.HashMap; public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener { public static final boolean ENABLE_SHELL_TRANSITIONS = - SystemProperties.getBoolean("persist.debug.shell_transit", false); + SystemProperties.getBoolean("persist.wm.debug.shell_transit", false); public static final boolean SHELL_TRANSITIONS_ROTATION = ENABLE_SHELL_TRANSITIONS - && SystemProperties.getBoolean("persist.debug.shell_transit_rotate", false); + && SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false); private RecentsAnimationController mController; private RecentsAnimationCallbacks mCallbacks; diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java index ff175f18f2..5094d49200 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -111,7 +111,8 @@ public class FallbackRecentsStateController implements StateHandler<RecentsState RecentsState currentState = mActivity.getStateManager().getState(); if (isSplitSelectionState(state) && !isSplitSelectionState(currentState)) { - setter.add(mRecentsView.createSplitSelectInitAnimation().buildAnim()); + setter.add(mRecentsView.createSplitSelectInitAnimation( + state.getTransitionDuration(mActivity)).buildAnim()); } Pair<FloatProperty, FloatProperty> taskViewsFloat = diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java index dbe260ac65..7836ecef14 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java @@ -22,6 +22,7 @@ import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; +import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.taskbar.TaskbarActivityContext; import com.android.quickstep.InputConsumer; @@ -36,14 +37,20 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { private final GestureDetector mLongPressDetector; private final float mSquaredTouchSlop; + private float mDownX, mDownY; private boolean mCanceledUnstashHint; + private final float mUnstashArea; + private final float mScreenWidth; public TaskbarStashInputConsumer(Context context, InputConsumer delegate, InputMonitorCompat inputMonitor, TaskbarActivityContext taskbarActivityContext) { super(delegate, inputMonitor); mTaskbarActivityContext = taskbarActivityContext; mSquaredTouchSlop = Utilities.squaredTouchSlop(context); + mScreenWidth = context.getResources().getDisplayMetrics().widthPixels; + mUnstashArea = context.getResources() + .getDimensionPixelSize(R.dimen.taskbar_unstash_input_area); mLongPressDetector = new GestureDetector(context, new SimpleOnGestureListener() { @Override @@ -69,11 +76,13 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { final float y = ev.getRawY(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: - mDownX = x; - mDownY = y; - mTaskbarActivityContext.startTaskbarUnstashHint( - /* animateForward = */ true); - mCanceledUnstashHint = false; + if (isInArea(x)) { + mDownX = x; + mDownY = y; + mTaskbarActivityContext.startTaskbarUnstashHint( + /* animateForward = */ true); + mCanceledUnstashHint = false; + } break; case MotionEvent.ACTION_MOVE: if (!mCanceledUnstashHint @@ -95,10 +104,18 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { } } + private boolean isInArea(float x) { + float areaFromMiddle = mUnstashArea / 2.0f; + float distFromMiddle = Math.abs(mScreenWidth / 2.0f - x); + return distFromMiddle < areaFromMiddle; + } + private void onLongPressDetected(MotionEvent motionEvent) { - if (mTaskbarActivityContext != null - && mTaskbarActivityContext.onLongPressToUnstashTaskbar()) { - setActive(motionEvent); + if (mTaskbarActivityContext != null && isInArea(motionEvent.getRawX())) { + boolean taskBarPressed = mTaskbarActivityContext.onLongPressToUnstashTaskbar(); + if (taskBarPressed) { + setActive(motionEvent); + } } } } diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java index 1c3e784308..5ef9a9b697 100644 --- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java @@ -52,6 +52,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; import androidx.core.graphics.ColorUtils; +import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.quickstep.AnimatedFloat; @@ -110,6 +111,12 @@ public class AllSetActivity extends Activity { mContentView = findViewById(R.id.content_view); mSwipeUpShift = getResources().getDimension(R.dimen.allset_swipe_up_shift); + boolean isTablet = InvariantDeviceProfile.INSTANCE.get(getApplicationContext()) + .getDeviceProfile(this).isTablet; + TextView subtitle = findViewById(R.id.subtitle); + subtitle.setText(isTablet + ? R.string.allset_description_tablet : R.string.allset_description); + TextView tv = findViewById(R.id.navigation_settings); tv.setTextColor(accentColor); tv.setOnClickListener(v -> { diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java index 49d820387c..b68650524e 100644 --- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java @@ -57,14 +57,14 @@ final class BackGestureTutorialController extends TutorialController { @LayoutRes int getMockAppTaskCurrentPageLayoutResId() { return mTutorialFragment.isLargeScreen() - ? R.layout.gesture_tutorial_foldable_mock_conversation + ? R.layout.gesture_tutorial_tablet_mock_conversation : R.layout.gesture_tutorial_mock_conversation; } @LayoutRes int getMockAppTaskPreviousPageLayoutResId() { return mTutorialFragment.isLargeScreen() - ? R.layout.gesture_tutorial_foldable_mock_conversation_list + ? R.layout.gesture_tutorial_tablet_mock_conversation_list : R.layout.gesture_tutorial_mock_conversation_list; } diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java index 0bc3691d44..6254313f74 100644 --- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java @@ -51,7 +51,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll @Override protected int getMockAppTaskLayoutResId() { return mTutorialFragment.isLargeScreen() - ? R.layout.gesture_tutorial_foldable_mock_webpage + ? R.layout.gesture_tutorial_tablet_mock_webpage : R.layout.gesture_tutorial_mock_webpage; } diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java index f308f27d4d..09640c675b 100644 --- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java @@ -61,7 +61,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont @Override protected int getMockAppTaskLayoutResId() { return mTutorialFragment.isLargeScreen() - ? R.layout.gesture_tutorial_foldable_mock_conversation_list + ? R.layout.gesture_tutorial_tablet_mock_conversation_list : R.layout.gesture_tutorial_mock_conversation_list; } diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java index 9a101b9651..b70c411196 100644 --- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java @@ -280,6 +280,15 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { super(context, deviceState, gestureState); mRemoteTargetHandles[0] = new RemoteTargetGluer.RemoteTargetHandle( mRemoteTargetHandles[0].getTaskViewSimulator(), new FakeTransformParams()); + + for (RemoteTargetGluer.RemoteTargetHandle handle + : mTargetGluer.getRemoteTargetHandles()) { + // Override home screen rotation preference so that home and overview animations + // work properly + handle.getTaskViewSimulator() + .getOrientationState() + .ignoreAllowHomeRotationPreference(); + } } void initDp(DeviceProfile dp) { @@ -336,8 +345,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { 1f - SHAPE_PROGRESS_DURATION /* shapeProgressStart */, radius, 255, false, /* isOpening */ - mFakeIconView, mDp, - false /* isVerticalBarLayout */); + mFakeIconView, mDp); mFakeIconView.setAlpha(1); mFakeTaskView.setAlpha(getWindowAlpha(progress)); mFakePreviousTaskView.setAlpha(getWindowAlpha(progress)); diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java index 4145393262..2ddbd970e3 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java @@ -49,6 +49,7 @@ import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.content.res.AppCompatResources; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; @@ -73,7 +74,7 @@ abstract class TutorialController implements BackGestureAttemptCallback, private static final int FEEDBACK_ANIMATION_MS = 133; private static final int RIPPLE_VISIBLE_MS = 300; private static final int GESTURE_ANIMATION_DELAY_MS = 1500; - private static final int ADVANCE_TUTORIAL_TIMEOUT_MS = 4000; + private static final int ADVANCE_TUTORIAL_TIMEOUT_MS = 2000; private static final long GESTURE_ANIMATION_PAUSE_DURATION_MILLIS = 1000; final TutorialFragment mTutorialFragment; @@ -185,7 +186,9 @@ abstract class TutorialController implements BackGestureAttemptCallback, @LayoutRes protected int getMockHotseatResId() { return mTutorialFragment.isLargeScreen() - ? R.layout.gesture_tutorial_foldable_mock_hotseat + ? (mTutorialFragment.isFoldable() + ? R.layout.gesture_tutorial_foldable_mock_hotseat + : R.layout.gesture_tutorial_tablet_mock_hotseat) : R.layout.gesture_tutorial_mock_hotseat; } @@ -319,6 +322,9 @@ abstract class TutorialController implements BackGestureAttemptCallback, } void hideFeedback() { + if (mFeedbackView.getVisibility() != View.VISIBLE) { + return; + } cancelQueuedGestureAnimation(); mFeedbackView.clearAnimation(); mFeedbackView.setVisibility(View.INVISIBLE); @@ -515,20 +521,45 @@ abstract class TutorialController implements BackGestureAttemptCallback, } private void updateLayout() { - if (mContext != null) { - RelativeLayout.LayoutParams feedbackLayoutParams = - (RelativeLayout.LayoutParams) mFeedbackView.getLayoutParams(); - feedbackLayoutParams.setMarginStart(mContext.getResources().getDimensionPixelSize( - mTutorialFragment.isLargeScreen() - ? R.dimen.gesture_tutorial_foldable_feedback_margin_start_end - : R.dimen.gesture_tutorial_feedback_margin_start_end)); - feedbackLayoutParams.setMarginEnd(mContext.getResources().getDimensionPixelSize( - mTutorialFragment.isLargeScreen() - ? R.dimen.gesture_tutorial_foldable_feedback_margin_start_end - : R.dimen.gesture_tutorial_feedback_margin_start_end)); - - mFakeTaskbarView.setVisibility(mTutorialFragment.isLargeScreen() ? View.VISIBLE : GONE); + if (mContext == null) { + return; + } + RelativeLayout.LayoutParams feedbackLayoutParams = + (RelativeLayout.LayoutParams) mFeedbackView.getLayoutParams(); + feedbackLayoutParams.setMarginStart(mContext.getResources().getDimensionPixelSize( + mTutorialFragment.isLargeScreen() + ? R.dimen.gesture_tutorial_tablet_feedback_margin_start_end + : R.dimen.gesture_tutorial_feedback_margin_start_end)); + feedbackLayoutParams.setMarginEnd(mContext.getResources().getDimensionPixelSize( + mTutorialFragment.isLargeScreen() + ? R.dimen.gesture_tutorial_tablet_feedback_margin_start_end + : R.dimen.gesture_tutorial_feedback_margin_start_end)); + feedbackLayoutParams.topMargin = mContext.getResources().getDimensionPixelSize( + mTutorialFragment.isLargeScreen() + ? R.dimen.gesture_tutorial_tablet_feedback_margin_top + : R.dimen.gesture_tutorial_feedback_margin_top); + + mFakeTaskbarView.setVisibility(mTutorialFragment.isLargeScreen() ? View.VISIBLE : GONE); + + RelativeLayout.LayoutParams hotseatLayoutParams = + (RelativeLayout.LayoutParams) mFakeHotseatView.getLayoutParams(); + if (!mTutorialFragment.isLargeScreen()) { + DeviceProfile dp = mTutorialFragment.getDeviceProfile(); + dp.updateIsSeascape(mContext); + + hotseatLayoutParams.addRule(dp.isLandscape + ? (dp.isSeascape() + ? RelativeLayout.ALIGN_PARENT_START + : RelativeLayout.ALIGN_PARENT_END) + : RelativeLayout.ALIGN_PARENT_BOTTOM); + } else { + hotseatLayoutParams.width = RelativeLayout.LayoutParams.MATCH_PARENT; + hotseatLayoutParams.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + hotseatLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + hotseatLayoutParams.removeRule(RelativeLayout.ALIGN_PARENT_START); + hotseatLayoutParams.removeRule(RelativeLayout.ALIGN_PARENT_END); } + mFakeHotseatView.setLayoutParams(hotseatLayoutParams); } private AlertDialog createSkipTutorialDialog() { diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java index 2fd7cde3a0..4b836e380e 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java @@ -20,7 +20,6 @@ import android.animation.AnimatorListenerAdapter; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.content.pm.ActivityInfo; import android.graphics.Insets; import android.graphics.drawable.Animatable2; import android.graphics.drawable.AnimatedVectorDrawable; @@ -41,6 +40,7 @@ import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.quickstep.interaction.TutorialController.TutorialType; @@ -67,7 +67,9 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener { private boolean mFragmentStopped = false; + private DeviceProfile mDeviceProfile; private boolean mIsLargeScreen; + private boolean mIsFoldable; public static TutorialFragment newInstance(TutorialType tutorialType, boolean gestureComplete) { TutorialFragment fragment = getFragmentForTutorialType(tutorialType); @@ -139,22 +141,24 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener { mEdgeBackGestureHandler = new EdgeBackGestureHandler(getContext()); mNavBarGestureHandler = new NavBarGestureHandler(getContext()); - mIsLargeScreen = InvariantDeviceProfile.INSTANCE.get(getContext()) - .getDeviceProfile(getContext()).isTablet; - - if (mIsLargeScreen) { - ((Activity) getContext()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER); - } else { - // Temporary until UI mocks for landscape mode for phones are created. - ((Activity) getContext()).setRequestedOrientation( - ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } + mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(getContext()) + .getDeviceProfile(getContext()); + mIsLargeScreen = mDeviceProfile.isTablet; + mIsFoldable = mDeviceProfile.isTwoPanels; } public boolean isLargeScreen() { return mIsLargeScreen; } + public boolean isFoldable() { + return mIsFoldable; + } + + DeviceProfile getDeviceProfile() { + return mDeviceProfile; + } + @Override public void onDestroy() { super.onDestroy(); @@ -296,6 +300,9 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener { @Override public boolean onTouch(View view, MotionEvent motionEvent) { + if (mTutorialController != null) { + mTutorialController.hideFeedback(); + } // Note: Using logical-or to ensure both functions get called. return mEdgeBackGestureHandler.onTouch(view, motionEvent) | mNavBarGestureHandler.onTouch(view, motionEvent); diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java b/quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java index d880d74e5d..ae0e725aad 100644 --- a/quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java +++ b/quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java @@ -23,7 +23,6 @@ import android.widget.ImageView; import android.widget.LinearLayout; import androidx.appcompat.content.res.AppCompatResources; -import androidx.core.graphics.ColorUtils; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -87,8 +86,10 @@ public class TutorialStepIndicator extends LinearLayout { for (int i = mTotalSteps; i < getChildCount(); i++) { removeViewAt(i); } - int stepIndicatorColor = GraphicsUtils.getAttrColor( + int activeStepIndicatorColor = GraphicsUtils.getAttrColor( getContext(), android.R.attr.textColorPrimary); + int inactiveStepIndicatorColor = GraphicsUtils.getAttrColor( + getContext(), android.R.attr.textColorSecondaryInverse); for (int i = 0; i < mTotalSteps; i++) { Drawable pageIndicatorPillDrawable = AppCompatResources.getDrawable( getContext(), R.drawable.tutorial_step_indicator_pill); @@ -107,10 +108,9 @@ public class TutorialStepIndicator extends LinearLayout { } if (pageIndicatorPillDrawable != null) { if (i < mCurrentStep) { - pageIndicatorPillDrawable.setTint(stepIndicatorColor); + pageIndicatorPillDrawable.setTint(activeStepIndicatorColor); } else { - pageIndicatorPillDrawable.setTint( - ColorUtils.setAlphaComponent(stepIndicatorColor, 0x22)); + pageIndicatorPillDrawable.setTint(inactiveStepIndicatorColor); } } } diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java index d85515aef0..f6002ec10a 100644 --- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java +++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java @@ -19,6 +19,7 @@ package com.android.quickstep.logging; import static androidx.core.util.Preconditions.checkNotNull; import static androidx.core.util.Preconditions.checkState; +import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE; import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.EXTENDED_CONTAINERS; import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.FOLDER; import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.SEARCH_RESULT_CONTAINER; @@ -82,6 +83,7 @@ import java.util.concurrent.CopyOnWriteArrayList; public class StatsLogCompatManager extends StatsLogManager { private static final String TAG = "StatsLog"; + private static final String LATENCY_TAG = "StatsLatencyLog"; private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.STATSLOG); private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0); // LauncherAtom.ItemInfo.getDefaultInstance() should be used but until launcher proto migrates @@ -196,7 +198,9 @@ public class StatsLogCompatManager extends StatsLogManager { private static class StatsCompatLogger implements StatsLogger { private static final ItemInfo DEFAULT_ITEM_INFO = new ItemInfo(); - + static { + DEFAULT_ITEM_INFO.itemType = ITEM_TYPE_NON_ACTIONABLE; + } private final Context mContext; private final Optional<ActivityContext> mActivityContext; private ItemInfo mItemInfo = DEFAULT_ITEM_INFO; @@ -388,13 +392,21 @@ public class StatsLogCompatManager extends StatsLogManager { if (IS_VERBOSE) { String name = (event instanceof Enum) ? ((Enum) event).name() : event.getId() + ""; - - Log.d(TAG, instanceId == DEFAULT_INSTANCE_ID - ? String.format("\n%s (State:%s->%s)\n%s", name, getStateString(srcState), - getStateString(dstState), atomInfo) - : String.format("\n%s (State:%s->%s) (InstanceId:%s)\n%s", name, - getStateString(srcState), getStateString(dstState), instanceId, - atomInfo)); + StringBuilder logStringBuilder = new StringBuilder("\n"); + if (instanceId != DEFAULT_INSTANCE_ID) { + logStringBuilder.append(String.format("InstanceId:%s ", instanceId)); + } + logStringBuilder.append(name); + if (srcState != LAUNCHER_STATE_UNSPECIFIED + || dstState != LAUNCHER_STATE_UNSPECIFIED) { + logStringBuilder.append( + String.format("(State:%s->%s)", getStateString(srcState), + getStateString(dstState))); + } + if (mItemInfo != DEFAULT_ITEM_INFO) { + logStringBuilder.append("\n").append(atomInfo); + } + Log.d(TAG, logStringBuilder.toString()); } for (StatsLogConsumer consumer : LOGS_CONSUMER) { @@ -479,11 +491,12 @@ public class StatsLogCompatManager extends StatsLogManager { if (IS_VERBOSE) { String name = (event instanceof Enum) ? ((Enum) event).name() : event.getId() + ""; - - Log.d(TAG, mInstanceId == DEFAULT_INSTANCE_ID - ? String.format("\n%s = %dms\n", name, mLatencyInMillis) - : String.format("\n%s = %dms (InstanceId:%s)\n", name, - mLatencyInMillis, mInstanceId)); + StringBuilder logStringBuilder = new StringBuilder("\n"); + if (mInstanceId != DEFAULT_INSTANCE_ID) { + logStringBuilder.append(String.format("InstanceId:%s ", mInstanceId)); + } + logStringBuilder.append(String.format("%s=%sms", name, mLatencyInMillis)); + Log.d(LATENCY_TAG, logStringBuilder.toString()); } SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_LATENCY, diff --git a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java index 51a9915523..63d5b0dd50 100644 --- a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java +++ b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java @@ -48,10 +48,10 @@ import androidx.annotation.WorkerThread; import androidx.core.content.FileProvider; import com.android.internal.app.ChooserActivity; +import com.android.internal.util.ScreenshotHelper; import com.android.launcher3.BuildConfig; import com.android.quickstep.SystemUiProxy; import com.android.systemui.shared.recents.model.Task; -import com.android.systemui.shared.recents.utilities.BitmapUtil; import java.io.File; import java.io.FileOutputStream; @@ -77,7 +77,8 @@ public class ImageActionUtils { public static void saveScreenshot(SystemUiProxy systemUiProxy, Bitmap screenshot, Rect screenshotBounds, Insets visibleInsets, Task.TaskKey task) { - systemUiProxy.handleImageBundleAsScreenshot(BitmapUtil.hardwareBitmapToBundle(screenshot), + systemUiProxy.handleImageBundleAsScreenshot( + ScreenshotHelper.HardwareBitmapBundler.hardwareBitmapToBundle(screenshot), screenshotBounds, visibleInsets, task); } diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index 4f5c368f31..1631be037d 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -102,6 +102,8 @@ public class RecentsOrientedState implements // Whether the swipe gesture is running, so the recents would stay locked in the // current orientation private static final int FLAG_SWIPE_UP_NOT_RUNNING = 1 << 8; + // Ignore shared prefs for home rotation rotation, allowing it in if the activity supports it + private static final int FLAG_IGNORE_ALLOW_HOME_ROTATION_PREF = 1 << 9; private static final int MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE = FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY @@ -371,12 +373,17 @@ public class RecentsOrientedState implements == MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE; } + public void ignoreAllowHomeRotationPreference() { + setFlag(FLAG_IGNORE_ALLOW_HOME_ROTATION_PREF, true); + } + public boolean isRecentsActivityRotationAllowed() { // Activity rotation is allowed if the multi-simulated-rotation is not supported // (fallback recents or tablets) or activity rotation is enabled by various settings. return ((mFlags & MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE) != MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE) - || (mFlags & (FLAG_HOME_ROTATION_ALLOWED_IN_PREFS + || (mFlags & (FLAG_IGNORE_ALLOW_HOME_ROTATION_PREF + | FLAG_HOME_ROTATION_ALLOWED_IN_PREFS | FLAG_MULTIWINDOW_ROTATION_ALLOWED | FLAG_HOME_ROTATION_FORCE_ENABLED_FOR_TESTING)) != 0; } @@ -599,7 +606,7 @@ public class RecentsOrientedState implements width = Math.min(currentSize.x, currentSize.y); height = Math.max(currentSize.x, currentSize.y); } - return idp.getBestMatch(width, height); + return idp.getBestMatch(width, height, mRecentsActivityRotation); } private static String nameAndAddress(Object obj) { diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index fff55a11c0..21e3ea0f2c 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -17,6 +17,7 @@ package com.android.quickstep.util; import static android.app.ActivityTaskManager.INVALID_TASK_ID; +import static android.app.PendingIntent.FLAG_MUTABLE; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; @@ -27,9 +28,11 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO import android.app.ActivityOptions; import android.app.ActivityThread; import android.app.PendingIntent; +import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.IBinder; +import android.text.TextUtils; import android.view.RemoteAnimationAdapter; import android.view.SurfaceControl; import android.window.TransitionInfo; @@ -45,6 +48,7 @@ import com.android.quickstep.TaskAnimationManager; import com.android.quickstep.TaskViewUtils; import com.android.quickstep.views.GroupedTaskView; import com.android.quickstep.views.TaskView; +import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -59,12 +63,13 @@ import java.util.function.Consumer; */ public class SplitSelectStateController { + private final Context mContext; private final Handler mHandler; private final SystemUiProxy mSystemUiProxy; private final StateManager mStateManager; private final DepthController mDepthController; private @StagePosition int mStagePosition; - private PendingIntent mInitialTaskPendingIntent; + private Intent mInitialTaskIntent; private int mInitialTaskId = INVALID_TASK_ID; private int mSecondTaskId = INVALID_TASK_ID; private boolean mRecentsAnimationRunning; @@ -72,10 +77,11 @@ public class SplitSelectStateController { @Nullable private GroupedTaskView mLaunchingTaskView; - public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy, - StateManager stateManager, DepthController depthController) { + public SplitSelectStateController(Context context, Handler handler, StateManager stateManager, + DepthController depthController) { + mContext = context; mHandler = handler; - mSystemUiProxy = systemUiProxy; + mSystemUiProxy = SystemUiProxy.INSTANCE.get(mContext); mStateManager = stateManager; mDepthController = depthController; } @@ -86,12 +92,11 @@ public class SplitSelectStateController { public void setInitialTaskSelect(int taskId, @StagePosition int stagePosition) { mInitialTaskId = taskId; mStagePosition = stagePosition; - mInitialTaskPendingIntent = null; + mInitialTaskIntent = null; } - public void setInitialTaskSelect(PendingIntent pendingIntent, - @StagePosition int stagePosition) { - mInitialTaskPendingIntent = pendingIntent; + public void setInitialTaskSelect(Intent intent, @StagePosition int stagePosition) { + mInitialTaskIntent = intent; mStagePosition = stagePosition; mInitialTaskId = INVALID_TASK_ID; } @@ -99,9 +104,22 @@ public class SplitSelectStateController { /** * To be called after second task selected */ - public void setSecondTaskId(int taskId, Consumer<Boolean> callback) { - mSecondTaskId = taskId; - launchTasks(mInitialTaskId, mInitialTaskPendingIntent, mSecondTaskId, mStagePosition, + public void setSecondTask(Task task, Consumer<Boolean> callback) { + mSecondTaskId = task.key.id; + final Intent fillInIntent; + if (mInitialTaskIntent != null) { + fillInIntent = new Intent(); + if (TextUtils.equals(mInitialTaskIntent.getComponent().getPackageName(), + task.topActivity.getPackageName())) { + fillInIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); + } + } else { + fillInIntent = null; + } + final PendingIntent pendingIntent = + mInitialTaskIntent == null ? null : PendingIntent.getActivity(mContext, 0, + mInitialTaskIntent, FLAG_MUTABLE); + launchTasks(mInitialTaskId, pendingIntent, fillInIntent, mSecondTaskId, mStagePosition, callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO); } @@ -113,18 +131,32 @@ public class SplitSelectStateController { mLaunchingTaskView = groupedTaskView; TaskView.TaskIdAttributeContainer[] taskIdAttributeContainers = groupedTaskView.getTaskIdAttributeContainers(); - launchTasks(taskIdAttributeContainers[0].getTask().key.id, null, + launchTasks(taskIdAttributeContainers[0].getTask().key.id, taskIdAttributeContainers[1].getTask().key.id, taskIdAttributeContainers[0].getStagePosition(), callback, freezeTaskList, groupedTaskView.getSplitRatio()); } /** + * To be called when we want to launch split pairs from Overview when split is initiated from + * Overview. + */ + public void launchTasks(int taskId1, int taskId2, @StagePosition int stagePosition, + Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio) { + launchTasks(taskId1, null /* taskPendingIntent */, null /* fillInIntent */, taskId2, + stagePosition, callback, freezeTaskList, splitRatio); + } + + /** + * To be called when we want to launch split pairs from Overview. Split can be initiated from + * either Overview or home, or all apps. Either both taskIds are set, or a pending intent + a + * fill in intent with a taskId2 are set. + * @param taskPendingIntent is null when split is initiated from Overview * @param stagePosition representing location of task1 */ public void launchTasks(int taskId1, @Nullable PendingIntent taskPendingIntent, - int taskId2, @StagePosition int stagePosition, Consumer<Boolean> callback, - boolean freezeTaskList, float splitRatio) { + @Nullable Intent fillInIntent, int taskId2, @StagePosition int stagePosition, + Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio) { // Assume initial task is for top/left part of screen final int[] taskIds = stagePosition == STAGE_POSITION_TOP_OR_LEFT ? new int[]{taskId1, taskId2} @@ -156,7 +188,7 @@ public class SplitSelectStateController { splitRatio, adapter); } else { mSystemUiProxy.startIntentAndTaskWithLegacyTransition(taskPendingIntent, - new Intent(), taskId2, mainOpts.toBundle(), null /* sideOptions */, + fillInIntent, taskId2, mainOpts.toBundle(), null /* sideOptions */, stagePosition, splitRatio, adapter); } } @@ -250,7 +282,7 @@ public class SplitSelectStateController { */ public void resetState() { mInitialTaskId = INVALID_TASK_ID; - mInitialTaskPendingIntent = null; + mInitialTaskIntent = null; mSecondTaskId = INVALID_TASK_ID; mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED; mRecentsAnimationRunning = false; @@ -262,7 +294,7 @@ public class SplitSelectStateController { * chosen */ public boolean isSplitSelectActive() { - return (mInitialTaskId != INVALID_TASK_ID || mInitialTaskPendingIntent != null) + return (mInitialTaskId != INVALID_TASK_ID || mInitialTaskIntent != null) && mSecondTaskId == INVALID_TASK_ID; } } diff --git a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java new file mode 100644 index 0000000000..19a48dbf20 --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.util; + +import android.content.Context; +import android.view.Display; + +import com.android.launcher3.util.window.WindowManagerProxy; + +/** + * Extension of {@link WindowManagerProxy} with some assumption for the default system Launcher + */ +public class SystemWindowManagerProxy extends WindowManagerProxy { + + public SystemWindowManagerProxy(Context context) { + super(true); + } + + @Override + protected String getDisplayId(Display display) { + return display.getUniqueId(); + } + + @Override + public boolean isInternalDisplay(Display display) { + return display.getType() == Display.TYPE_INTERNAL; + } + + @Override + public int getRotation(Context context) { + return context.getResources().getConfiguration().windowConfiguration.getRotation(); + } +} diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java index 04af3c11ab..d9f668dd1b 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java @@ -182,9 +182,8 @@ public class GroupedTaskView extends TaskView { @Override public void launchTask(@NonNull Consumer<Boolean> callback, boolean freezeTaskList) { - getRecentsView().getSplitPlaceholder().launchTasks(mTask.key.id, null, - mSecondaryTask.key.id, STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList, - getSplitRatio()); + getRecentsView().getSplitPlaceholder().launchTasks(mTask.key.id, mSecondaryTask.key.id, + STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList, getSplitRatio()); } @Override diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 5e331e2e86..6bb20fca32 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -16,7 +16,6 @@ package com.android.quickstep.views; -import static android.app.PendingIntent.FLAG_MUTABLE; import static android.view.Surface.ROTATION_0; import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.makeMeasureSpec; @@ -28,7 +27,6 @@ import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRES import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION; -import static com.android.launcher3.QuickstepTransitionManager.SPLIT_LAUNCH_DURATION; import static com.android.launcher3.Utilities.EDGE_NAV_BAR; import static com.android.launcher3.Utilities.mapToRange; import static com.android.launcher3.Utilities.squaredHypot; @@ -45,7 +43,6 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN; import static com.android.launcher3.statehandlers.DepthController.DEPTH; -import static com.android.launcher3.testing.TestProtocol.TASK_VIEW_ID_CRASH; import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; @@ -69,8 +66,6 @@ import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; -import android.app.PendingIntent; -import android.content.ComponentName; import android.content.Context; import android.content.LocusId; import android.content.res.Configuration; @@ -2013,22 +2008,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T return null; } - @Nullable - private TaskView getTaskViewByComponentName(ComponentName componentName) { - if (componentName == null) { - return null; - } - - for (int i = 0; i < getTaskViewCount(); i++) { - TaskView taskView = requireTaskViewAt(i); - if (taskView.getItemInfo().getIntent().getComponent().getPackageName().equals( - componentName.getPackageName())) { - return taskView; - } - } - return null; - } - public int getRunningTaskIndex() { TaskView taskView = getRunningTaskView(); return taskView == null ? -1 : indexOfChild(taskView); @@ -2282,8 +2261,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T * Sets the running task id, cleaning up the old running task if necessary. */ public void setCurrentTask(int runningTaskViewId) { - Log.d(TASK_VIEW_ID_CRASH, "currentRunningTaskViewId: " + mRunningTaskViewId - + " requestedTaskViewId: " + runningTaskViewId); if (mRunningTaskViewId == runningTaskViewId) { return; } @@ -3973,28 +3950,17 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T } public void initiateSplitSelect(QuickstepSystemShortcut.SplitSelectSource splitSelectSource) { - // Remove the task if it exists in Overview - TaskView matchingTaskView = getTaskViewByComponentName( - splitSelectSource.intent.getComponent()); - if (matchingTaskView != null) { - removeTaskInternal(matchingTaskView.getTaskViewId()); - } - mSplitSelectSource = splitSelectSource; - mSplitSelectStateController.setInitialTaskSelect( - PendingIntent.getActivity( - mContext, 0, splitSelectSource.intent, FLAG_MUTABLE), + mSplitSelectStateController.setInitialTaskSelect(splitSelectSource.intent, splitSelectSource.position.stagePosition); } - public PendingAnimation createSplitSelectInitAnimation() { + public PendingAnimation createSplitSelectInitAnimation(int duration) { if (mSplitHiddenTaskView != null) { - int duration = mActivity.getStateManager().getState().getTransitionDuration( - getContext()); return createTaskDismissAnimation(mSplitHiddenTaskView, true, false, duration, true /* dismissingForSplitSelection*/); } else { - PendingAnimation anim = new PendingAnimation(SPLIT_LAUNCH_DURATION); + PendingAnimation anim = new PendingAnimation(duration); createInitialSplitSelectAnimation(anim); return anim; } @@ -4039,8 +4005,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds, secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isInitialSplit */); pendingAnimation.addEndListener(aBoolean -> - mSplitSelectStateController.setSecondTaskId(task.key.id, - aBoolean1 -> RecentsView.this.resetFromSplitSelectionState())); + mSplitSelectStateController.setSecondTask( + task, aBoolean1 -> RecentsView.this.resetFromSplitSelectionState())); if (containerTaskView.containsMultipleTasks()) { // If we are launching from a child task, then only hide the thumbnail itself mSecondSplitHiddenView = thumbnailView; |