1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.launcher3.desktop 17 18 import android.app.IApplicationThread 19 import android.os.IBinder 20 import android.os.RemoteException 21 import android.util.Log 22 import android.view.SurfaceControl 23 import android.window.IRemoteTransitionFinishedCallback 24 import android.window.RemoteTransition 25 import android.window.RemoteTransitionStub 26 import android.window.TransitionInfo 27 import com.android.launcher3.statehandlers.DepthController 28 import com.android.launcher3.statemanager.StateManager 29 import com.android.launcher3.util.Executors.MAIN_EXECUTOR 30 import com.android.quickstep.SystemUiProxy 31 import com.android.quickstep.TaskViewUtils 32 import com.android.quickstep.views.DesktopTaskView 33 import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource 34 import java.util.function.Consumer 35 36 /** Manage recents related operations with desktop tasks */ 37 class DesktopRecentsTransitionController( 38 private val stateManager: StateManager<*, *>, 39 private val systemUiProxy: SystemUiProxy, 40 private val appThread: IApplicationThread, 41 private val depthController: DepthController? 42 ) { 43 44 /** Launch desktop tasks from recents view */ launchDesktopFromRecentsnull45 fun launchDesktopFromRecents( 46 desktopTaskView: DesktopTaskView, 47 callback: Consumer<Boolean>? = null 48 ) { 49 val animRunner = 50 RemoteDesktopLaunchTransitionRunner( 51 desktopTaskView, 52 stateManager, 53 depthController, 54 callback 55 ) 56 val transition = RemoteTransition(animRunner, appThread, "RecentsToDesktop") 57 systemUiProxy.showDesktopApps(desktopTaskView.display.displayId, transition) 58 } 59 60 /** Launch desktop tasks from recents view */ moveToDesktopnull61 fun moveToDesktop(taskId: Int, transitionSource: DesktopModeTransitionSource) { 62 systemUiProxy.moveToDesktop(taskId, transitionSource) 63 } 64 65 private class RemoteDesktopLaunchTransitionRunner( 66 private val desktopTaskView: DesktopTaskView, 67 private val stateManager: StateManager<*, *>, 68 private val depthController: DepthController?, 69 private val successCallback: Consumer<Boolean>? 70 ) : RemoteTransitionStub() { 71 startAnimationnull72 override fun startAnimation( 73 token: IBinder, 74 info: TransitionInfo, 75 t: SurfaceControl.Transaction, 76 finishCallback: IRemoteTransitionFinishedCallback 77 ) { 78 val errorHandlingFinishCallback = Runnable { 79 try { 80 finishCallback.onTransitionFinished(null /* wct */, null /* sct */) 81 } catch (e: RemoteException) { 82 Log.e(TAG, "Failed to call finish callback for desktop recents animation", e) 83 } 84 } 85 86 MAIN_EXECUTOR.execute { 87 TaskViewUtils.composeRecentsDesktopLaunchAnimator( 88 desktopTaskView, 89 stateManager, 90 depthController, 91 info, 92 t 93 ) { 94 errorHandlingFinishCallback.run() 95 successCallback?.accept(true) 96 } 97 } 98 } 99 } 100 101 companion object { 102 const val TAG = "DesktopRecentsTransitionController" 103 } 104 } 105