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
This commit is contained in:
Tony Wickham
2021-11-24 10:54:27 -08:00
parent db5f5f05e7
commit a143500a69
2 changed files with 33 additions and 3 deletions

View File

@@ -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<Runnable> 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);
}
}
}

View File

@@ -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