summaryrefslogtreecommitdiffstats
path: root/quickstep
diff options
context:
space:
mode:
Diffstat (limited to 'quickstep')
-rw-r--r--quickstep/libs/sysui_shared.jarbin146489 -> 146890 bytes
-rw-r--r--quickstep/recents_ui_overrides/res/values/override.xml (renamed from quickstep/res/values/override.xml)2
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java148
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java (renamed from quickstep/src/com/android/launcher3/uioverrides/OverviewState.java)0
-rw-r--r--quickstep/res/values/dimens.xml2
-rw-r--r--quickstep/res/values/strings.xml4
-rw-r--r--quickstep/src/com/android/launcher3/LauncherInitListener.java4
-rw-r--r--quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java (renamed from quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java)257
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/UiFactory.java6
-rw-r--r--quickstep/src/com/android/quickstep/RecentsActivity.java8
-rw-r--r--quickstep/src/com/android/quickstep/RecentsModel.java21
-rw-r--r--quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java17
-rw-r--r--quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java18
-rw-r--r--quickstep/src/com/android/quickstep/views/LauncherRecentsView.java2
14 files changed, 323 insertions, 166 deletions
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 8af310c21..ab97344d1 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/res/values/override.xml b/quickstep/recents_ui_overrides/res/values/override.xml
index d6836594f..c60cf5ab6 100644
--- a/quickstep/res/values/override.xml
+++ b/quickstep/recents_ui_overrides/res/values/override.xml
@@ -14,6 +14,8 @@
limitations under the License.
-->
+<!-- Class overrides for launcher with quickstep. -->
+
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_transition_manager_class" translatable="false">com.android.launcher3.LauncherAppTransitionManagerImpl</string>
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
new file mode 100644
index 000000000..9921455ca
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2018 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;
+
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.TaskUtils.findTaskViewToLaunch;
+import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.app.ActivityOptions;
+import android.content.Context;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.Interpolators;
+import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+
+/**
+ * A {@link QuickstepAppTransitionManagerImpl} that also implements recents transitions from
+ * {@link RecentsView}.
+ */
+public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransitionManagerImpl {
+
+ private RecentsView mRecentsView;
+
+ public LauncherAppTransitionManagerImpl(Context context) {
+ super(context);
+ mRecentsView = mLauncher.getOverviewPanel();
+ }
+
+ @Override
+ protected boolean isLaunchingFromRecents(@NonNull View v,
+ @Nullable RemoteAnimationTargetCompat[] targets) {
+ return mLauncher.getStateManager().getState().overviewUi
+ && findTaskViewToLaunch(mLauncher, v, targets) != null;
+ }
+
+ @Override
+ protected boolean isQuickSwitchInProgress() {
+ return mRecentsView.getQuickScrubController().isQuickSwitch();
+ }
+
+ @Override
+ protected ActivityOptions getQuickSwitchActivityOptions() {
+ return ActivityOptions.makeCustomAnimation(mLauncher, R.anim.no_anim,
+ R.anim.no_anim);
+ }
+
+ @Override
+ protected void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
+ @NonNull RemoteAnimationTargetCompat[] targets, boolean launcherClosing) {
+ RecentsView recentsView = mLauncher.getOverviewPanel();
+ boolean skipLauncherChanges = !launcherClosing;
+ boolean isLaunchingFromQuickscrub =
+ recentsView.getQuickScrubController().isWaitingForTaskLaunch();
+
+ TaskView taskView = findTaskViewToLaunch(mLauncher, v, targets);
+
+ int duration = isLaunchingFromQuickscrub
+ ? RECENTS_QUICKSCRUB_LAUNCH_DURATION
+ : RECENTS_LAUNCH_DURATION;
+
+ ClipAnimationHelper helper = new ClipAnimationHelper(mLauncher);
+ anim.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, targets, helper)
+ .setDuration(duration));
+
+ Animator childStateAnimation = null;
+ // Found a visible recents task that matches the opening app, lets launch the app from there
+ Animator launcherAnim;
+ final AnimatorListenerAdapter windowAnimEndListener;
+ if (launcherClosing) {
+ launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView, helper);
+ launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
+ launcherAnim.setDuration(duration);
+
+ // Make sure recents gets fixed up by resetting task alphas and scales, etc.
+ windowAnimEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLauncher.getStateManager().moveToRestState();
+ mLauncher.getStateManager().reapplyState();
+ }
+ };
+ } else {
+ AnimatorPlaybackController controller =
+ mLauncher.getStateManager().createAnimationToNewWorkspace(NORMAL, duration);
+ controller.dispatchOnStart();
+ childStateAnimation = controller.getTarget();
+ launcherAnim = controller.getAnimationPlayer().setDuration(duration);
+ windowAnimEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLauncher.getStateManager().goToState(NORMAL, false);
+ }
+ };
+ }
+ anim.play(launcherAnim);
+
+ // Set the current animation first, before adding windowAnimEndListener. Setting current
+ // animation adds some listeners which need to be called before windowAnimEndListener
+ // (the ordering of listeners matter in this case).
+ mLauncher.getStateManager().setCurrentAnimation(anim, childStateAnimation);
+ anim.addListener(windowAnimEndListener);
+ }
+
+ @Override
+ protected Runnable composeViewContentAnimator(@NonNull AnimatorSet anim, float[] alphas,
+ float[] trans) {
+ RecentsView overview = mLauncher.getOverviewPanel();
+ ObjectAnimator alpha = ObjectAnimator.ofFloat(overview,
+ RecentsView.CONTENT_ALPHA, alphas);
+ alpha.setDuration(CONTENT_ALPHA_DURATION);
+ alpha.setInterpolator(LINEAR);
+ anim.play(alpha);
+
+ ObjectAnimator transY = ObjectAnimator.ofFloat(overview, View.TRANSLATION_Y, trans);
+ transY.setInterpolator(AGGRESSIVE_EASE);
+ transY.setDuration(CONTENT_TRANSLATION_DURATION);
+ anim.play(transY);
+
+ return mLauncher.getStateManager()::reapplyState;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java
index de6f7a759..de6f7a759 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index e0c4e4baa..8d62ab8e1 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -20,6 +20,8 @@
<dimen name="task_thumbnail_half_top_margin">12dp</dimen>
<dimen name="task_thumbnail_icon_size">48dp</dimen>
<dimen name="task_corner_radius">8dp</dimen>
+ <!-- For screens without rounded corners -->
+ <dimen name="task_corner_radius_small">2dp</dimen>
<dimen name="recents_page_spacing">10dp</dimen>
<dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen>
<dimen name="quickscrub_adjacent_visible_width">20dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 7c4795694..0c741a140 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -62,8 +62,4 @@
<!-- Annotation shown on an app card in Recents, telling that the app has a usage limit set by
the user, and a given time is left for it today [CHAR LIMIT=20] -->
<string name="time_left_for_app"><xliff:g id="time" example="7 minutes">%1$s</xliff:g> left today</string>
-
- <!-- Annotation shown on an app card in Recents, telling that the app is in a group that has a
- usage limit set by the user, and a given time is left for the group today [CHAR LIMIT=20] -->
- <string name="time_left_for_group"><xliff:g id="time" example="1 hour">%1$s</xliff:g> left for group</string>
</resources> \ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java
index 08b6bfc6a..c5c5323ec 100644
--- a/quickstep/src/com/android/launcher3/LauncherInitListener.java
+++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java
@@ -44,8 +44,8 @@ public class LauncherInitListener extends InternalStateHandler implements Activi
@Override
protected boolean init(Launcher launcher, boolean alreadyOnHome) {
if (mRemoteAnimationProvider != null) {
- LauncherAppTransitionManagerImpl appTransitionManager =
- (LauncherAppTransitionManagerImpl) launcher.getAppTransitionManager();
+ QuickstepAppTransitionManagerImpl appTransitionManager =
+ (QuickstepAppTransitionManagerImpl) launcher.getAppTransitionManager();
// Set a one-time animation provider. After the first call, this will get cleared.
// TODO: Probably also check the intended target id.
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 264ad5ab1..07a5b7202 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -22,7 +22,6 @@ import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS;
import static com.android.launcher3.BaseActivity.PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
@@ -30,8 +29,6 @@ import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
-import static com.android.quickstep.TaskUtils.findTaskViewToLaunch;
-import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
@@ -57,10 +54,12 @@ import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.InsettableFrameLayout.LayoutParams;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.graphics.DrawableFactory;
@@ -68,12 +67,9 @@ import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.quickstep.RecentsModel;
-import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.RemoteAnimationTargetSet;
-import com.android.quickstep.views.RecentsView;
-import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityCompat;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
@@ -85,14 +81,15 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
import com.android.systemui.shared.system.WindowManagerWrapper;
/**
- * Manages the opening and closing app transitions from Launcher.
+ * {@link LauncherAppTransitionManager} with Quickstep-specific app transitions for launching from
+ * home and/or all-apps.
*/
@TargetApi(Build.VERSION_CODES.O)
@SuppressWarnings("unused")
-public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManager
+public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTransitionManager
implements OnDeviceProfileChangeListener {
- private static final String TAG = "LauncherTransition";
+ private static final String TAG = "QuickstepTransition";
/** Duration of status bar animations. */
public static final int STATUS_BAR_TRANSITION_DURATION = 120;
@@ -119,10 +116,14 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
private static final int LAUNCHER_RESUME_START_DELAY = 100;
private static final int CLOSING_TRANSITION_DURATION_MS = 250;
+ protected static final int CONTENT_ALPHA_DURATION = 217;
+ protected static final int CONTENT_TRANSLATION_DURATION = 350;
+
// Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down.
public static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f;
- private final Launcher mLauncher;
+ protected final Launcher mLauncher;
+
private final DragLayer mDragLayer;
private final AlphaProperty mDragLayerAlpha;
@@ -150,7 +151,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
}
};
- public LauncherAppTransitionManagerImpl(Context context) {
+ public QuickstepAppTransitionManagerImpl(Context context) {
mLauncher = Launcher.getLauncher(context);
mDragLayer = mLauncher.getDragLayer();
mDragLayerAlpha = mDragLayer.getAlphaProperty(ALPHA_INDEX_TRANSITIONS);
@@ -179,12 +180,9 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
@Override
public ActivityOptions getActivityLaunchOptions(Launcher launcher, View v) {
if (hasControlRemoteAppTransitionPermission()) {
- boolean fromRecents = mLauncher.getStateManager().getState().overviewUi
- && findTaskViewToLaunch(launcher, v, null) != null;
- RecentsView recentsView = mLauncher.getOverviewPanel();
- if (fromRecents && recentsView.getQuickScrubController().isQuickSwitch()) {
- return ActivityOptions.makeCustomAnimation(mLauncher, R.anim.no_anim,
- R.anim.no_anim);
+ boolean fromRecents = isLaunchingFromRecents(v, null /* targets */);
+ if (fromRecents && isQuickSwitchInProgress()) {
+ return getQuickSwitchActivityOptions();
}
RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mHandler,
@@ -198,34 +196,10 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
boolean launcherClosing =
launcherIsATargetWithMode(targetCompats, MODE_CLOSING);
- if (!composeRecentsLaunchAnimator(v, targetCompats, anim)) {
- // Set the state animation first so that any state listeners are called
- // before our internal listeners.
- mLauncher.getStateManager().setCurrentAnimation(anim);
-
- Rect windowTargetBounds = getWindowTargetBounds(targetCompats);
- boolean isAllOpeningTargetTrs = true;
- for (int i = 0; i < targetCompats.length; i++) {
- RemoteAnimationTargetCompat target = targetCompats[i];
- if (target.mode == MODE_OPENING) {
- isAllOpeningTargetTrs &= target.isTranslucent;
- }
- if (!isAllOpeningTargetTrs) break;
- }
- playIconAnimators(anim, v, windowTargetBounds, !isAllOpeningTargetTrs);
- if (launcherClosing) {
- Pair<AnimatorSet, Runnable> launcherContentAnimator =
- getLauncherContentAnimator(true /* isAppOpening */,
- new float[] {0, mContentTransY});
- anim.play(launcherContentAnimator.first);
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- launcherContentAnimator.second.run();
- }
- });
- }
- anim.play(getOpeningWindowAnimators(v, targetCompats, windowTargetBounds));
+ if (isLaunchingFromRecents(v, targetCompats)) {
+ composeRecentsLaunchAnimator(anim, v, targetCompats, launcherClosing);
+ } else {
+ composeIconLaunchAnimator(anim, v, targetCompats, launcherClosing);
}
if (launcherClosing) {
@@ -236,6 +210,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
}
};
+ // Note that this duration is a guess as we do not know if the animation will be a
+ // recents launch or not for sure until we know the opening app targets.
int duration = fromRecents
? RECENTS_LAUNCH_DURATION
: APP_LAUNCH_DURATION;
@@ -249,6 +225,83 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
}
/**
+ * Whether the launch is a recents app transition and we should do a launch animation
+ * from the recents view. Note that if the remote animation targets are not provided, this
+ * may not always be correct as we may resolve the opening app to a task when the animation
+ * starts.
+ *
+ * @param v the view to launch from
+ * @param targets apps that are opening/closing
+ * @return true if the app is launching from recents, false if it most likely is not
+ */
+ protected abstract boolean isLaunchingFromRecents(@NonNull View v,
+ @Nullable RemoteAnimationTargetCompat[] targets);
+
+ /**
+ * Whether a quick scrub is in progress.
+ *
+ * @return true if in progress
+ */
+ protected abstract boolean isQuickSwitchInProgress();
+
+ /**
+ * Get activity options for a quick switch launch that include the launch animation.
+ *
+ * @return the activity options for a quick switch recents launch
+ */
+ protected abstract ActivityOptions getQuickSwitchActivityOptions();
+
+ /**
+ * Composes the animations for a launch from the recents list.
+ *
+ * @param anim the animator set to add to
+ * @param v the launching view
+ * @param targets the apps that are opening/closing
+ * @param launcherClosing true if the launcher app is closing
+ */
+ protected abstract void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
+ @NonNull RemoteAnimationTargetCompat[] targets, boolean launcherClosing);
+
+ /**
+ * Compose the animations for a launch from the app icon.
+ *
+ * @param anim the animation to add to
+ * @param v the launching view with the icon
+ * @param targets the list of opening/closing apps
+ * @param launcherClosing true if launcher is closing
+ */
+ private void composeIconLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
+ @NonNull RemoteAnimationTargetCompat[] targets, boolean launcherClosing) {
+ // Set the state animation first so that any state listeners are called
+ // before our internal listeners.
+ mLauncher.getStateManager().setCurrentAnimation(anim);
+
+ Rect windowTargetBounds = getWindowTargetBounds(targets);
+ boolean isAllOpeningTargetTrs = true;
+ for (int i = 0; i < targets.length; i++) {
+ RemoteAnimationTargetCompat target = targets[i];
+ if (target.mode == MODE_OPENING) {
+ isAllOpeningTargetTrs &= target.isTranslucent;
+ }
+ if (!isAllOpeningTargetTrs) break;
+ }
+ playIconAnimators(anim, v, windowTargetBounds, !isAllOpeningTargetTrs);
+ if (launcherClosing) {
+ Pair<AnimatorSet, Runnable> launcherContentAnimator =
+ getLauncherContentAnimator(true /* isAppOpening */,
+ new float[] {0, mContentTransY});
+ anim.play(launcherContentAnimator.first);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ launcherContentAnimator.second.run();
+ }
+ });
+ }
+ anim.play(getOpeningWindowAnimators(v, targets, windowTargetBounds));
+ }
+
+ /**
* Return the window bounds of the opening target.
* In multiwindow mode, we need to get the final size of the opening app window target to help
* figure out where the floating view should animate to.
@@ -278,75 +331,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
}
/**
- * Composes the animations for a launch from the recents list if possible.
- */
- private boolean composeRecentsLaunchAnimator(View v,
- RemoteAnimationTargetCompat[] targets, AnimatorSet target) {
- // Ensure recents is actually visible
- if (!mLauncher.getStateManager().getState().overviewUi) {
- return false;
- }
-
- RecentsView recentsView = mLauncher.getOverviewPanel();
- boolean launcherClosing = launcherIsATargetWithMode(targets, MODE_CLOSING);
- boolean skipLauncherChanges = !launcherClosing;
- boolean isLaunchingFromQuickscrub =
- recentsView.getQuickScrubController().isWaitingForTaskLaunch();
-
- TaskView taskView = findTaskViewToLaunch(mLauncher, v, targets);
- if (taskView == null) {
- return false;
- }
-
- int duration = isLaunchingFromQuickscrub
- ? RECENTS_QUICKSCRUB_LAUNCH_DURATION
- : RECENTS_LAUNCH_DURATION;
-
- ClipAnimationHelper helper = new ClipAnimationHelper(mLauncher);
- target.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, targets, helper)
- .setDuration(duration));
-
- Animator childStateAnimation = null;
- // Found a visible recents task that matches the opening app, lets launch the app from there
- Animator launcherAnim;
- final AnimatorListenerAdapter windowAnimEndListener;
- if (launcherClosing) {
- launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView, helper);
- launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
- launcherAnim.setDuration(duration);
-
- // Make sure recents gets fixed up by resetting task alphas and scales, etc.
- windowAnimEndListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mLauncher.getStateManager().moveToRestState();
- mLauncher.getStateManager().reapplyState();
- }
- };
- } else {
- AnimatorPlaybackController controller =
- mLauncher.getStateManager().createAnimationToNewWorkspace(NORMAL, duration);
- controller.dispatchOnStart();
- childStateAnimation = controller.getTarget();
- launcherAnim = controller.getAnimationPlayer().setDuration(duration);
- windowAnimEndListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mLauncher.getStateManager().goToState(NORMAL, false);
- }
- };
- }
- target.play(launcherAnim);
-
- // Set the current animation first, before adding windowAnimEndListener. Setting current
- // animation adds some listeners which need to be called before windowAnimEndListener
- // (the ordering of listeners matter in this case).
- mLauncher.getStateManager().setCurrentAnimation(target, childStateAnimation);
- target.addListener(windowAnimEndListener);
- return true;
- }
-
- /**
* Content is everything on screen except the background and the floating view (if any).
*
* @param isAppOpening True when this is called when an app is opening.
@@ -371,7 +355,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
appsView.setTranslationY(trans[0]);
ObjectAnimator alpha = ObjectAnimator.ofFloat(appsView, View.ALPHA, alphas);
- alpha.setDuration(217);
+ alpha.setDuration(CONTENT_ALPHA_DURATION);
alpha.setInterpolator(LINEAR);
appsView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
alpha.addListener(new AnimatorListenerAdapter() {
@@ -382,7 +366,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
});
ObjectAnimator transY = ObjectAnimator.ofFloat(appsView, View.TRANSLATION_Y, trans);
transY.setInterpolator(AGGRESSIVE_EASE);
- transY.setDuration(350);
+ transY.setDuration(CONTENT_TRANSLATION_DURATION);
launcherAnimator.play(alpha);
launcherAnimator.play(transY);
@@ -396,32 +380,19 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
launcherAnimator.play(ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS,
allAppsController.getProgress(), ALL_APPS_PROGRESS_OFF_SCREEN));
-
- RecentsView overview = mLauncher.getOverviewPanel();
- ObjectAnimator alpha = ObjectAnimator.ofFloat(overview,
- RecentsView.CONTENT_ALPHA, alphas);
- alpha.setDuration(217);
- alpha.setInterpolator(LINEAR);
- launcherAnimator.play(alpha);
-
- ObjectAnimator transY = ObjectAnimator.ofFloat(overview, View.TRANSLATION_Y, trans);
- transY.setInterpolator(AGGRESSIVE_EASE);
- transY.setDuration(350);
- launcherAnimator.play(transY);
-
- endListener = mLauncher.getStateManager()::reapplyState;
+ endListener = composeViewContentAnimator(launcherAnimator, alphas, trans);
} else {
mDragLayerAlpha.setValue(alphas[0]);
ObjectAnimator alpha =
ObjectAnimator.ofFloat(mDragLayerAlpha, MultiValueAlpha.VALUE, alphas);
- alpha.setDuration(217);
+ alpha.setDuration(CONTENT_ALPHA_DURATION);
alpha.setInterpolator(LINEAR);
launcherAnimator.play(alpha);
mDragLayer.setTranslationY(trans[0]);
ObjectAnimator transY = ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y, trans);
transY.setInterpolator(AGGRESSIVE_EASE);
- transY.setDuration(350);
+ transY.setDuration(CONTENT_TRANSLATION_DURATION);
launcherAnimator.play(transY);
mDragLayer.getScrim().hideSysUiScrim(true);
@@ -435,6 +406,17 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
}
/**
+ * Compose recents view alpha and translation Y animation when launcher opens/closes apps.
+ *
+ * @param anim the animator set to add to
+ * @param alphas the alphas to animate to over time
+ * @param trans the translation Y values to animator to over time
+ * @return listener to run when the animation ends
+ */
+ protected abstract Runnable composeViewContentAnimator(@NonNull AnimatorSet anim,
+ float[] alphas, float[] trans);
+
+ /**
* Animators for the "floating view" of the view used to launch the target.
*/
private void playIconAnimators(AnimatorSet appOpenAnimator, View v, Rect windowTargetBounds,
@@ -633,9 +615,12 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
// Animate window corner radius from 100% to windowCornerRadius.
float windowCornerRadius = RecentsModel.INSTANCE.get(mLauncher)
.getWindowCornerRadius();
- float circleRadius = iconWidth / 2f;
- float windowRadius = Utilities.mapRange(easePercent, circleRadius,
- windowCornerRadius);
+ float windowRadius = 0;
+ if (RecentsModel.INSTANCE.get(mLauncher).supportsRoundedCornersOnWindows()) {
+ float circleRadius = iconWidth / 2f;
+ windowRadius = Utilities.mapRange(easePercent, circleRadius,
+ windowCornerRadius);
+ }
// Animate the window crop so that it starts off as a square, and then reveals
// horizontally.
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index a9b251609..d295ac5c5 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -37,10 +37,10 @@ import android.util.Base64;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppTransitionManagerImpl;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.QuickstepAppTransitionManagerImpl;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.TouchController;
@@ -203,8 +203,8 @@ public class UiFactory {
public static void useFadeOutAnimationForLauncherStart(Launcher launcher,
CancellationSignal cancellationSignal) {
- LauncherAppTransitionManagerImpl appTransitionManager =
- (LauncherAppTransitionManagerImpl) launcher.getAppTransitionManager();
+ QuickstepAppTransitionManagerImpl appTransitionManager =
+ (QuickstepAppTransitionManagerImpl) launcher.getAppTransitionManager();
appTransitionManager.setRemoteAnimationProvider((targets) -> {
// On the first call clear the reference.
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index deedd324a..89c7abadb 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -18,9 +18,11 @@ package com.android.quickstep;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.STATUS_BAR_TRANSITION_DURATION;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.STATUS_BAR_TRANSITION_PRE_DELAY;
+import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
+import static com.android.launcher3.QuickstepAppTransitionManagerImpl
+ .STATUS_BAR_TRANSITION_DURATION;
+import static com.android.launcher3.QuickstepAppTransitionManagerImpl
+ .STATUS_BAR_TRANSITION_PRE_DELAY;
import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 442b106fa..e61c00af7 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -66,6 +66,7 @@ public class RecentsModel extends TaskStackChangeListener {
private final TaskThumbnailCache mThumbnailCache;
private float mWindowCornerRadius = -1;
+ private Boolean mSupportsRoundedCornersOnWindows;
private RecentsModel(Context context) {
mContext = context;
@@ -199,6 +200,26 @@ public class RecentsModel extends TaskStackChangeListener {
return mWindowCornerRadius;
}
+ public boolean supportsRoundedCornersOnWindows() {
+ if (mSupportsRoundedCornersOnWindows == null) {
+ if (mSystemUiProxy != null) {
+ try {
+ mSupportsRoundedCornersOnWindows =
+ mSystemUiProxy.supportsRoundedCornersOnWindows();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Connection to ISystemUIProxy was lost, ignoring window corner "
+ + "radius");
+ return false;
+ }
+ } else {
+ Log.w(TAG, "ISystemUIProxy is null, ignoring window corner radius");
+ return false;
+ }
+ }
+
+ return mSupportsRoundedCornersOnWindows;
+ }
+
public void onTrimMemory(int level) {
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
mThumbnailCache.getHighResLoadingState().setVisible(false);
diff --git a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
index 84033cbd6..31de68395 100644
--- a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -91,6 +91,8 @@ public class ClipAnimationHelper {
private final float mWindowCornerRadius;
// Corner radius of windows when they're in overview mode.
private final float mTaskCornerRadius;
+ // If windows can have real time rounded corners.
+ private final boolean mSupportsRoundedCornersOnWindows;
// Corner radius currently applied to transformed window.
private float mCurrentCornerRadius;
@@ -107,8 +109,12 @@ public class ClipAnimationHelper {
(t, a1) -> a1;
public ClipAnimationHelper(Context context) {
- mTaskCornerRadius = context.getResources().getDimension(R.dimen.task_corner_radius);
- mWindowCornerRadius = RecentsModel.INSTANCE.get(context).getWindowCornerRadius();
+ mWindowCornerRadius = RecentsModel.INSTANCE.get(context).getWindowCornerRadius();
+ mSupportsRoundedCornersOnWindows = RecentsModel.INSTANCE.get(context)
+ .supportsRoundedCornersOnWindows();
+ int taskCornerRadiusRes = mSupportsRoundedCornersOnWindows ?
+ R.dimen.task_corner_radius : R.dimen.task_corner_radius_small;
+ mTaskCornerRadius = context.getResources().getDimension(taskCornerRadiusRes);
}
private void updateSourceStack(RemoteAnimationTargetCompat target) {
@@ -197,9 +203,10 @@ public class ClipAnimationHelper {
mTmpMatrix.setRectToRect(mSourceRect, params.currentRect, ScaleToFit.FILL);
mTmpMatrix.postTranslate(app.position.x, app.position.y);
mClipRectF.roundOut(crop);
- cornerRadius = Utilities.mapRange(params.progress, mWindowCornerRadius,
- mTaskCornerRadius);
- mCurrentCornerRadius = cornerRadius;
+ if (mSupportsRoundedCornersOnWindows) {
+ cornerRadius = Utilities.mapRange(params.progress, mWindowCornerRadius,
+ mTaskCornerRadius);
+ }
}
alpha = mTaskAlphaCallback.apply(app, params.targetAlpha);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
index aafd725cb..9ad750b1b 100644
--- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -77,7 +77,6 @@ public final class DigitalWellBeingToast extends LinearLayout {
Utilities.THREAD_POOL_EXECUTOR.execute(() -> {
long appUsageLimitTimeMs = -1;
long appRemainingTimeMs = -1;
- boolean isGroupLimit = true;
try {
final Method getAppUsageLimit = LauncherApps.class.getMethod(
@@ -95,8 +94,6 @@ public final class DigitalWellBeingToast extends LinearLayout {
invoke(usageLimit);
appRemainingTimeMs = (long) appUsageLimitClass.getMethod("getUsageRemaining").
invoke(usageLimit);
- isGroupLimit = (boolean) appUsageLimitClass.getMethod("isGroupLimit").
- invoke(usageLimit);
}
} catch (Exception e) {
// Do nothing
@@ -104,14 +101,13 @@ public final class DigitalWellBeingToast extends LinearLayout {
final long appUsageLimitTimeMsFinal = appUsageLimitTimeMs;
final long appRemainingTimeMsFinal = appRemainingTimeMs;
- final boolean isGroupLimitFinal = isGroupLimit;
post(() -> {
if (appUsageLimitTimeMsFinal < 0) {
setVisibility(GONE);
} else {
setVisibility(VISIBLE);
- mText.setText(getText(appRemainingTimeMsFinal, isGroupLimitFinal));
+ mText.setText(getText(appRemainingTimeMsFinal));
mImage.setImageResource(appRemainingTimeMsFinal > 0 ?
R.drawable.hourglass_top : R.drawable.hourglass_bottom);
}
@@ -119,9 +115,7 @@ public final class DigitalWellBeingToast extends LinearLayout {
callback.call(
appUsageLimitTimeMsFinal >= 0 && appRemainingTimeMsFinal <= 0 ? 0 : 1,
getContentDescriptionForTask(
- task, appUsageLimitTimeMsFinal,
- appRemainingTimeMsFinal,
- isGroupLimitFinal));
+ task, appUsageLimitTimeMsFinal, appRemainingTimeMsFinal));
});
});
}
@@ -185,12 +179,12 @@ public final class DigitalWellBeingToast extends LinearLayout {
duration, FormatWidth.NARROW, R.string.shorter_duration_less_than_one_minute);
}
- private String getText(long remainingTime, boolean isGroupLimit) {
+ private String getText(long remainingTime) {
final Resources resources = getResources();
return (remainingTime <= 0) ?
resources.getString(R.string.app_in_grayscale) :
resources.getString(
- isGroupLimit ? R.string.time_left_for_group : R.string.time_left_for_app,
+ R.string.time_left_for_app,
getShorterReadableDuration(Duration.ofMillis(remainingTime)));
}
@@ -214,12 +208,12 @@ public final class DigitalWellBeingToast extends LinearLayout {
}
private String getContentDescriptionForTask(
- Task task, long appUsageLimitTimeMs, long appRemainingTimeMs, boolean isGroupLimit) {
+ Task task, long appUsageLimitTimeMs, long appRemainingTimeMs) {
return appUsageLimitTimeMs >= 0 ?
getResources().getString(
R.string.task_contents_description_with_remaining_time,
task.titleDescription,
- getText(appRemainingTimeMs, isGroupLimit)) :
+ getText(appRemainingTimeMs)) :
task.titleDescription;
}
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 722c721f9..f8eced00a 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -16,9 +16,9 @@
package com.android.quickstep.views;
import static com.android.launcher3.AbstractFloatingView.TYPE_QUICKSTEP_PREVIEW;
-import static com.android.launcher3.LauncherAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN;
import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.QuickstepAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;