summaryrefslogtreecommitdiff
path: root/quickstep/src
diff options
context:
space:
mode:
Diffstat (limited to 'quickstep/src')
-rw-r--r--quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java20
-rw-r--r--quickstep/src/com/android/launcher3/QuickstepTransitionManager.java22
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java5
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java7
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java35
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java6
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java17
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarUnfoldAnimationController.java25
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java33
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java10
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/unfold/NonDestroyableScopedUnfoldTransitionProgressProvider.java30
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java15
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java4
-rw-r--r--quickstep/src/com/android/quickstep/OrientationTouchTransformer.java79
-rw-r--r--quickstep/src/com/android/quickstep/RecentsActivity.java4
-rw-r--r--quickstep/src/com/android/quickstep/TaskAnimationManager.java4
-rw-r--r--quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java3
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java33
-rw-r--r--quickstep/src/com/android/quickstep/interaction/AllSetActivity.java7
-rw-r--r--quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java4
-rw-r--r--quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java2
-rw-r--r--quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java2
-rw-r--r--quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java12
-rw-r--r--quickstep/src/com/android/quickstep/interaction/TutorialController.java61
-rw-r--r--quickstep/src/com/android/quickstep/interaction/TutorialFragment.java29
-rw-r--r--quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java10
-rw-r--r--quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java39
-rw-r--r--quickstep/src/com/android/quickstep/util/ImageActionUtils.java5
-rw-r--r--quickstep/src/com/android/quickstep/util/RecentsOrientedState.java11
-rw-r--r--quickstep/src/com/android/quickstep/util/SplitSelectStateController.java66
-rw-r--r--quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java46
-rw-r--r--quickstep/src/com/android/quickstep/views/GroupedTaskView.java5
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsView.java44
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;