81db038977
Bug: 387471509 Test: EnterDeskTopViaMenuOfLiveOverviewTaskTest, EnterDeskTopViaMenuOfStaticOverviewTaskTest Flag: EXEMPT bug fix Change-Id: If1d6604b7e331cc4bdb8a3fac3804b6772e8be7a
154 lines
5.6 KiB
Kotlin
154 lines
5.6 KiB
Kotlin
/*
|
|
* 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.launcher3.desktop
|
|
|
|
import android.app.IApplicationThread
|
|
import android.os.IBinder
|
|
import android.os.RemoteException
|
|
import android.util.Log
|
|
import android.view.SurfaceControl
|
|
import android.view.WindowManager.TRANSIT_TO_FRONT
|
|
import android.window.IRemoteTransitionFinishedCallback
|
|
import android.window.RemoteTransition
|
|
import android.window.RemoteTransitionStub
|
|
import android.window.TransitionInfo
|
|
import com.android.launcher3.statehandlers.DepthController
|
|
import com.android.launcher3.statemanager.StateManager
|
|
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
|
|
import com.android.quickstep.SystemUiProxy
|
|
import com.android.quickstep.TaskViewUtils
|
|
import com.android.quickstep.views.DesktopTaskView
|
|
import com.android.quickstep.views.TaskContainer
|
|
import com.android.quickstep.views.TaskView
|
|
import com.android.window.flags.Flags
|
|
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource
|
|
import java.util.function.Consumer
|
|
|
|
/** Manage recents related operations with desktop tasks */
|
|
class DesktopRecentsTransitionController(
|
|
private val stateManager: StateManager<*, *>,
|
|
private val systemUiProxy: SystemUiProxy,
|
|
private val appThread: IApplicationThread,
|
|
private val depthController: DepthController?,
|
|
) {
|
|
|
|
/** Launch desktop tasks from recents view */
|
|
fun launchDesktopFromRecents(
|
|
desktopTaskView: DesktopTaskView,
|
|
animated: Boolean,
|
|
callback: Consumer<Boolean>? = null,
|
|
) {
|
|
val animRunner =
|
|
RemoteDesktopLaunchTransitionRunner(
|
|
desktopTaskView,
|
|
animated,
|
|
stateManager,
|
|
depthController,
|
|
callback,
|
|
)
|
|
val transition = RemoteTransition(animRunner, appThread, "RecentsToDesktop")
|
|
systemUiProxy.showDesktopApps(desktopTaskView.display.displayId, transition)
|
|
}
|
|
|
|
/** Launch desktop tasks from recents view */
|
|
fun moveToDesktop(
|
|
taskContainer: TaskContainer,
|
|
transitionSource: DesktopModeTransitionSource,
|
|
successCallback: Runnable,
|
|
) {
|
|
systemUiProxy.moveToDesktop(
|
|
taskContainer.task.key.id,
|
|
transitionSource,
|
|
/* transition = */ null,
|
|
successCallback,
|
|
)
|
|
}
|
|
|
|
/** Move task to external display from recents view */
|
|
fun moveToExternalDisplay(taskId: Int) {
|
|
systemUiProxy.moveToExternalDisplay(taskId)
|
|
}
|
|
|
|
private class RemoteDesktopLaunchTransitionRunner(
|
|
private val taskView: TaskView,
|
|
private val animated: Boolean,
|
|
private val stateManager: StateManager<*, *>,
|
|
private val depthController: DepthController?,
|
|
private val successCallback: Consumer<Boolean>?,
|
|
) : RemoteTransitionStub() {
|
|
|
|
override fun startAnimation(
|
|
token: IBinder,
|
|
info: TransitionInfo,
|
|
t: SurfaceControl.Transaction,
|
|
finishCallback: IRemoteTransitionFinishedCallback,
|
|
) {
|
|
val errorHandlingFinishCallback = Runnable {
|
|
try {
|
|
finishCallback.onTransitionFinished(null /* wct */, null /* sct */)
|
|
} catch (e: RemoteException) {
|
|
Log.e(TAG, "Failed to call finish callback for desktop recents animation", e)
|
|
}
|
|
}
|
|
|
|
if (Flags.enableDesktopWindowingPersistence()) {
|
|
handleAnimationAfterReboot(info)
|
|
}
|
|
MAIN_EXECUTOR.execute {
|
|
val animator =
|
|
TaskViewUtils.composeRecentsDesktopLaunchAnimator(
|
|
taskView,
|
|
stateManager,
|
|
depthController,
|
|
info,
|
|
t,
|
|
) {
|
|
errorHandlingFinishCallback.run()
|
|
successCallback?.accept(true)
|
|
}
|
|
if (!animated) {
|
|
animator.setDuration(0)
|
|
}
|
|
animator.start()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Upon reboot the start bounds of a task is set to fullscreen with the recents transition.
|
|
* Check this case and set the start bounds to the end bounds so that the window doesn't
|
|
* jump from start bounds to end bounds during the animation. Tasks in desktop cannot
|
|
* normally have top bound as 0 due to status bar so this is a good indicator to identify
|
|
* reboot case.
|
|
*/
|
|
private fun handleAnimationAfterReboot(info: TransitionInfo) {
|
|
info.changes.forEach { change ->
|
|
if (
|
|
change.mode == TRANSIT_TO_FRONT &&
|
|
change.taskInfo?.isFreeform == true &&
|
|
change.startAbsBounds.top == 0 &&
|
|
change.startAbsBounds.left == 0
|
|
) {
|
|
change.setStartAbsBounds(change.endAbsBounds)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
companion object {
|
|
const val TAG = "DesktopRecentsTransitionController"
|
|
}
|
|
}
|