From a143500a6924df6fa60d97237d58bb9425caa768 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 24 Nov 2021 10:54:27 -0800 Subject: [PATCH] Add TaskbarControllers#runAfterInit() And use it in TaskbarModelCallbacks#commitItemsToUI(), which in rare cases can run during init() before other controllers (namely TaskbarStashController) have been initialized. Test: call commitItemsToUI() in TaskbarModelCallbacks#init(), ensure no crash Fixes: 204847702 Change-Id: Ib9df3ea91d41c76ad1d3392e43b444b8b4a91374 Merged-In: Ib9df3ea91d41c76ad1d3392e43b444b8b4a91374 --- .../launcher3/taskbar/TaskbarControllers.java | 27 +++++++++++++++++++ .../taskbar/TaskbarModelCallbacks.java | 9 ++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 56730dbd70..2d4942d058 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -19,6 +19,9 @@ import androidx.annotation.NonNull; import com.android.systemui.shared.rotation.RotationButtonController; +import java.util.ArrayList; +import java.util.List; + /** * Hosts various taskbar controllers to facilitate passing between one another. */ @@ -43,6 +46,9 @@ public class TaskbarControllers { /** Do not store this controller, as it may change at runtime. */ @NonNull public TaskbarUIController uiController = TaskbarUIController.DEFAULT; + private boolean mAreAllControllersInitialized; + private final List mPostInitCallbacks = new ArrayList<>(); + public TaskbarControllers(TaskbarActivityContext taskbarActivityContext, TaskbarDragController taskbarDragController, TaskbarNavButtonController navButtonController, @@ -81,6 +87,8 @@ public class TaskbarControllers { * in constructors for now, as some controllers may still be waiting for init(). */ public void init(TaskbarSharedState sharedState) { + mAreAllControllersInitialized = false; + taskbarDragController.init(this); navbarButtonsViewController.init(this); rotationButtonController.init(); @@ -92,6 +100,12 @@ public class TaskbarControllers { stashedHandleViewController.init(this); taskbarStashController.init(this, sharedState); taskbarEduController.init(this); + + mAreAllControllersInitialized = true; + for (Runnable postInitCallback : mPostInitCallbacks) { + postInitCallback.run(); + } + mPostInitCallbacks.clear(); } /** @@ -108,4 +122,17 @@ public class TaskbarControllers { stashedHandleViewController.onDestroy(); taskbarAutohideSuspendController.onDestroy(); } + + /** + * If all controllers are already initialized, runs the given callback immediately. Otherwise, + * queues it to run after calling init() on all controllers. This should likely be used in any + * case where one controller is telling another controller to do something inside init(). + */ + public void runAfterInit(Runnable callback) { + if (mAreAllControllersInitialized) { + callback.run(); + } else { + mPostInitCallbacks.add(callback); + } + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java index 6dcfe564a6..37a9b5e5b2 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java @@ -184,9 +184,12 @@ public class TaskbarModelCallbacks implements } mContainer.updateHotseatItems(hotseatItemInfos); - mControllers.taskbarStashController.updateStateForFlag( - TaskbarStashController.FLAG_STASHED_IN_APP_EMPTY, isHotseatEmpty); - mControllers.taskbarStashController.applyState(); + final boolean finalIsHotseatEmpty = isHotseatEmpty; + mControllers.runAfterInit(() -> { + mControllers.taskbarStashController.updateStateForFlag( + TaskbarStashController.FLAG_STASHED_IN_APP_EMPTY, finalIsHotseatEmpty); + mControllers.taskbarStashController.applyState(); + }); } @Override