Refactoring OverviewCommandHelper (2/3)
This CL should not affect the behavior of OverviewCommandHelper.
- It splits executeCommand into smaller functions
- Rearrange public/private functions
- Adds extra logs.
Bug: 352046797
Bug: 351122926
Flag: EXEMPT bugfix.
Test: Manual.
Change-Id: I283f179794af812973a559db6291febe19e3c6d7
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
index 56153a9..5e29139 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
@@ -73,48 +73,6 @@
private val visibleRecentsView: RecentsView<*, *>?
get() = activityInterface.getVisibleRecentsView<RecentsView<*, *>>()
- /** Called when the command finishes execution. */
- private fun onCommandFinished(command: CommandInfo) {
- command.status = CommandStatus.COMPLETED
- if (commandQueue.first() !== command) {
- Log.d(
- TAG,
- "next task not scheduled. First pending command type " +
- "is ${commandQueue.first()} - command type is: $command"
- )
- return
- }
-
- Log.d(TAG, "command executed successfully! $command")
- commandQueue.remove(command)
- executeNext()
- }
-
- /**
- * Executes the next command from the queue. If the command finishes immediately (returns true),
- * it continues to execute the next command, until the queue is empty of a command defer's its
- * completion (returns false).
- */
- @UiThread
- private fun executeNext() {
- val command: CommandInfo =
- commandQueue.firstOrNull()
- ?: run {
- Log.d(TAG, "no pending commands to be executed.")
- return
- }
-
- Log.d(TAG, "executing command: $command")
- val result = executeCommand(command)
-
- Log.d(TAG, "command executed: $command with result: $result")
- if (result) {
- onCommandFinished(command)
- } else {
- Log.d(TAG, "waiting for command callback: $command")
- }
- }
-
/**
* Adds a command to be executed next, after all pending tasks are completed. Max commands that
* can be queued is [.MAX_QUEUE_SIZE]. Requests after reaching that limit will be silently
@@ -138,23 +96,89 @@
fun canStartHomeSafely(): Boolean = commandQueue.isEmpty() || commandQueue.first().type == HOME
- /** Clear commands from the queue */
+ /** Clear pending commands from the queue */
fun clearPendingCommands() {
Log.d(TAG, "clearing pending commands: $commandQueue")
commandQueue.clear()
}
- private fun getNextTask(view: RecentsView<*, *>): TaskView? {
- val runningTaskView = view.runningTaskView
+ /**
+ * Executes the next command from the queue. If the command finishes immediately (returns true),
+ * it continues to execute the next command, until the queue is empty of a command defer's its
+ * completion (returns false).
+ */
+ @UiThread
+ private fun executeNext() {
+ val command: CommandInfo =
+ commandQueue.firstOrNull()
+ ?: run {
+ Log.d(TAG, "no pending commands to be executed.")
+ return
+ }
- return if (runningTaskView == null) {
- view.getTaskViewAt(0)
+ command.status = CommandStatus.PROCESSING
+ Log.d(TAG, "executing command: $command")
+
+ val result = executeCommand(command)
+ Log.d(TAG, "command executed: $command with result: $result")
+ if (result) {
+ onCommandFinished(command)
} else {
- val nextTask = view.nextTaskView
- nextTask ?: runningTaskView
+ Log.d(TAG, "waiting for command callback: $command")
}
}
+ /**
+ * Executes the task and returns true if next task can be executed. If false, then the next task
+ * is deferred until [.scheduleNextTask] is called
+ */
+ private fun executeCommand(command: CommandInfo): Boolean {
+ if (waitForToggleCommandComplete && command.type == TOGGLE) {
+ Log.d(TAG, "executeCommand: $command - waiting for toggle command complete")
+ return true
+ }
+
+ val recentsView = visibleRecentsView
+ Log.d(TAG, "executeCommand: $command - visibleRecentsView: $recentsView")
+ return if (recentsView != null) {
+ executeWhenRecentsIsVisible(command, recentsView)
+ } else {
+ executeWhenRecentsIsNotVisible(command)
+ }
+ }
+
+ private fun executeWhenRecentsIsVisible(
+ command: CommandInfo,
+ recentsView: RecentsView<*, *>,
+ ): Boolean =
+ when (command.type) {
+ SHOW -> true // already visible
+ KEYBOARD_INPUT,
+ HIDE -> {
+ if (recentsView.isHandlingTouch) {
+ true
+ } else {
+ keyboardTaskFocusIndex = PagedView.INVALID_PAGE
+ val currentPage = recentsView.nextPage
+ val taskView = recentsView.getTaskViewAt(currentPage)
+ launchTask(recentsView, taskView, command)
+ }
+ }
+ TOGGLE -> {
+ val taskView =
+ if (recentsView.runningTaskView == null) {
+ recentsView.getTaskViewAt(0)
+ } else {
+ recentsView.nextTaskView ?: recentsView.runningTaskView
+ }
+ launchTask(recentsView, taskView, command)
+ }
+ HOME -> {
+ recentsView.startHome()
+ true
+ }
+ }
+
private fun launchTask(
recents: RecentsView<*, *>,
taskView: TaskView?,
@@ -182,81 +206,46 @@
}
}
- /**
- * Executes the task and returns true if next task can be executed. If false, then the next task
- * is deferred until [.scheduleNextTask] is called
- */
- private fun executeCommand(command: CommandInfo): Boolean {
- command.status = CommandStatus.PROCESSING
+ private fun executeWhenRecentsIsNotVisible(command: CommandInfo): Boolean {
+ val recentsViewContainer = activityInterface.getCreatedContainer() as? RecentsViewContainer
+ val recentsView: RecentsView<*, *>? = recentsViewContainer?.getOverviewPanel()
+ val deviceProfile = recentsViewContainer?.getDeviceProfile()
+ val uiController = activityInterface.getTaskbarController()
+ val allowQuickSwitch =
+ FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get() &&
+ uiController != null &&
+ deviceProfile != null &&
+ (deviceProfile.isTablet || deviceProfile.isTwoPanels)
- if (waitForToggleCommandComplete && command.type == TOGGLE) {
- Log.d(TAG, "executeCommand: $command - waiting for toggle command complete")
- return true
- }
-
- var recentsView = visibleRecentsView
- Log.d(TAG, "executeCommand: $command - visibleRecentsView: $recentsView")
- if (recentsView == null) {
- val activity = activityInterface.getCreatedContainer() as? RecentsViewContainer
- recentsView = activity?.getOverviewPanel()
- val deviceProfile = activity?.getDeviceProfile()
- val uiController = activityInterface.getTaskbarController()
- val allowQuickSwitch =
- FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get() &&
- uiController != null &&
- deviceProfile != null &&
- (deviceProfile.isTablet || deviceProfile.isTwoPanels)
-
- when (command.type) {
- HIDE -> {
- if (!allowQuickSwitch) return true
- keyboardTaskFocusIndex = uiController!!.launchFocusedTask()
- if (keyboardTaskFocusIndex == -1) return true
- }
- KEYBOARD_INPUT ->
- if (allowQuickSwitch) {
- uiController!!.openQuickSwitchView()
- return true
- } else {
- keyboardTaskFocusIndex = 0
- }
- HOME -> {
- ActiveGestureLog.INSTANCE.addLog("OverviewCommandHelper.executeCommand(HOME)")
- // Although IActivityTaskManager$Stub$Proxy.startActivity is a slow binder call,
- // we should still call it on main thread because launcher is waiting for
- // ActivityTaskManager to resume it. Also calling startActivity() on bg thread
- // could potentially delay resuming launcher. See b/348668521 for more details.
- touchInteractionService.startActivity(overviewComponentObserver.homeIntent)
+ when (command.type) {
+ HIDE -> {
+ if (!allowQuickSwitch) return true
+ keyboardTaskFocusIndex = uiController!!.launchFocusedTask()
+ if (keyboardTaskFocusIndex == -1) return true
+ }
+ KEYBOARD_INPUT ->
+ if (allowQuickSwitch) {
+ uiController!!.openQuickSwitchView()
return true
- }
- SHOW ->
- // When Recents is not currently visible, the command's type is SHOW
- // when overview is triggered via the keyboard overview button or Action+Tab
- // keys (Not Alt+Tab which is KQS). The overview button on-screen in 3-button
- // nav is TYPE_TOGGLE.
+ } else {
keyboardTaskFocusIndex = 0
- TOGGLE -> {}
- }
- } else {
- return when (command.type) {
- SHOW -> true // already visible
- KEYBOARD_INPUT,
- HIDE -> {
- if (recentsView.isHandlingTouch) {
- true
- } else {
- keyboardTaskFocusIndex = PagedView.INVALID_PAGE
- val currentPage = recentsView.nextPage
- val taskView = recentsView.getTaskViewAt(currentPage)
- launchTask(recentsView, taskView, command)
- }
}
- TOGGLE -> launchTask(recentsView, getNextTask(recentsView), command)
- HOME -> {
- recentsView.startHome()
- true
- }
+ HOME -> {
+ ActiveGestureLog.INSTANCE.addLog("OverviewCommandHelper.executeCommand(HOME)")
+ // Although IActivityTaskManager$Stub$Proxy.startActivity is a slow binder call,
+ // we should still call it on main thread because launcher is waiting for
+ // ActivityTaskManager to resume it. Also calling startActivity() on bg thread
+ // could potentially delay resuming launcher. See b/348668521 for more details.
+ touchInteractionService.startActivity(overviewComponentObserver.homeIntent)
+ return true
}
+ SHOW ->
+ // When Recents is not currently visible, the command's type is SHOW
+ // when overview is triggered via the keyboard overview button or Action+Tab
+ // keys (Not Alt+Tab which is KQS). The overview button on-screen in 3-button
+ // nav is TYPE_TOGGLE.
+ keyboardTaskFocusIndex = 0
+ TOGGLE -> {}
}
recentsView?.setKeyboardTaskFocusIndex(keyboardTaskFocusIndex)
@@ -264,6 +253,7 @@
val animatorListener: Animator.AnimatorListener =
object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
+ Log.d(TAG, "switching to Overview state - onAnimationStart: $command")
super.onAnimationStart(animation)
updateRecentsViewFocus(command)
logShowOverviewFrom(command.type)
@@ -309,9 +299,11 @@
controller: RecentsAnimationController,
targets: RecentsAnimationTargets
) {
+ Log.d(TAG, "recents animation started: $command")
updateRecentsViewFocus(command)
logShowOverviewFrom(command.type)
activityInterface.runOnInitBackgroundStateUI {
+ Log.d(TAG, "recents animation started - onInitBackgroundStateUI: $command")
interactionHandler.onGestureEnded(0f, PointF())
}
command.removeListener(this)
@@ -320,6 +312,7 @@
override fun onRecentsAnimationCanceled(
thumbnailDatas: HashMap<Int, ThumbnailData>
) {
+ Log.d(TAG, "recents animation canceled: $command")
interactionHandler.onGestureCancelled()
command.removeListener(this)
@@ -366,6 +359,23 @@
onCommandFinished(command)
}
+ /** Called when the command finishes execution. */
+ private fun onCommandFinished(command: CommandInfo) {
+ command.status = CommandStatus.COMPLETED
+ if (commandQueue.first() !== command) {
+ Log.d(
+ TAG,
+ "next task not scheduled. First pending command type " +
+ "is ${commandQueue.first()} - command type is: $command"
+ )
+ return
+ }
+
+ Log.d(TAG, "command executed successfully! $command")
+ commandQueue.remove(command)
+ executeNext()
+ }
+
private fun updateRecentsViewFocus(command: CommandInfo) {
val recentsView: RecentsView<*, *> = visibleRecentsView ?: return
if (command.type != KEYBOARD_INPUT && command.type != HIDE && command.type != SHOW) {
@@ -380,10 +390,11 @@
// here we launch overview with live tile.
recentsView.viewRootImpl.touchModeChanged(false)
// Ensure that recents view has focus so that it receives the followup key inputs
- if (requestFocus(recentsView.getTaskViewAt(keyboardTaskFocusIndex))) return
- if (requestFocus(recentsView.nextTaskView)) return
- if (requestFocus(recentsView.getTaskViewAt(0))) return
- requestFocus(recentsView)
+ // Stops requesting focused after first view gets focused.
+ recentsView.getTaskViewAt(keyboardTaskFocusIndex).requestFocus() ||
+ recentsView.nextTaskView.requestFocus() ||
+ recentsView.getTaskViewAt(0).requestFocus() ||
+ recentsView.requestFocus()
}
private fun onRecentsViewFocusUpdated(command: CommandInfo) {
@@ -396,11 +407,11 @@
keyboardTaskFocusIndex = PagedView.INVALID_PAGE
}
- private fun requestFocus(taskView: View?): Boolean {
- if (taskView == null) return false
- taskView.post {
- taskView.requestFocus()
- taskView.requestAccessibilityFocus()
+ private fun View?.requestFocus(): Boolean {
+ if (this == null) return false
+ post {
+ requestFocus()
+ requestAccessibilityFocus()
}
return true
}