Update BubbleViewInfoTask to verify that the state hasn't changed after the task was scheduled or while it is running.

Without this there is a race condition that causes the task to inflate a bubble incorrectly, e.g. without a dot path, which then leads to an NPE trying to render the dot.

Bug: 269670598
Test: Tested on a physical device
Change-Id: Ib2cbd4ef0fd2a33766620a0997f130eb4b8bb86f
This commit is contained in:
Liran Binyamin
2023-06-05 18:33:14 -04:00
parent 9ce13dd292
commit 065c12c764

View File

@@ -104,7 +104,11 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
@Override
protected BubbleViewInfo doInBackground(Void... voids) {
if (mController.get().isShowingAsBubbleBar()) {
if (!verifyState()) {
// If we're in an inconsistent state, then switched modes and should just bail now.
return null;
}
if (mLayerView.get() != null) {
return BubbleViewInfo.populateForBubbleBar(mContext.get(), mController.get(),
mLayerView.get(), mIconFactory, mBubble, mSkipInflation);
} else {
@@ -118,7 +122,11 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
if (isCancelled() || viewInfo == null) {
return;
}
mMainExecutor.execute(() -> {
if (!verifyState()) {
return;
}
mBubble.setViewInfo(viewInfo);
if (mCallback != null) {
mCallback.onBubbleViewsReady(mBubble);
@@ -126,6 +134,14 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
});
}
private boolean verifyState() {
if (mController.get().isShowingAsBubbleBar()) {
return mLayerView.get() != null;
} else {
return mStackView.get() != null;
}
}
/**
* Info necessary to render a bubble.
*/