Loading quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +9 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.launcher3.uioverrides.states; import android.content.Context; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.Launcher; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.userevent.nano.LauncherLogProto; Loading Loading @@ -54,11 +55,7 @@ public class BackgroundAppState extends OverviewState { @Override public float[] getOverviewScaleAndOffset(Launcher launcher) { return new float[] {getOverviewScale(launcher), NO_OFFSET}; } private float getOverviewScale(Launcher launcher) { return ((RecentsView) launcher.getOverviewPanel()).getMaxScaleForFullScreen(); return getOverviewScaleAndOffsetForBackgroundState(launcher); } @Override Loading Loading @@ -88,4 +85,11 @@ public class BackgroundAppState extends OverviewState { protected float getDepthUnchecked(Context context) { return 1f; } public static float[] getOverviewScaleAndOffsetForBackgroundState( BaseDraggingActivity activity) { return new float[] { ((RecentsView) activity.getOverviewPanel()).getMaxScaleForFullScreen(), NO_OFFSET}; } } quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java +13 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Rect; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; Loading Loading @@ -49,22 +50,25 @@ public class OverviewModalTaskState extends OverviewState { @Override public float[] getOverviewScaleAndOffset(Launcher launcher) { Resources res = launcher.getBaseContext().getResources(); return getOverviewScaleAndOffsetForModalState(launcher); } @Override public float getOverviewModalness() { return 1.0f; } public static float[] getOverviewScaleAndOffsetForModalState(BaseDraggingActivity activity) { Resources res = activity.getResources(); Rect out = new Rect(); launcher.<RecentsView>getOverviewPanel().getTaskSize(out); activity.<RecentsView>getOverviewPanel().getTaskSize(out); int taskHeight = out.height(); float topMargin = res.getDimension(R.dimen.task_thumbnail_top_margin); float bottomMargin = res.getDimension(R.dimen.overview_actions_top_margin); float newHeight = taskHeight + topMargin + bottomMargin; float scale = newHeight / taskHeight; return new float[] {scale, 0}; } @Override public float getOverviewModalness() { return 1.0f; return new float[] {scale, NO_OFFSET}; } } quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java +16 −20 Original line number Diff line number Diff line Loading @@ -15,14 +15,15 @@ */ package com.android.quickstep; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import static com.android.quickstep.fallback.FallbackRecentsView.ZOOM_PROGRESS; import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP; import static com.android.quickstep.fallback.RecentsState.DEFAULT; import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY; import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Rect; Loading @@ -30,6 +31,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.ActivityInitListener; Loading Loading @@ -89,15 +91,13 @@ public final class FallbackActivityInterface implements public AnimationFactory prepareRecentsUI( boolean activityVisible, Consumer<AnimatorPlaybackController> callback) { RecentsActivity activity = getCreatedActivity(); if (activityVisible) { if (activity == null) { return (transitionLength) -> { }; } activity.getStateManager().goToState(BACKGROUND_APP); FallbackRecentsView rv = activity.getOverviewPanel(); rv.setContentAlpha(0); rv.getClearAllButton().setVisibilityAlpha(0); rv.setDisallowScrollToClearAll(true); rv.setInOverviewState(false); return new AnimationFactory() { Loading @@ -115,23 +115,19 @@ public final class FallbackActivityInterface implements @Override public void createActivityInterface(long transitionLength) { AnimatorSet animatorSet = new AnimatorSet(); PendingAnimation pa = new PendingAnimation(transitionLength * 2); if (isAnimatingToRecents) { ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1); anim.setDuration(transitionLength).setInterpolator(LINEAR); animatorSet.play(anim); pa.addFloat(rv, CONTENT_ALPHA, 0, 1, LINEAR); } ObjectAnimator anim = ObjectAnimator.ofFloat(rv, ZOOM_PROGRESS, 1, 0); anim.setDuration(transitionLength).setInterpolator(LINEAR); animatorSet.play(anim); AnimatorPlaybackController controller = AnimatorPlaybackController.wrap(animatorSet, transitionLength); pa.addFloat(rv, SCALE_PROPERTY, rv.getMaxScaleForFullScreen(), 1, LINEAR); pa.addFloat(rv, FULLSCREEN_PROGRESS, 1, 0, LINEAR); AnimatorPlaybackController controller = pa.createPlaybackController(); // Since we are changing the start position of the UI, reapply the state, at the end controller.setEndAction(() -> rv.setInOverviewState(controller.getInterpolatedProgress() > 0.5)); controller.setEndAction(() -> activity.getStateManager().goToState( controller.getInterpolatedProgress() > 0.5 ? DEFAULT : BACKGROUND_APP)); callback.accept(controller); } }; Loading @@ -147,7 +143,7 @@ public final class FallbackActivityInterface implements @Nullable @Override public RecentsActivity getCreatedActivity() { return BaseRecentsActivity.ACTIVITY_TRACKER.getCreatedActivity(); return RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity(); } @Nullable Loading quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java +48 −4 Original line number Diff line number Diff line Loading @@ -37,10 +37,12 @@ import android.os.Bundle; import android.util.ArrayMap; import android.view.MotionEvent; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.util.ObjectWrapper; import com.android.quickstep.BaseActivityInterface.AnimationFactory; import com.android.quickstep.GestureState.GestureEndTarget; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.RectFSpringAnim; Loading Loading @@ -103,6 +105,12 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa private final PointF mEndVelocityPxPerMs = new PointF(0, 0.5f); private RunningWindowAnim mFinishAnimation; // Used to control Recents components throughout the swipe gesture. private AnimatorPlaybackController mLauncherTransitionController; private boolean mHasLauncherTransitionControllerStarted; private AnimationFactory mAnimationFactory = (t) -> { }; public FallbackSwipeHandler(Context context, RecentsAnimationDeviceState deviceState, GestureState gestureState, InputConsumerController inputConsumer, boolean isLikelyToStartNewTask, boolean continuingLastGesture) { Loading Loading @@ -165,10 +173,6 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa mRecentsView = mActivity.getOverviewPanel(); mRecentsView.setOnPageTransitionEndCallback(null); linkRecentsViewScroll(); mRecentsView.setDisallowScrollToClearAll(true); mRecentsView.getClearAllButton().setVisibilityAlpha(0); mRecentsView.setZoomProgress(1); if (!mContinuingLastGesture) { if (mRunningOverHome) { mRecentsView.onGestureAnimationStart(mGestureState.getRunningTask()); Loading @@ -178,9 +182,48 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa } mStateCallback.setStateOnUiThread(STATE_RECENTS_PRESENT); mDeviceState.enableMultipleRegions(false); mAnimationFactory = mActivityInterface.prepareRecentsUI(alreadyOnHome, this::onAnimatorPlaybackControllerCreated); mAnimationFactory.createActivityInterface(mTransitionDragLength); return true; } @Override protected void initTransitionEndpoints(DeviceProfile dp) { super.initTransitionEndpoints(dp); if (canCreateNewOrUpdateExistingLauncherTransitionController()) { mAnimationFactory.createActivityInterface(mTransitionDragLength); } } private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) { mLauncherTransitionController = anim; mLauncherTransitionController.dispatchSetInterpolator(t -> t * mDragLengthFactor); mLauncherTransitionController.dispatchOnStart(); updateLauncherTransitionProgress(); } private void updateLauncherTransitionProgress() { if (mLauncherTransitionController == null || !canCreateNewOrUpdateExistingLauncherTransitionController()) { return; } // Normalize the progress to 0 to 1, as the animation controller will clamp it to that // anyway. The controller mimics the drag length factor by applying it to its interpolators. float progress = mCurrentShift.value / mDragLengthFactor; mLauncherTransitionController.setPlayFraction(progress); } /** * We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME * (it has its own animation) or if we're already animating the current controller. * @return Whether we can create the launcher controller or update its progress. */ private boolean canCreateNewOrUpdateExistingLauncherTransitionController() { return mGestureState.getEndTarget() != HOME && !mHasLauncherTransitionControllerStarted; } @Override protected boolean moveWindowWithRecentsScroll() { return mInQuickSwitchMode; Loading Loading @@ -260,6 +303,7 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa } applyWindowTransform(); updateLauncherTransitionProgress(); } @Override Loading quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +156 −26 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ 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.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; Loading @@ -29,21 +32,32 @@ import android.animation.AnimatorSet; import android.app.ActivityOptions; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.view.View; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAnimationRunner; import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.util.ActivityTracker; import com.android.launcher3.util.ObjectWrapper; import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.fallback.FallbackRecentsStateController; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.fallback.RecentsRootView; import com.android.quickstep.fallback.RecentsState; import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityOptionsCompat; Loading @@ -51,26 +65,40 @@ import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.io.FileDescriptor; import java.io.PrintWriter; /** * A recents activity that shows the recently launched tasks as swipable task cards. * See {@link com.android.quickstep.views.RecentsView}. */ public final class RecentsActivity extends BaseRecentsActivity { public final class RecentsActivity extends StatefulActivity<RecentsState> { public static final String EXTRA_THUMBNAIL = "thumbnailData"; public static final String EXTRA_TASK_ID = "taskID"; public static final ActivityTracker<RecentsActivity> ACTIVITY_TRACKER = new ActivityTracker<>(); private Handler mUiHandler = new Handler(Looper.getMainLooper()); private RecentsRootView mRecentsRootView; private FallbackRecentsView mFallbackRecentsView; private OverviewActionsView mActionsView; @Override private Configuration mOldConfig; private StateManager<RecentsState> mStateManager; /** * Init drag layer and overview panel views. */ protected void initViews() { setContentView(R.layout.fallback_recents_activity); mRecentsRootView = findViewById(R.id.drag_layer); mFallbackRecentsView = findViewById(R.id.overview_panel); mActionsView = findViewById(R.id.overview_actions_view); mRecentsRootView.recreateControllers(); mFallbackRecentsView.init(findViewById(R.id.overview_actions_view)); mFallbackRecentsView.init(mActionsView); } @Override Loading Loading @@ -103,25 +131,38 @@ public final class RecentsActivity extends BaseRecentsActivity { intent.removeExtra(EXTRA_TASK_ID); intent.removeExtra(EXTRA_THUMBNAIL); super.onNewIntent(intent); ACTIVITY_TRACKER.handleNewIntent(this, intent); } @Override /** * Logic for when device configuration changes (rotation, screen size change, multi-window, * etc.) */ protected void onHandleConfigChanged() { super.onHandleConfigChanged(); mRecentsRootView.recreateControllers(); } mUserEventDispatcher = null; initDeviceProfile(); @Override protected void reapplyUi() { mRecentsRootView.dispatchInsets(); AbstractFloatingView.closeOpenViews(this, true, AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE); dispatchDeviceProfileChanged(); reapplyUi(); mRecentsRootView.recreateControllers(); } @Override /** * Generate the device profile to use in this activity. * @return device profile */ protected DeviceProfile createDeviceProfile() { DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); DeviceProfile dp1 = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); // In case we are reusing IDP, create a copy so that we don't conflict with Launcher // activity. return (mRecentsRootView != null) && isInMultiWindowMode() ? dp.getMultiWindowProfile(this, getMultiWindowDisplaySize()) : super.createDeviceProfile(); : dp1.copy(this); } @Override Loading @@ -139,6 +180,10 @@ public final class RecentsActivity extends BaseRecentsActivity { return (T) mFallbackRecentsView; } public OverviewActionsView getActionsView() { return mActionsView; } @Override public void returnToHomescreen() { super.returnToHomescreen(); Loading @@ -160,12 +205,7 @@ public final class RecentsActivity extends BaseRecentsActivity { RemoteAnimationTargetCompat[] wallpaperTargets, AnimationResult result) { AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets, wallpaperTargets); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mFallbackRecentsView.resetViewUI(); } }); anim.addListener(resetStateListener()); result.setAnimation(anim, RecentsActivity.this); } }; Loading Loading @@ -193,12 +233,7 @@ public final class RecentsActivity extends BaseRecentsActivity { .createAdjacentPageAnimForTaskLaunch(taskView); adjacentAnimation.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR); adjacentAnimation.setDuration(RECENTS_LAUNCH_DURATION); adjacentAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mFallbackRecentsView.resetTaskVisuals(); } }); adjacentAnimation.addListener(resetStateListener()); target.play(adjacentAnimation); } return target; Loading @@ -210,13 +245,14 @@ public final class RecentsActivity extends BaseRecentsActivity { // onActivityStart callback. mFallbackRecentsView.setContentAlpha(1); super.onStart(); mFallbackRecentsView.resetTaskVisuals(); } @Override protected void onStop() { super.onStop(); mFallbackRecentsView.reset(); // Workaround for b/78520668, explicitly trim memory once UI is hidden onTrimMemory(TRIM_MEMORY_UI_HIDDEN); } @Override Loading @@ -228,4 +264,98 @@ public final class RecentsActivity extends BaseRecentsActivity { public void onTaskLaunched() { mFallbackRecentsView.resetTaskVisuals(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mStateManager = new StateManager<>(this, RecentsState.DEFAULT); mOldConfig = new Configuration(getResources().getConfiguration()); initDeviceProfile(); initViews(); getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW, Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)); ACTIVITY_TRACKER.handleCreate(this); } @Override public void onConfigurationChanged(Configuration newConfig) { int diff = newConfig.diff(mOldConfig); if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) { onHandleConfigChanged(); } mOldConfig.setTo(newConfig); super.onConfigurationChanged(newConfig); } /** * Initialize/update the device profile. */ private void initDeviceProfile() { mDeviceProfile = createDeviceProfile(); onDeviceProfileInitiated(); } @Override public void onEnterAnimationComplete() { super.onEnterAnimationComplete(); // After the transition to home, enable the high-res thumbnail loader if it wasn't enabled // as a part of quickstep, so that high-res thumbnails can load the next time we enter // overview RecentsModel.INSTANCE.get(this).getThumbnailCache() .getHighResLoadingState().setVisible(true); } @Override public void onTrimMemory(int level) { super.onTrimMemory(level); RecentsModel.INSTANCE.get(this).onTrimMemory(level); } @Override protected void onDestroy() { super.onDestroy(); ACTIVITY_TRACKER.onActivityDestroyed(this); } @Override public void onBackPressed() { // TODO: Launch the task we came from startHome(); } public void startHome() { startActivity(new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_HOME) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } @Override protected StateHandler<RecentsState>[] createStateHandlers() { return new StateHandler[] { new FallbackRecentsStateController(this) }; } @Override public StateManager<RecentsState> getStateManager() { return mStateManager; } @Override public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { super.dump(prefix, fd, writer, args); writer.println(prefix + "Misc:"); dumpMisc(prefix + "\t", writer); } private AnimatorListenerAdapter resetStateListener() { return new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mFallbackRecentsView.resetTaskVisuals(); mStateManager.reapplyState(); } }; } } Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +9 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.launcher3.uioverrides.states; import android.content.Context; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.Launcher; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.userevent.nano.LauncherLogProto; Loading Loading @@ -54,11 +55,7 @@ public class BackgroundAppState extends OverviewState { @Override public float[] getOverviewScaleAndOffset(Launcher launcher) { return new float[] {getOverviewScale(launcher), NO_OFFSET}; } private float getOverviewScale(Launcher launcher) { return ((RecentsView) launcher.getOverviewPanel()).getMaxScaleForFullScreen(); return getOverviewScaleAndOffsetForBackgroundState(launcher); } @Override Loading Loading @@ -88,4 +85,11 @@ public class BackgroundAppState extends OverviewState { protected float getDepthUnchecked(Context context) { return 1f; } public static float[] getOverviewScaleAndOffsetForBackgroundState( BaseDraggingActivity activity) { return new float[] { ((RecentsView) activity.getOverviewPanel()).getMaxScaleForFullScreen(), NO_OFFSET}; } }
quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java +13 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Rect; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; Loading Loading @@ -49,22 +50,25 @@ public class OverviewModalTaskState extends OverviewState { @Override public float[] getOverviewScaleAndOffset(Launcher launcher) { Resources res = launcher.getBaseContext().getResources(); return getOverviewScaleAndOffsetForModalState(launcher); } @Override public float getOverviewModalness() { return 1.0f; } public static float[] getOverviewScaleAndOffsetForModalState(BaseDraggingActivity activity) { Resources res = activity.getResources(); Rect out = new Rect(); launcher.<RecentsView>getOverviewPanel().getTaskSize(out); activity.<RecentsView>getOverviewPanel().getTaskSize(out); int taskHeight = out.height(); float topMargin = res.getDimension(R.dimen.task_thumbnail_top_margin); float bottomMargin = res.getDimension(R.dimen.overview_actions_top_margin); float newHeight = taskHeight + topMargin + bottomMargin; float scale = newHeight / taskHeight; return new float[] {scale, 0}; } @Override public float getOverviewModalness() { return 1.0f; return new float[] {scale, NO_OFFSET}; } }
quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java +16 −20 Original line number Diff line number Diff line Loading @@ -15,14 +15,15 @@ */ package com.android.quickstep; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import static com.android.quickstep.fallback.FallbackRecentsView.ZOOM_PROGRESS; import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP; import static com.android.quickstep.fallback.RecentsState.DEFAULT; import static com.android.quickstep.util.WindowSizeStrategy.FALLBACK_RECENTS_SIZE_STRATEGY; import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Rect; Loading @@ -30,6 +31,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.ActivityInitListener; Loading Loading @@ -89,15 +91,13 @@ public final class FallbackActivityInterface implements public AnimationFactory prepareRecentsUI( boolean activityVisible, Consumer<AnimatorPlaybackController> callback) { RecentsActivity activity = getCreatedActivity(); if (activityVisible) { if (activity == null) { return (transitionLength) -> { }; } activity.getStateManager().goToState(BACKGROUND_APP); FallbackRecentsView rv = activity.getOverviewPanel(); rv.setContentAlpha(0); rv.getClearAllButton().setVisibilityAlpha(0); rv.setDisallowScrollToClearAll(true); rv.setInOverviewState(false); return new AnimationFactory() { Loading @@ -115,23 +115,19 @@ public final class FallbackActivityInterface implements @Override public void createActivityInterface(long transitionLength) { AnimatorSet animatorSet = new AnimatorSet(); PendingAnimation pa = new PendingAnimation(transitionLength * 2); if (isAnimatingToRecents) { ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1); anim.setDuration(transitionLength).setInterpolator(LINEAR); animatorSet.play(anim); pa.addFloat(rv, CONTENT_ALPHA, 0, 1, LINEAR); } ObjectAnimator anim = ObjectAnimator.ofFloat(rv, ZOOM_PROGRESS, 1, 0); anim.setDuration(transitionLength).setInterpolator(LINEAR); animatorSet.play(anim); AnimatorPlaybackController controller = AnimatorPlaybackController.wrap(animatorSet, transitionLength); pa.addFloat(rv, SCALE_PROPERTY, rv.getMaxScaleForFullScreen(), 1, LINEAR); pa.addFloat(rv, FULLSCREEN_PROGRESS, 1, 0, LINEAR); AnimatorPlaybackController controller = pa.createPlaybackController(); // Since we are changing the start position of the UI, reapply the state, at the end controller.setEndAction(() -> rv.setInOverviewState(controller.getInterpolatedProgress() > 0.5)); controller.setEndAction(() -> activity.getStateManager().goToState( controller.getInterpolatedProgress() > 0.5 ? DEFAULT : BACKGROUND_APP)); callback.accept(controller); } }; Loading @@ -147,7 +143,7 @@ public final class FallbackActivityInterface implements @Nullable @Override public RecentsActivity getCreatedActivity() { return BaseRecentsActivity.ACTIVITY_TRACKER.getCreatedActivity(); return RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity(); } @Nullable Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java +48 −4 Original line number Diff line number Diff line Loading @@ -37,10 +37,12 @@ import android.os.Bundle; import android.util.ArrayMap; import android.view.MotionEvent; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.util.ObjectWrapper; import com.android.quickstep.BaseActivityInterface.AnimationFactory; import com.android.quickstep.GestureState.GestureEndTarget; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.RectFSpringAnim; Loading Loading @@ -103,6 +105,12 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa private final PointF mEndVelocityPxPerMs = new PointF(0, 0.5f); private RunningWindowAnim mFinishAnimation; // Used to control Recents components throughout the swipe gesture. private AnimatorPlaybackController mLauncherTransitionController; private boolean mHasLauncherTransitionControllerStarted; private AnimationFactory mAnimationFactory = (t) -> { }; public FallbackSwipeHandler(Context context, RecentsAnimationDeviceState deviceState, GestureState gestureState, InputConsumerController inputConsumer, boolean isLikelyToStartNewTask, boolean continuingLastGesture) { Loading Loading @@ -165,10 +173,6 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa mRecentsView = mActivity.getOverviewPanel(); mRecentsView.setOnPageTransitionEndCallback(null); linkRecentsViewScroll(); mRecentsView.setDisallowScrollToClearAll(true); mRecentsView.getClearAllButton().setVisibilityAlpha(0); mRecentsView.setZoomProgress(1); if (!mContinuingLastGesture) { if (mRunningOverHome) { mRecentsView.onGestureAnimationStart(mGestureState.getRunningTask()); Loading @@ -178,9 +182,48 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa } mStateCallback.setStateOnUiThread(STATE_RECENTS_PRESENT); mDeviceState.enableMultipleRegions(false); mAnimationFactory = mActivityInterface.prepareRecentsUI(alreadyOnHome, this::onAnimatorPlaybackControllerCreated); mAnimationFactory.createActivityInterface(mTransitionDragLength); return true; } @Override protected void initTransitionEndpoints(DeviceProfile dp) { super.initTransitionEndpoints(dp); if (canCreateNewOrUpdateExistingLauncherTransitionController()) { mAnimationFactory.createActivityInterface(mTransitionDragLength); } } private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) { mLauncherTransitionController = anim; mLauncherTransitionController.dispatchSetInterpolator(t -> t * mDragLengthFactor); mLauncherTransitionController.dispatchOnStart(); updateLauncherTransitionProgress(); } private void updateLauncherTransitionProgress() { if (mLauncherTransitionController == null || !canCreateNewOrUpdateExistingLauncherTransitionController()) { return; } // Normalize the progress to 0 to 1, as the animation controller will clamp it to that // anyway. The controller mimics the drag length factor by applying it to its interpolators. float progress = mCurrentShift.value / mDragLengthFactor; mLauncherTransitionController.setPlayFraction(progress); } /** * We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME * (it has its own animation) or if we're already animating the current controller. * @return Whether we can create the launcher controller or update its progress. */ private boolean canCreateNewOrUpdateExistingLauncherTransitionController() { return mGestureState.getEndTarget() != HOME && !mHasLauncherTransitionControllerStarted; } @Override protected boolean moveWindowWithRecentsScroll() { return mInQuickSwitchMode; Loading Loading @@ -260,6 +303,7 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa } applyWindowTransform(); updateLauncherTransitionProgress(); } @Override Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +156 −26 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ 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.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; Loading @@ -29,21 +32,32 @@ import android.animation.AnimatorSet; import android.app.ActivityOptions; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.view.View; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAnimationRunner; import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.util.ActivityTracker; import com.android.launcher3.util.ObjectWrapper; import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.fallback.FallbackRecentsStateController; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.fallback.RecentsRootView; import com.android.quickstep.fallback.RecentsState; import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityOptionsCompat; Loading @@ -51,26 +65,40 @@ import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.io.FileDescriptor; import java.io.PrintWriter; /** * A recents activity that shows the recently launched tasks as swipable task cards. * See {@link com.android.quickstep.views.RecentsView}. */ public final class RecentsActivity extends BaseRecentsActivity { public final class RecentsActivity extends StatefulActivity<RecentsState> { public static final String EXTRA_THUMBNAIL = "thumbnailData"; public static final String EXTRA_TASK_ID = "taskID"; public static final ActivityTracker<RecentsActivity> ACTIVITY_TRACKER = new ActivityTracker<>(); private Handler mUiHandler = new Handler(Looper.getMainLooper()); private RecentsRootView mRecentsRootView; private FallbackRecentsView mFallbackRecentsView; private OverviewActionsView mActionsView; @Override private Configuration mOldConfig; private StateManager<RecentsState> mStateManager; /** * Init drag layer and overview panel views. */ protected void initViews() { setContentView(R.layout.fallback_recents_activity); mRecentsRootView = findViewById(R.id.drag_layer); mFallbackRecentsView = findViewById(R.id.overview_panel); mActionsView = findViewById(R.id.overview_actions_view); mRecentsRootView.recreateControllers(); mFallbackRecentsView.init(findViewById(R.id.overview_actions_view)); mFallbackRecentsView.init(mActionsView); } @Override Loading Loading @@ -103,25 +131,38 @@ public final class RecentsActivity extends BaseRecentsActivity { intent.removeExtra(EXTRA_TASK_ID); intent.removeExtra(EXTRA_THUMBNAIL); super.onNewIntent(intent); ACTIVITY_TRACKER.handleNewIntent(this, intent); } @Override /** * Logic for when device configuration changes (rotation, screen size change, multi-window, * etc.) */ protected void onHandleConfigChanged() { super.onHandleConfigChanged(); mRecentsRootView.recreateControllers(); } mUserEventDispatcher = null; initDeviceProfile(); @Override protected void reapplyUi() { mRecentsRootView.dispatchInsets(); AbstractFloatingView.closeOpenViews(this, true, AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE); dispatchDeviceProfileChanged(); reapplyUi(); mRecentsRootView.recreateControllers(); } @Override /** * Generate the device profile to use in this activity. * @return device profile */ protected DeviceProfile createDeviceProfile() { DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); DeviceProfile dp1 = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); // In case we are reusing IDP, create a copy so that we don't conflict with Launcher // activity. return (mRecentsRootView != null) && isInMultiWindowMode() ? dp.getMultiWindowProfile(this, getMultiWindowDisplaySize()) : super.createDeviceProfile(); : dp1.copy(this); } @Override Loading @@ -139,6 +180,10 @@ public final class RecentsActivity extends BaseRecentsActivity { return (T) mFallbackRecentsView; } public OverviewActionsView getActionsView() { return mActionsView; } @Override public void returnToHomescreen() { super.returnToHomescreen(); Loading @@ -160,12 +205,7 @@ public final class RecentsActivity extends BaseRecentsActivity { RemoteAnimationTargetCompat[] wallpaperTargets, AnimationResult result) { AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets, wallpaperTargets); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mFallbackRecentsView.resetViewUI(); } }); anim.addListener(resetStateListener()); result.setAnimation(anim, RecentsActivity.this); } }; Loading Loading @@ -193,12 +233,7 @@ public final class RecentsActivity extends BaseRecentsActivity { .createAdjacentPageAnimForTaskLaunch(taskView); adjacentAnimation.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR); adjacentAnimation.setDuration(RECENTS_LAUNCH_DURATION); adjacentAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mFallbackRecentsView.resetTaskVisuals(); } }); adjacentAnimation.addListener(resetStateListener()); target.play(adjacentAnimation); } return target; Loading @@ -210,13 +245,14 @@ public final class RecentsActivity extends BaseRecentsActivity { // onActivityStart callback. mFallbackRecentsView.setContentAlpha(1); super.onStart(); mFallbackRecentsView.resetTaskVisuals(); } @Override protected void onStop() { super.onStop(); mFallbackRecentsView.reset(); // Workaround for b/78520668, explicitly trim memory once UI is hidden onTrimMemory(TRIM_MEMORY_UI_HIDDEN); } @Override Loading @@ -228,4 +264,98 @@ public final class RecentsActivity extends BaseRecentsActivity { public void onTaskLaunched() { mFallbackRecentsView.resetTaskVisuals(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mStateManager = new StateManager<>(this, RecentsState.DEFAULT); mOldConfig = new Configuration(getResources().getConfiguration()); initDeviceProfile(); initViews(); getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW, Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)); ACTIVITY_TRACKER.handleCreate(this); } @Override public void onConfigurationChanged(Configuration newConfig) { int diff = newConfig.diff(mOldConfig); if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) { onHandleConfigChanged(); } mOldConfig.setTo(newConfig); super.onConfigurationChanged(newConfig); } /** * Initialize/update the device profile. */ private void initDeviceProfile() { mDeviceProfile = createDeviceProfile(); onDeviceProfileInitiated(); } @Override public void onEnterAnimationComplete() { super.onEnterAnimationComplete(); // After the transition to home, enable the high-res thumbnail loader if it wasn't enabled // as a part of quickstep, so that high-res thumbnails can load the next time we enter // overview RecentsModel.INSTANCE.get(this).getThumbnailCache() .getHighResLoadingState().setVisible(true); } @Override public void onTrimMemory(int level) { super.onTrimMemory(level); RecentsModel.INSTANCE.get(this).onTrimMemory(level); } @Override protected void onDestroy() { super.onDestroy(); ACTIVITY_TRACKER.onActivityDestroyed(this); } @Override public void onBackPressed() { // TODO: Launch the task we came from startHome(); } public void startHome() { startActivity(new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_HOME) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } @Override protected StateHandler<RecentsState>[] createStateHandlers() { return new StateHandler[] { new FallbackRecentsStateController(this) }; } @Override public StateManager<RecentsState> getStateManager() { return mStateManager; } @Override public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { super.dump(prefix, fd, writer, args); writer.println(prefix + "Misc:"); dumpMisc(prefix + "\t", writer); } private AnimatorListenerAdapter resetStateListener() { return new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mFallbackRecentsView.resetTaskVisuals(); mStateManager.reapplyState(); } }; } }