Loading quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java +17 −7 Original line number Diff line number Diff line Loading @@ -15,20 +15,26 @@ */ package com.android.launcher3.taskbar; import static android.window.SplashScreen.SPLASH_SCREEN_STYLE_UNDEFINED; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import android.animation.Animator; import android.app.ActivityOptions; import android.view.KeyEvent; import android.view.View; import android.window.RemoteTransition; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; import com.android.launcher3.taskbar.overlay.TaskbarOverlayDragLayer; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.util.GroupTask; import com.android.quickstep.util.SlideInRemoteTransition; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; Loading Loading @@ -142,19 +148,23 @@ public class KeyboardQuickSwitchViewController { return -1; } RemoteTransition remoteTransition = new RemoteTransition(new SlideInRemoteTransition( Utilities.isRtl(mControllers.taskbarActivityContext.getResources()))); if (mOnDesktop) { UI_HELPER_EXECUTOR.execute(() -> SystemUiProxy.INSTANCE.get(mKeyboardQuickSwitchView.getContext()) .showDesktopApp(task.task1.key.id)); } else if (task.task2 == null) { UI_HELPER_EXECUTOR.execute(() -> UI_HELPER_EXECUTOR.execute(() -> { ActivityOptions activityOptions = mControllers.taskbarActivityContext .makeDefaultActivityOptions(SPLASH_SCREEN_STYLE_UNDEFINED).options; activityOptions.setRemoteTransition(remoteTransition); ActivityManagerWrapper.getInstance().startActivityFromRecents( task.task1.key, mControllers.taskbarActivityContext.getActivityLaunchOptions( taskView == null ? mKeyboardQuickSwitchView : taskView, null) .options)); task.task1.key, activityOptions); }); } else { mControllers.uiController.launchSplitTasks(task); mControllers.uiController.launchSplitTasks(task, remoteTransition); } return -1; } Loading quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +4 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.os.RemoteException; import android.util.Log; import android.view.TaskTransitionSpec; import android.view.WindowManagerGlobal; import android.window.RemoteTransition; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading Loading @@ -390,8 +391,9 @@ public class LauncherTaskbarUIController extends TaskbarUIController { } @Override public void launchSplitTasks(@NonNull GroupTask groupTask) { mLauncher.launchSplitTasks(groupTask); public void launchSplitTasks( @NonNull GroupTask groupTask, @Nullable RemoteTransition remoteTransition) { mLauncher.launchSplitTasks(groupTask, remoteTransition); } @Override Loading quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +3 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.Intent; import android.graphics.drawable.BitmapDrawable; import android.view.MotionEvent; import android.view.View; import android.window.RemoteTransition; import androidx.annotation.CallSuper; import androidx.annotation.NonNull; Loading Loading @@ -302,7 +303,8 @@ public class TaskbarUIController { /** * Launches the given task in split-screen. */ public void launchSplitTasks(@NonNull GroupTask groupTask) { } public void launchSplitTasks( @NonNull GroupTask groupTask, @Nullable RemoteTransition remoteTransition) { } /** * Returns the matching view (if any) in the taskbar. Loading quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +5 −2 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ import android.widget.TextClock; import android.window.BackEvent; import android.window.OnBackAnimationCallback; import android.window.OnBackInvokedDispatcher; import android.window.RemoteTransition; import android.window.SplashScreen; import androidx.annotation.BinderThread; Loading Loading @@ -1271,7 +1272,8 @@ public class QuickstepLauncher extends Launcher { /** * Launches the given {@link GroupTask} in splitscreen. */ public void launchSplitTasks(@NonNull GroupTask groupTask) { public void launchSplitTasks( @NonNull GroupTask groupTask, @Nullable RemoteTransition remoteTransition) { // Top/left and bottom/right tasks respectively. Task task1 = groupTask.task1; // task2 should never be null when calling this method. Allow a crash to catch invalid calls Loading @@ -1285,7 +1287,8 @@ public class QuickstepLauncher extends Launcher { /* freezeTaskList= */ false, groupTask.mSplitBounds == null ? SNAP_TO_50_50 : groupTask.mSplitBounds.snapPosition); : groupTask.mSplitBounds.snapPosition, remoteTransition); } /** Loading quickstep/src/com/android/quickstep/util/SlideInRemoteTransition.kt 0 → 100644 +115 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.quickstep.util import android.animation.ValueAnimator import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.graphics.Rect import android.os.IBinder import android.os.RemoteException import android.view.SurfaceControl import android.view.SurfaceControl.Transaction import android.window.IRemoteTransition import android.window.IRemoteTransitionFinishedCallback import android.window.TransitionInfo import com.android.launcher3.anim.AnimatorListeners.forEndCallback import com.android.launcher3.util.Executors import com.android.wm.shell.util.TransitionUtil /** Remote animation which slides the opening targets in and the closing targets out */ class SlideInRemoteTransition(val isRtl: Boolean) : IRemoteTransition.Stub() { override fun mergeAnimation( iBinder: IBinder, transitionInfo: TransitionInfo, transaction: Transaction, mergeTarget: IBinder, finishCB: IRemoteTransitionFinishedCallback ) { try { finishCB.onTransitionFinished(null, Transaction()) } catch (e: RemoteException) { // Ignore } } override fun startAnimation( transition: IBinder, info: TransitionInfo, startT: Transaction, finishCB: IRemoteTransitionFinishedCallback ) { val anim = ValueAnimator.ofFloat(0f, 1f) val closingStartBounds: HashMap<SurfaceControl, Rect> = HashMap() val openingEndBounds: HashMap<SurfaceControl, Rect> = HashMap() for (chg in info.changes) { val leash = chg.leash startT.show(leash) val taskInfo = chg.taskInfo if (taskInfo?.activityType == ACTIVITY_TYPE_HOME || taskInfo?.parentTaskId != -1) { continue } if (TransitionUtil.isClosingType(chg.mode)) { closingStartBounds[leash] = chg.startAbsBounds } if (TransitionUtil.isOpeningType(chg.mode)) { openingEndBounds[leash] = chg.endAbsBounds } } startT.apply() anim.addUpdateListener { val t = Transaction() closingStartBounds.keys.forEach { // Translate the surface from its original position on-screen to off-screen on the // right (or left in RTL) val startBounds = closingStartBounds[it] val targetX = (if (isRtl) -1 else 1) * startBounds!!.right t.setPosition(it, anim.animatedValue as Float * targetX, 0f) } openingEndBounds.keys.forEach { // Set the alpha in the update listener to prevent one visible frame at the // beginning t.setAlpha(it, 1f) // Translate the surface from off-screen on the left (or left in RTL) to its final // position on-screen val endBounds = openingEndBounds[it] val targetX = (if (isRtl) -1 else 1) * endBounds!!.right t.setPosition(it, (1f - anim.animatedValue as Float) * -targetX, 0f) } t.apply() } anim.addListener( forEndCallback( Runnable { val t = Transaction() try { finishCB.onTransitionFinished(null, t) } catch (e: RemoteException) { // Ignore } } ) ) Executors.MAIN_EXECUTOR.execute { anim.start() } } override fun onTransitionConsumed(transition: IBinder?, aborted: Boolean) {} } Loading
quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java +17 −7 Original line number Diff line number Diff line Loading @@ -15,20 +15,26 @@ */ package com.android.launcher3.taskbar; import static android.window.SplashScreen.SPLASH_SCREEN_STYLE_UNDEFINED; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import android.animation.Animator; import android.app.ActivityOptions; import android.view.KeyEvent; import android.view.View; import android.window.RemoteTransition; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; import com.android.launcher3.taskbar.overlay.TaskbarOverlayDragLayer; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.util.GroupTask; import com.android.quickstep.util.SlideInRemoteTransition; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; Loading Loading @@ -142,19 +148,23 @@ public class KeyboardQuickSwitchViewController { return -1; } RemoteTransition remoteTransition = new RemoteTransition(new SlideInRemoteTransition( Utilities.isRtl(mControllers.taskbarActivityContext.getResources()))); if (mOnDesktop) { UI_HELPER_EXECUTOR.execute(() -> SystemUiProxy.INSTANCE.get(mKeyboardQuickSwitchView.getContext()) .showDesktopApp(task.task1.key.id)); } else if (task.task2 == null) { UI_HELPER_EXECUTOR.execute(() -> UI_HELPER_EXECUTOR.execute(() -> { ActivityOptions activityOptions = mControllers.taskbarActivityContext .makeDefaultActivityOptions(SPLASH_SCREEN_STYLE_UNDEFINED).options; activityOptions.setRemoteTransition(remoteTransition); ActivityManagerWrapper.getInstance().startActivityFromRecents( task.task1.key, mControllers.taskbarActivityContext.getActivityLaunchOptions( taskView == null ? mKeyboardQuickSwitchView : taskView, null) .options)); task.task1.key, activityOptions); }); } else { mControllers.uiController.launchSplitTasks(task); mControllers.uiController.launchSplitTasks(task, remoteTransition); } return -1; } Loading
quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +4 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.os.RemoteException; import android.util.Log; import android.view.TaskTransitionSpec; import android.view.WindowManagerGlobal; import android.window.RemoteTransition; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading Loading @@ -390,8 +391,9 @@ public class LauncherTaskbarUIController extends TaskbarUIController { } @Override public void launchSplitTasks(@NonNull GroupTask groupTask) { mLauncher.launchSplitTasks(groupTask); public void launchSplitTasks( @NonNull GroupTask groupTask, @Nullable RemoteTransition remoteTransition) { mLauncher.launchSplitTasks(groupTask, remoteTransition); } @Override Loading
quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +3 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.Intent; import android.graphics.drawable.BitmapDrawable; import android.view.MotionEvent; import android.view.View; import android.window.RemoteTransition; import androidx.annotation.CallSuper; import androidx.annotation.NonNull; Loading Loading @@ -302,7 +303,8 @@ public class TaskbarUIController { /** * Launches the given task in split-screen. */ public void launchSplitTasks(@NonNull GroupTask groupTask) { } public void launchSplitTasks( @NonNull GroupTask groupTask, @Nullable RemoteTransition remoteTransition) { } /** * Returns the matching view (if any) in the taskbar. Loading
quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +5 −2 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ import android.widget.TextClock; import android.window.BackEvent; import android.window.OnBackAnimationCallback; import android.window.OnBackInvokedDispatcher; import android.window.RemoteTransition; import android.window.SplashScreen; import androidx.annotation.BinderThread; Loading Loading @@ -1271,7 +1272,8 @@ public class QuickstepLauncher extends Launcher { /** * Launches the given {@link GroupTask} in splitscreen. */ public void launchSplitTasks(@NonNull GroupTask groupTask) { public void launchSplitTasks( @NonNull GroupTask groupTask, @Nullable RemoteTransition remoteTransition) { // Top/left and bottom/right tasks respectively. Task task1 = groupTask.task1; // task2 should never be null when calling this method. Allow a crash to catch invalid calls Loading @@ -1285,7 +1287,8 @@ public class QuickstepLauncher extends Launcher { /* freezeTaskList= */ false, groupTask.mSplitBounds == null ? SNAP_TO_50_50 : groupTask.mSplitBounds.snapPosition); : groupTask.mSplitBounds.snapPosition, remoteTransition); } /** Loading
quickstep/src/com/android/quickstep/util/SlideInRemoteTransition.kt 0 → 100644 +115 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.quickstep.util import android.animation.ValueAnimator import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.graphics.Rect import android.os.IBinder import android.os.RemoteException import android.view.SurfaceControl import android.view.SurfaceControl.Transaction import android.window.IRemoteTransition import android.window.IRemoteTransitionFinishedCallback import android.window.TransitionInfo import com.android.launcher3.anim.AnimatorListeners.forEndCallback import com.android.launcher3.util.Executors import com.android.wm.shell.util.TransitionUtil /** Remote animation which slides the opening targets in and the closing targets out */ class SlideInRemoteTransition(val isRtl: Boolean) : IRemoteTransition.Stub() { override fun mergeAnimation( iBinder: IBinder, transitionInfo: TransitionInfo, transaction: Transaction, mergeTarget: IBinder, finishCB: IRemoteTransitionFinishedCallback ) { try { finishCB.onTransitionFinished(null, Transaction()) } catch (e: RemoteException) { // Ignore } } override fun startAnimation( transition: IBinder, info: TransitionInfo, startT: Transaction, finishCB: IRemoteTransitionFinishedCallback ) { val anim = ValueAnimator.ofFloat(0f, 1f) val closingStartBounds: HashMap<SurfaceControl, Rect> = HashMap() val openingEndBounds: HashMap<SurfaceControl, Rect> = HashMap() for (chg in info.changes) { val leash = chg.leash startT.show(leash) val taskInfo = chg.taskInfo if (taskInfo?.activityType == ACTIVITY_TYPE_HOME || taskInfo?.parentTaskId != -1) { continue } if (TransitionUtil.isClosingType(chg.mode)) { closingStartBounds[leash] = chg.startAbsBounds } if (TransitionUtil.isOpeningType(chg.mode)) { openingEndBounds[leash] = chg.endAbsBounds } } startT.apply() anim.addUpdateListener { val t = Transaction() closingStartBounds.keys.forEach { // Translate the surface from its original position on-screen to off-screen on the // right (or left in RTL) val startBounds = closingStartBounds[it] val targetX = (if (isRtl) -1 else 1) * startBounds!!.right t.setPosition(it, anim.animatedValue as Float * targetX, 0f) } openingEndBounds.keys.forEach { // Set the alpha in the update listener to prevent one visible frame at the // beginning t.setAlpha(it, 1f) // Translate the surface from off-screen on the left (or left in RTL) to its final // position on-screen val endBounds = openingEndBounds[it] val targetX = (if (isRtl) -1 else 1) * endBounds!!.right t.setPosition(it, (1f - anim.animatedValue as Float) * -targetX, 0f) } t.apply() } anim.addListener( forEndCallback( Runnable { val t = Transaction() try { finishCB.onTransitionFinished(null, t) } catch (e: RemoteException) { // Ignore } } ) ) Executors.MAIN_EXECUTOR.execute { anim.start() } } override fun onTransitionConsumed(transition: IBinder?, aborted: Boolean) {} }