From c779ae54cefbfcb26258ab3067ce36ce7d18abbd Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Tue, 31 Jan 2023 10:54:19 +0800 Subject: [PATCH] Fix bug with trying to split an app with itself This patch fixes the following user flow: 1) App is already running 2) User initiates splitscreen from Home with that app 3) User selects the same app from Taskbar or AllApps Previously, this caused a crash because the split-from-home initiation removed the corresponding app tile, causing a null pointer exception when the same task ID was used as a split target. Fixed by adding a null check: if the target TaskView can't be found for any reason, fall back to launching the second app via Intent instead. If the app doesn't support multi-instance, the UI will now show an attempted split, followed by the message "This app can only be opened in 1 window." Fixes: 263041522 Fixes: 266218404 Test: Manual Change-Id: I39ed60c9ac758ac215391f0618f44f7fcee4f32c --- .../taskbar/TaskbarUIController.java | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index ebb37a88fc..2d47616594 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -175,24 +175,32 @@ public class TaskbarUIController { (Consumer) foundTask -> { if (foundTask != null) { TaskView foundTaskView = recents.getTaskViewByTaskId(foundTask.key.id); - // There is already a running app of this type, use that as second app. - recents.confirmSplitSelect( - foundTaskView, - foundTaskView.getTask(), - foundTaskView.getIconView().getDrawable(), - foundTaskView.getThumbnail(), - foundTaskView.getThumbnail().getThumbnail(), - null /* intent */); - } else { - // No running app of that type, create a new instance as second app. - recents.confirmSplitSelect( - null /* containerTaskView */, - null /* task */, - new BitmapDrawable(info.bitmap.icon), - startingView, - null /* thumbnail */, - intent); + // TODO (b/266482558): This additional null check is needed because there + // are times when our Tasks list doesn't match our TaskViews list (like when + // a tile is removed during {@link RecentsView#applyLoadPlan()}. A clearer + // state management system is in the works so that we don't need to rely on + // null checks as much. See comments at ag/21152798. + if (foundTaskView != null) { + // There is already a running app of this type, use that as second app. + recents.confirmSplitSelect( + foundTaskView, + foundTaskView.getTask(), + foundTaskView.getIconView().getDrawable(), + foundTaskView.getThumbnail(), + foundTaskView.getThumbnail().getThumbnail(), + null /* intent */); + return; + } } + + // No running app of that type, create a new instance as second app. + recents.confirmSplitSelect( + null /* containerTaskView */, + null /* task */, + new BitmapDrawable(info.bitmap.icon), + startingView, + null /* thumbnail */, + intent); } ); }