Loading quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +1 −1 Original line number Diff line number Diff line Loading @@ -349,7 +349,7 @@ public abstract class BaseQuickstepLauncher extends Launcher mActionsView = findViewById(R.id.overview_actions_view); RecentsView overviewPanel = (RecentsView) getOverviewPanel(); SplitSelectStateController controller = new SplitSelectStateController(SystemUiProxy.INSTANCE.get(this)); new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this)); overviewPanel.init(mActionsView, controller); mActionsView.setDp(getDeviceProfile()); mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this)); Loading quickstep/src/com/android/quickstep/RecentsActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -122,7 +122,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> { SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f); SplitSelectStateController controller = new SplitSelectStateController(SystemUiProxy.INSTANCE.get(this)); new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this)); mDragLayer.recreateControllers(); mFallbackRecentsView.init(mActionsView, controller); } Loading quickstep/src/com/android/quickstep/TaskViewUtils.java +55 −21 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLAT import static com.android.launcher3.anim.Interpolators.clampToProgress; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.statehandlers.DepthController.DEPTH; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; Loading @@ -42,6 +43,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -79,6 +81,8 @@ import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import java.util.ArrayList; /** * Utility class for helpful methods related to {@link TaskView} objects and their tasks. */ Loading Loading @@ -427,35 +431,65 @@ public final class TaskViewUtils { @NonNull RemoteAnimationTargetCompat[] wallpaperTargets, @NonNull RemoteAnimationTargetCompat[] nonAppTargets, @NonNull Runnable finishCallback) { final ArrayList<SurfaceControl> openingTargets = new ArrayList<>(); final ArrayList<SurfaceControl> closingTargets = new ArrayList<>(); final int[] splitRoots = new int[2]; for (int i = 0; i < appTargets.length; ++i) { final int taskId = appTargets[i].taskInfo != null ? appTargets[i].taskInfo.taskId : -1; final int mode = appTargets[i].mode; if (taskId == initialTask.key.id || taskId == secondTask.key.id) { if (mode != MODE_OPENING) { throw new IllegalStateException( "Expected task to be opening, but it is " + mode); for (RemoteAnimationTargetCompat appTarget : appTargets) { final int taskId = appTarget.taskInfo != null ? appTarget.taskInfo.taskId : -1; final int mode = appTarget.mode; final SurfaceControl leash = appTarget.leash.getSurfaceControl(); if (leash == null) { continue; } splitRoots[taskId == initialTask.key.id ? 0 : 1] = i; if (mode == MODE_OPENING) { openingTargets.add(leash); } else if (taskId == initialTask.key.id || taskId == secondTask.key.id) { throw new IllegalStateException("Expected task to be opening, but it is " + mode); } else if (mode == MODE_CLOSING) { closingTargets.add(leash); } } SurfaceControl.Transaction t = new SurfaceControl.Transaction(); // This is where we should animate the split roots. For now, though, just make them visible. for (int i = 0; i < 2; ++i) { t.show(appTargets[splitRoots[i]].leash.getSurfaceControl()); t.setAlpha(appTargets[splitRoots[i]].leash.getSurfaceControl(), 1.f); for (int i = 0; i < nonAppTargets.length; ++i) { final SurfaceControl leash = appTargets[i].leash.getSurfaceControl(); if (nonAppTargets[i].windowType == TYPE_DOCK_DIVIDER && leash != null) { openingTargets.add(leash); } } // This contains the initial state (before animation), so apply this at the beginning of // the animation. final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f); animator.addUpdateListener(valueAnimator -> { float progress = valueAnimator.getAnimatedFraction(); for (SurfaceControl leash: openingTargets) { t.setAlpha(leash, progress); } for (SurfaceControl leash: closingTargets) { t.setAlpha(leash, 1 - progress); } t.apply(); }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { for (SurfaceControl leash: openingTargets) { t.show(leash).setAlpha(leash, 0.0f); } t.apply(); } // Once there is an animation, this should be called AFTER the animation completes. @Override public void onAnimationEnd(Animator animation) { for (SurfaceControl leash: closingTargets) { t.hide(leash); } super.onAnimationEnd(animation); finishCallback.run(); } }); animator.start(); } public static void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v, @NonNull RemoteAnimationTargetCompat[] appTargets, Loading quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +23 −13 Original line number Diff line number Diff line Loading @@ -16,17 +16,20 @@ package com.android.quickstep.util; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; import android.app.ActivityThread; import android.graphics.Rect; import android.os.Handler; import android.os.IBinder; import android.view.RemoteAnimationAdapter; import android.view.SurfaceControl; import android.window.TransitionInfo; import com.android.launcher3.Utilities; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.StagePosition; import com.android.quickstep.SystemUiProxy; Loading @@ -47,13 +50,15 @@ import java.util.function.Consumer; */ public class SplitSelectStateController { private final Handler mHandler; private final SystemUiProxy mSystemUiProxy; private @StagePosition int mStagePosition; private Task mInitialTask; private Task mSecondTask; private Rect mInitialBounds; public SplitSelectStateController(SystemUiProxy systemUiProxy) { public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) { mHandler = handler; mSystemUiProxy = systemUiProxy; } Loading @@ -70,9 +75,9 @@ public class SplitSelectStateController { /** * To be called after second task selected */ public void setSecondTaskId(Task taskView) { public void setSecondTaskId(Task taskView, Consumer<Boolean> callback) { mSecondTask = taskView; launchTasks(mInitialTask, mSecondTask, mStagePosition, null /*callback*/); launchTasks(mInitialTask, mSecondTask, mStagePosition, callback); } /** Loading Loading @@ -151,22 +156,27 @@ public class SplitSelectStateController { public void onAnimationStart(int transit, RemoteAnimationTargetCompat[] apps, RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps, Runnable finishedCallback) { TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTask, postAsyncCallback(mHandler, () -> TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTask, mSecondTask, apps, wallpapers, nonApps, () -> { finishedCallback.run(); if (mSuccessCallback != null) { mSuccessCallback.accept(true); } }); })); // After successful launch, call resetState resetState(); } @Override public void onAnimationCancelled() { postAsyncCallback(mHandler, () -> { if (mSuccessCallback != null) { mSuccessCallback.accept(false); } }); resetState(); } } Loading quickstep/src/com/android/quickstep/views/RecentsView.java +3 −4 Original line number Diff line number Diff line Loading @@ -3836,10 +3836,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds, secondTaskEndingBounds, taskView.getThumbnail(), true /*fadeWithThumbnail*/); pendingAnimation.addEndListener(aBoolean -> { mSplitSelectStateController.setSecondTaskId(taskView.getTask()); resetFromSplitSelectionState(); }); pendingAnimation.addEndListener(aBoolean -> mSplitSelectStateController.setSecondTaskId(taskView.getTask(), aBoolean1 -> RecentsView.this.resetFromSplitSelectionState())); mSecondSplitHiddenTaskView = taskView; taskView.setVisibility(INVISIBLE); pendingAnimation.buildAnim().start(); Loading Loading
quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +1 −1 Original line number Diff line number Diff line Loading @@ -349,7 +349,7 @@ public abstract class BaseQuickstepLauncher extends Launcher mActionsView = findViewById(R.id.overview_actions_view); RecentsView overviewPanel = (RecentsView) getOverviewPanel(); SplitSelectStateController controller = new SplitSelectStateController(SystemUiProxy.INSTANCE.get(this)); new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this)); overviewPanel.init(mActionsView, controller); mActionsView.setDp(getDeviceProfile()); mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this)); Loading
quickstep/src/com/android/quickstep/RecentsActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -122,7 +122,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> { SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f); SplitSelectStateController controller = new SplitSelectStateController(SystemUiProxy.INSTANCE.get(this)); new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this)); mDragLayer.recreateControllers(); mFallbackRecentsView.init(mActionsView, controller); } Loading
quickstep/src/com/android/quickstep/TaskViewUtils.java +55 −21 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLAT import static com.android.launcher3.anim.Interpolators.clampToProgress; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.statehandlers.DepthController.DEPTH; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; Loading @@ -42,6 +43,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -79,6 +81,8 @@ import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import java.util.ArrayList; /** * Utility class for helpful methods related to {@link TaskView} objects and their tasks. */ Loading Loading @@ -427,35 +431,65 @@ public final class TaskViewUtils { @NonNull RemoteAnimationTargetCompat[] wallpaperTargets, @NonNull RemoteAnimationTargetCompat[] nonAppTargets, @NonNull Runnable finishCallback) { final ArrayList<SurfaceControl> openingTargets = new ArrayList<>(); final ArrayList<SurfaceControl> closingTargets = new ArrayList<>(); final int[] splitRoots = new int[2]; for (int i = 0; i < appTargets.length; ++i) { final int taskId = appTargets[i].taskInfo != null ? appTargets[i].taskInfo.taskId : -1; final int mode = appTargets[i].mode; if (taskId == initialTask.key.id || taskId == secondTask.key.id) { if (mode != MODE_OPENING) { throw new IllegalStateException( "Expected task to be opening, but it is " + mode); for (RemoteAnimationTargetCompat appTarget : appTargets) { final int taskId = appTarget.taskInfo != null ? appTarget.taskInfo.taskId : -1; final int mode = appTarget.mode; final SurfaceControl leash = appTarget.leash.getSurfaceControl(); if (leash == null) { continue; } splitRoots[taskId == initialTask.key.id ? 0 : 1] = i; if (mode == MODE_OPENING) { openingTargets.add(leash); } else if (taskId == initialTask.key.id || taskId == secondTask.key.id) { throw new IllegalStateException("Expected task to be opening, but it is " + mode); } else if (mode == MODE_CLOSING) { closingTargets.add(leash); } } SurfaceControl.Transaction t = new SurfaceControl.Transaction(); // This is where we should animate the split roots. For now, though, just make them visible. for (int i = 0; i < 2; ++i) { t.show(appTargets[splitRoots[i]].leash.getSurfaceControl()); t.setAlpha(appTargets[splitRoots[i]].leash.getSurfaceControl(), 1.f); for (int i = 0; i < nonAppTargets.length; ++i) { final SurfaceControl leash = appTargets[i].leash.getSurfaceControl(); if (nonAppTargets[i].windowType == TYPE_DOCK_DIVIDER && leash != null) { openingTargets.add(leash); } } // This contains the initial state (before animation), so apply this at the beginning of // the animation. final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f); animator.addUpdateListener(valueAnimator -> { float progress = valueAnimator.getAnimatedFraction(); for (SurfaceControl leash: openingTargets) { t.setAlpha(leash, progress); } for (SurfaceControl leash: closingTargets) { t.setAlpha(leash, 1 - progress); } t.apply(); }); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { for (SurfaceControl leash: openingTargets) { t.show(leash).setAlpha(leash, 0.0f); } t.apply(); } // Once there is an animation, this should be called AFTER the animation completes. @Override public void onAnimationEnd(Animator animation) { for (SurfaceControl leash: closingTargets) { t.hide(leash); } super.onAnimationEnd(animation); finishCallback.run(); } }); animator.start(); } public static void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v, @NonNull RemoteAnimationTargetCompat[] appTargets, Loading
quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +23 −13 Original line number Diff line number Diff line Loading @@ -16,17 +16,20 @@ package com.android.quickstep.util; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; import android.app.ActivityThread; import android.graphics.Rect; import android.os.Handler; import android.os.IBinder; import android.view.RemoteAnimationAdapter; import android.view.SurfaceControl; import android.window.TransitionInfo; import com.android.launcher3.Utilities; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.StagePosition; import com.android.quickstep.SystemUiProxy; Loading @@ -47,13 +50,15 @@ import java.util.function.Consumer; */ public class SplitSelectStateController { private final Handler mHandler; private final SystemUiProxy mSystemUiProxy; private @StagePosition int mStagePosition; private Task mInitialTask; private Task mSecondTask; private Rect mInitialBounds; public SplitSelectStateController(SystemUiProxy systemUiProxy) { public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) { mHandler = handler; mSystemUiProxy = systemUiProxy; } Loading @@ -70,9 +75,9 @@ public class SplitSelectStateController { /** * To be called after second task selected */ public void setSecondTaskId(Task taskView) { public void setSecondTaskId(Task taskView, Consumer<Boolean> callback) { mSecondTask = taskView; launchTasks(mInitialTask, mSecondTask, mStagePosition, null /*callback*/); launchTasks(mInitialTask, mSecondTask, mStagePosition, callback); } /** Loading Loading @@ -151,22 +156,27 @@ public class SplitSelectStateController { public void onAnimationStart(int transit, RemoteAnimationTargetCompat[] apps, RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps, Runnable finishedCallback) { TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTask, postAsyncCallback(mHandler, () -> TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTask, mSecondTask, apps, wallpapers, nonApps, () -> { finishedCallback.run(); if (mSuccessCallback != null) { mSuccessCallback.accept(true); } }); })); // After successful launch, call resetState resetState(); } @Override public void onAnimationCancelled() { postAsyncCallback(mHandler, () -> { if (mSuccessCallback != null) { mSuccessCallback.accept(false); } }); resetState(); } } Loading
quickstep/src/com/android/quickstep/views/RecentsView.java +3 −4 Original line number Diff line number Diff line Loading @@ -3836,10 +3836,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds, secondTaskEndingBounds, taskView.getThumbnail(), true /*fadeWithThumbnail*/); pendingAnimation.addEndListener(aBoolean -> { mSplitSelectStateController.setSecondTaskId(taskView.getTask()); resetFromSplitSelectionState(); }); pendingAnimation.addEndListener(aBoolean -> mSplitSelectStateController.setSecondTaskId(taskView.getTask(), aBoolean1 -> RecentsView.this.resetFromSplitSelectionState())); mSecondSplitHiddenTaskView = taskView; taskView.setVisibility(INVISIBLE); pendingAnimation.buildAnim().start(); Loading