summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt349
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java178
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java2
5 files changed, 489 insertions, 62 deletions
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt
new file mode 100644
index 000000000000..9fdde128ce41
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles
+
+import android.content.Context
+import android.content.pm.LauncherApps
+import android.content.pm.ShortcutInfo
+import android.content.res.Resources
+import android.graphics.Color
+import android.os.Handler
+import android.os.UserManager
+import android.view.IWindowManager
+import android.view.WindowManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.internal.protolog.ProtoLog
+import com.android.internal.statusbar.IStatusBarService
+import com.android.launcher3.icons.BubbleIconFactory
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.WindowManagerShellWrapper
+import com.android.wm.shell.bubbles.properties.BubbleProperties
+import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayInsetsController
+import com.android.wm.shell.common.FloatingContentCoordinator
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.common.TaskStackListenerImpl
+import com.android.wm.shell.shared.TransactionPool
+import com.android.wm.shell.sysui.ShellCommandHandler
+import com.android.wm.shell.sysui.ShellController
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.taskview.TaskView
+import com.android.wm.shell.taskview.TaskViewTransitions
+import com.android.wm.shell.transition.Transitions
+import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.MoreExecutors.directExecutor
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+
+/** Test inflating bubbles with [BubbleViewInfoTask]. */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BubbleViewInfoTaskTest {
+
+ private val context = ApplicationProvider.getApplicationContext<Context>()
+ private lateinit var metadataFlagListener: Bubbles.BubbleMetadataFlagListener
+ private lateinit var iconFactory: BubbleIconFactory
+ private lateinit var bubbleController: BubbleController
+ private lateinit var mainExecutor: TestExecutor
+ private lateinit var bgExecutor: TestExecutor
+ private lateinit var bubbleStackView: BubbleStackView
+ private lateinit var bubblePositioner: BubblePositioner
+ private lateinit var expandedViewManager: BubbleExpandedViewManager
+
+ private val bubbleTaskViewFactory = BubbleTaskViewFactory {
+ BubbleTaskView(mock<TaskView>(), directExecutor())
+ }
+
+ @Before
+ fun setUp() {
+ ProtoLog.REQUIRE_PROTOLOGTOOL = false
+ metadataFlagListener = Bubbles.BubbleMetadataFlagListener {}
+ iconFactory =
+ BubbleIconFactory(
+ context,
+ 60,
+ 30,
+ Color.RED,
+ context.resources.getDimensionPixelSize(R.dimen.importance_ring_stroke_width)
+ )
+
+ mainExecutor = TestExecutor()
+ bgExecutor = TestExecutor()
+ val windowManager = context.getSystemService(WindowManager::class.java)
+ val shellInit = ShellInit(mainExecutor)
+ val shellCommandHandler = ShellCommandHandler()
+ val shellController =
+ ShellController(
+ context,
+ shellInit,
+ shellCommandHandler,
+ mock<DisplayInsetsController>(),
+ mainExecutor
+ )
+ bubblePositioner = BubblePositioner(context, windowManager)
+ val bubbleData =
+ BubbleData(
+ context,
+ mock<BubbleLogger>(),
+ bubblePositioner,
+ BubbleEducationController(context),
+ mainExecutor,
+ bgExecutor
+ )
+
+ val surfaceSynchronizer = { obj: Runnable -> obj.run() }
+
+ val bubbleDataRepository =
+ BubbleDataRepository(
+ mock<LauncherApps>(),
+ mainExecutor,
+ bgExecutor,
+ BubblePersistentRepository(context)
+ )
+
+ bubbleController =
+ BubbleController(
+ context,
+ shellInit,
+ shellCommandHandler,
+ shellController,
+ bubbleData,
+ surfaceSynchronizer,
+ FloatingContentCoordinator(),
+ bubbleDataRepository,
+ mock<IStatusBarService>(),
+ windowManager,
+ WindowManagerShellWrapper(mainExecutor),
+ mock<UserManager>(),
+ mock<LauncherApps>(),
+ mock<BubbleLogger>(),
+ mock<TaskStackListenerImpl>(),
+ mock<ShellTaskOrganizer>(),
+ bubblePositioner,
+ mock<DisplayController>(),
+ null,
+ null,
+ mainExecutor,
+ mock<Handler>(),
+ bgExecutor,
+ mock<TaskViewTransitions>(),
+ mock<Transitions>(),
+ SyncTransactionQueue(TransactionPool(), mainExecutor),
+ mock<IWindowManager>(),
+ mock<BubbleProperties>()
+ )
+
+ val bubbleStackViewManager = BubbleStackViewManager.fromBubbleController(bubbleController)
+ bubbleStackView =
+ BubbleStackView(
+ context,
+ bubbleStackViewManager,
+ bubblePositioner,
+ bubbleData,
+ surfaceSynchronizer,
+ FloatingContentCoordinator(),
+ bubbleController,
+ mainExecutor
+ )
+ expandedViewManager = BubbleExpandedViewManager.fromBubbleController(bubbleController)
+ }
+
+ @Test
+ fun start_runsOnExecutors() {
+ val bubble = createBubbleWithShortcut()
+ val task = createBubbleViewInfoTask(bubble)
+
+ task.start()
+
+ assertThat(bubble.isInflated).isFalse()
+ assertThat(bubble.expandedView).isNull()
+ assertThat(task.isFinished).isFalse()
+
+ bgExecutor.flushAll()
+ assertThat(bubble.isInflated).isFalse()
+ assertThat(bubble.expandedView).isNull()
+ assertThat(task.isFinished).isFalse()
+
+ mainExecutor.flushAll()
+ assertThat(bubble.isInflated).isTrue()
+ assertThat(bubble.expandedView).isNotNull()
+ assertThat(task.isFinished).isTrue()
+ }
+
+ @Test
+ fun startSync_runsImmediately() {
+ val bubble = createBubbleWithShortcut()
+ val task = createBubbleViewInfoTask(bubble)
+
+ task.startSync()
+ assertThat(bubble.isInflated).isTrue()
+ assertThat(bubble.expandedView).isNotNull()
+ assertThat(task.isFinished).isTrue()
+ }
+
+ @Test
+ fun start_calledTwice_throwsIllegalStateException() {
+ val bubble = createBubbleWithShortcut()
+ val task = createBubbleViewInfoTask(bubble)
+ task.start()
+ Assert.assertThrows(IllegalStateException::class.java) { task.start() }
+ }
+
+ @Test
+ fun startSync_calledTwice_throwsIllegalStateException() {
+ val bubble = createBubbleWithShortcut()
+ val task = createBubbleViewInfoTask(bubble)
+ task.startSync()
+ Assert.assertThrows(IllegalStateException::class.java) { task.startSync() }
+ }
+
+ @Test
+ fun start_callbackNotified() {
+ val bubble = createBubbleWithShortcut()
+ var bubbleFromCallback: Bubble? = null
+ val callback = BubbleViewInfoTask.Callback { b: Bubble? -> bubbleFromCallback = b }
+ val task = createBubbleViewInfoTask(bubble, callback)
+ task.start()
+ bgExecutor.flushAll()
+ mainExecutor.flushAll()
+ assertThat(bubbleFromCallback).isSameInstanceAs(bubble)
+ }
+
+ @Test
+ fun startSync_callbackNotified() {
+ val bubble = createBubbleWithShortcut()
+ var bubbleFromCallback: Bubble? = null
+ val callback = BubbleViewInfoTask.Callback { b: Bubble? -> bubbleFromCallback = b }
+ val task = createBubbleViewInfoTask(bubble, callback)
+ task.startSync()
+ assertThat(bubbleFromCallback).isSameInstanceAs(bubble)
+ }
+
+ @Test
+ fun cancel_beforeBackgroundWorkStarts_bubbleNotInflated() {
+ val bubble = createBubbleWithShortcut()
+ val task = createBubbleViewInfoTask(bubble)
+ task.start()
+
+ // Cancel before allowing background or main executor to run
+ task.cancel()
+ bgExecutor.flushAll()
+ mainExecutor.flushAll()
+
+ assertThat(bubble.isInflated).isFalse()
+ assertThat(bubble.expandedView).isNull()
+ assertThat(task.isFinished).isTrue()
+ }
+
+ @Test
+ fun cancel_afterBackgroundWorkBeforeMainThreadWork_bubbleNotInflated() {
+ val bubble = createBubbleWithShortcut()
+ val task = createBubbleViewInfoTask(bubble)
+ task.start()
+
+ // Cancel after background executor runs, but before main executor runs
+ bgExecutor.flushAll()
+ task.cancel()
+ mainExecutor.flushAll()
+
+ assertThat(bubble.isInflated).isFalse()
+ assertThat(bubble.expandedView).isNull()
+ assertThat(task.isFinished).isTrue()
+ }
+
+ @Test
+ fun cancel_beforeStart_bubbleNotInflated() {
+ val bubble = createBubbleWithShortcut()
+ val task = createBubbleViewInfoTask(bubble)
+ task.cancel()
+ task.start()
+ bgExecutor.flushAll()
+ mainExecutor.flushAll()
+
+ assertThat(task.isFinished).isTrue()
+ assertThat(bubble.isInflated).isFalse()
+ assertThat(bubble.expandedView).isNull()
+ }
+
+ private fun createBubbleWithShortcut(): Bubble {
+ val shortcutInfo = ShortcutInfo.Builder(context, "mockShortcutId").build()
+ return Bubble(
+ "mockKey",
+ shortcutInfo,
+ 1000,
+ Resources.ID_NULL,
+ "mockTitle",
+ 0 /* taskId */,
+ "mockLocus",
+ true /* isDismissible */,
+ mainExecutor,
+ bgExecutor,
+ metadataFlagListener
+ )
+ }
+
+ private fun createBubbleViewInfoTask(
+ bubble: Bubble,
+ callback: BubbleViewInfoTask.Callback? = null
+ ): BubbleViewInfoTask {
+ return BubbleViewInfoTask(
+ bubble,
+ context,
+ expandedViewManager,
+ bubbleTaskViewFactory,
+ bubblePositioner,
+ bubbleStackView,
+ null /* layerView */,
+ iconFactory,
+ false /* skipInflation */,
+ callback,
+ mainExecutor,
+ bgExecutor
+ )
+ }
+
+ private class TestExecutor : ShellExecutor {
+
+ private val runnables: MutableList<Runnable> = mutableListOf()
+
+ override fun execute(runnable: Runnable) {
+ runnables.add(runnable)
+ }
+
+ override fun executeDelayed(runnable: Runnable, delayMillis: Long) {
+ execute(runnable)
+ }
+
+ override fun removeCallbacks(runnable: Runnable?) {}
+
+ override fun hasCallback(runnable: Runnable?): Boolean = false
+
+ fun flushAll() {
+ while (runnables.isNotEmpty()) {
+ runnables.removeAt(0).run()
+ }
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 021d3c32fd63..3e758bbad29b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -568,11 +568,11 @@ public class Bubble implements BubbleViewProvider {
@Nullable BubbleBarLayerView layerView,
BubbleIconFactory iconFactory,
boolean skipInflation) {
+ ProtoLog.v(WM_SHELL_BUBBLES, "Inflate bubble key=%s", getKey());
if (Flags.bubbleViewInfoExecutors()) {
- if (mInflationTask != null && mInflationTask.getStatus() != FINISHED) {
- mInflationTask.cancel(true /* mayInterruptIfRunning */);
+ if (mInflationTask != null && !mInflationTask.isFinished()) {
+ mInflationTask.cancel();
}
- // TODO(b/353894869): switch to executors
mInflationTask = new BubbleViewInfoTask(this,
context,
expandedViewManager,
@@ -583,11 +583,12 @@ public class Bubble implements BubbleViewProvider {
iconFactory,
skipInflation,
callback,
- mMainExecutor);
+ mMainExecutor,
+ mBgExecutor);
if (mInflateSynchronously) {
- mInflationTask.onPostExecute(mInflationTask.doInBackground());
+ mInflationTask.startSync();
} else {
- mInflationTask.execute();
+ mInflationTask.start();
}
} else {
if (mInflationTaskLegacy != null && mInflationTaskLegacy.getStatus() != FINISHED) {
@@ -625,7 +626,7 @@ public class Bubble implements BubbleViewProvider {
if (mInflationTask == null) {
return;
}
- mInflationTask.cancel(true /* mayInterruptIfRunning */);
+ mInflationTask.cancel();
} else {
if (mInflationTaskLegacy == null) {
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
index 03a2efd902f9..13855f73fb4a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
@@ -20,6 +20,7 @@ import static com.android.wm.shell.bubbles.BadgedImageView.DEFAULT_PATH_SIZE;
import static com.android.wm.shell.bubbles.BadgedImageView.WHITE_SCRIM_ALPHA;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -34,13 +35,13 @@ import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
-import android.os.AsyncTask;
import android.util.Log;
import android.util.PathParser;
import android.view.LayoutInflater;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
+import com.android.internal.protolog.ProtoLog;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.BubbleIconFactory;
import com.android.wm.shell.R;
@@ -50,15 +51,14 @@ import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
import java.lang.ref.WeakReference;
import java.util.Objects;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* Simple task to inflate views & load necessary info to display a bubble.
*/
-// TODO(b/353894869): switch to executors
-public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask.BubbleViewInfo> {
+public class BubbleViewInfoTask {
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleViewInfoTask" : TAG_BUBBLES;
-
/**
* Callback to find out when the bubble has been inflated & necessary data loaded.
*/
@@ -69,17 +69,22 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
void onBubbleViewsReady(Bubble bubble);
}
- private Bubble mBubble;
- private WeakReference<Context> mContext;
- private WeakReference<BubbleExpandedViewManager> mExpandedViewManager;
- private WeakReference<BubbleTaskViewFactory> mTaskViewFactory;
- private WeakReference<BubblePositioner> mPositioner;
- private WeakReference<BubbleStackView> mStackView;
- private WeakReference<BubbleBarLayerView> mLayerView;
- private BubbleIconFactory mIconFactory;
- private boolean mSkipInflation;
- private Callback mCallback;
- private Executor mMainExecutor;
+ private final Bubble mBubble;
+ private final WeakReference<Context> mContext;
+ private final WeakReference<BubbleExpandedViewManager> mExpandedViewManager;
+ private final WeakReference<BubbleTaskViewFactory> mTaskViewFactory;
+ private final WeakReference<BubblePositioner> mPositioner;
+ private final WeakReference<BubbleStackView> mStackView;
+ private final WeakReference<BubbleBarLayerView> mLayerView;
+ private final BubbleIconFactory mIconFactory;
+ private final boolean mSkipInflation;
+ private final Callback mCallback;
+ private final Executor mMainExecutor;
+ private final Executor mBgExecutor;
+
+ private final AtomicBoolean mStarted = new AtomicBoolean();
+ private final AtomicBoolean mCancelled = new AtomicBoolean();
+ private final AtomicBoolean mFinished = new AtomicBoolean();
/**
* Creates a task to load information for the provided {@link Bubble}. Once all info
@@ -95,7 +100,8 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
BubbleIconFactory factory,
boolean skipInflation,
Callback c,
- Executor mainExecutor) {
+ Executor mainExecutor,
+ Executor bgExecutor) {
mBubble = b;
mContext = new WeakReference<>(context);
mExpandedViewManager = new WeakReference<>(expandedViewManager);
@@ -107,40 +113,123 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
mSkipInflation = skipInflation;
mCallback = c;
mMainExecutor = mainExecutor;
+ mBgExecutor = bgExecutor;
}
- @Override
- protected BubbleViewInfo doInBackground(Void... voids) {
+ /**
+ * Load bubble view info in background using {@code bgExecutor} specified in constructor.
+ * <br>
+ * Use {@link #cancel()} to stop the task.
+ *
+ * @throws IllegalStateException if the task is already started
+ */
+ public void start() {
+ verifyCanStart();
+ if (mCancelled.get()) {
+ // We got cancelled even before start was called. Exit early
+ mFinished.set(true);
+ return;
+ }
+ mBgExecutor.execute(() -> {
+ if (mCancelled.get()) {
+ // We got cancelled while background executor was busy and this was waiting
+ mFinished.set(true);
+ return;
+ }
+ BubbleViewInfo viewInfo = loadViewInfo();
+ if (mCancelled.get()) {
+ // Do not schedule anything on main executor if we got cancelled.
+ // Loading view info involves inflating views and it is possible we get cancelled
+ // during it.
+ mFinished.set(true);
+ return;
+ }
+ mMainExecutor.execute(() -> {
+ // Before updating view info check that we did not get cancelled while waiting
+ // main executor to pick up the work
+ if (!mCancelled.get()) {
+ updateViewInfo(viewInfo);
+ }
+ mFinished.set(true);
+ });
+ });
+ }
+
+ private void verifyCanStart() {
+ if (mStarted.getAndSet(true)) {
+ throw new IllegalStateException("Task already started");
+ }
+ }
+
+ /**
+ * Load bubble view info synchronously.
+ *
+ * @throws IllegalStateException if the task is already started
+ */
+ public void startSync() {
+ verifyCanStart();
+ if (mCancelled.get()) {
+ mFinished.set(true);
+ return;
+ }
+ updateViewInfo(loadViewInfo());
+ mFinished.set(true);
+ }
+
+ /**
+ * Cancel the task. Stops the task from running if called before {@link #start()} or
+ * {@link #startSync()}
+ */
+ public void cancel() {
+ mCancelled.set(true);
+ }
+
+ /**
+ * Return {@code true} when the task has completed loading the view info.
+ */
+ public boolean isFinished() {
+ return mFinished.get();
+ }
+
+ @Nullable
+ private BubbleViewInfo loadViewInfo() {
if (!verifyState()) {
// If we're in an inconsistent state, then switched modes and should just bail now.
return null;
}
+ ProtoLog.v(WM_SHELL_BUBBLES, "Task loading bubble view info key=%s", mBubble.getKey());
if (mLayerView.get() != null) {
- return BubbleViewInfo.populateForBubbleBar(mContext.get(), mExpandedViewManager.get(),
- mTaskViewFactory.get(), mPositioner.get(), mLayerView.get(), mIconFactory,
- mBubble, mSkipInflation);
+ return BubbleViewInfo.populateForBubbleBar(mContext.get(), mTaskViewFactory.get(),
+ mLayerView.get(), mIconFactory, mBubble, mSkipInflation);
} else {
- return BubbleViewInfo.populate(mContext.get(), mExpandedViewManager.get(),
- mTaskViewFactory.get(), mPositioner.get(), mStackView.get(), mIconFactory,
- mBubble, mSkipInflation);
+ return BubbleViewInfo.populate(mContext.get(), mTaskViewFactory.get(),
+ mPositioner.get(), mStackView.get(), mIconFactory, mBubble, mSkipInflation);
}
}
- @Override
- protected void onPostExecute(BubbleViewInfo viewInfo) {
- if (isCancelled() || viewInfo == null) {
+ private void updateViewInfo(@Nullable BubbleViewInfo viewInfo) {
+ if (viewInfo == null || !verifyState()) {
return;
}
-
- mMainExecutor.execute(() -> {
- if (!verifyState()) {
- return;
+ ProtoLog.v(WM_SHELL_BUBBLES, "Task updating bubble view info key=%s", mBubble.getKey());
+ if (!mBubble.isInflated()) {
+ if (viewInfo.expandedView != null) {
+ ProtoLog.v(WM_SHELL_BUBBLES, "Task initializing expanded view key=%s",
+ mBubble.getKey());
+ viewInfo.expandedView.initialize(mExpandedViewManager.get(), mStackView.get(),
+ mPositioner.get(), false /* isOverflow */, viewInfo.taskView);
+ } else if (viewInfo.bubbleBarExpandedView != null) {
+ ProtoLog.v(WM_SHELL_BUBBLES, "Task initializing bubble bar expanded view key=%s",
+ mBubble.getKey());
+ viewInfo.bubbleBarExpandedView.initialize(mExpandedViewManager.get(),
+ mPositioner.get(), false /* isOverflow */, viewInfo.taskView);
}
- mBubble.setViewInfo(viewInfo);
- if (mCallback != null) {
- mCallback.onBubbleViewsReady(mBubble);
- }
- });
+ }
+
+ mBubble.setViewInfo(viewInfo);
+ if (mCallback != null) {
+ mCallback.onBubbleViewsReady(mBubble);
+ }
}
private boolean verifyState() {
@@ -158,6 +247,9 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
public static class BubbleViewInfo {
// TODO(b/273312602): for foldables it might make sense to populate all of the views
+ // Only set if views where inflated as part of the task
+ @Nullable BubbleTaskView taskView;
+
// Always populated
ShortcutInfo shortcutInfo;
String appName;
@@ -177,9 +269,7 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
@Nullable
public static BubbleViewInfo populateForBubbleBar(Context c,
- BubbleExpandedViewManager expandedViewManager,
BubbleTaskViewFactory taskViewFactory,
- BubblePositioner positioner,
BubbleBarLayerView layerView,
BubbleIconFactory iconFactory,
Bubble b,
@@ -187,12 +277,11 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
BubbleViewInfo info = new BubbleViewInfo();
if (!skipInflation && !b.isInflated()) {
- BubbleTaskView bubbleTaskView = b.getOrCreateBubbleTaskView(taskViewFactory);
+ ProtoLog.v(WM_SHELL_BUBBLES, "Task inflating bubble bar views key=%s", b.getKey());
+ info.taskView = b.getOrCreateBubbleTaskView(taskViewFactory);
LayoutInflater inflater = LayoutInflater.from(c);
info.bubbleBarExpandedView = (BubbleBarExpandedView) inflater.inflate(
R.layout.bubble_bar_expanded_view, layerView, false /* attachToRoot */);
- info.bubbleBarExpandedView.initialize(
- expandedViewManager, positioner, false /* isOverflow */, bubbleTaskView);
}
if (!populateCommonInfo(info, c, b, iconFactory)) {
@@ -206,7 +295,6 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
@VisibleForTesting
@Nullable
public static BubbleViewInfo populate(Context c,
- BubbleExpandedViewManager expandedViewManager,
BubbleTaskViewFactory taskViewFactory,
BubblePositioner positioner,
BubbleStackView stackView,
@@ -217,17 +305,15 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
// View inflation: only should do this once per bubble
if (!skipInflation && !b.isInflated()) {
+ ProtoLog.v(WM_SHELL_BUBBLES, "Task inflating bubble views key=%s", b.getKey());
LayoutInflater inflater = LayoutInflater.from(c);
info.imageView = (BadgedImageView) inflater.inflate(
R.layout.bubble_view, stackView, false /* attachToRoot */);
info.imageView.initialize(positioner);
- BubbleTaskView bubbleTaskView = b.getOrCreateBubbleTaskView(taskViewFactory);
+ info.taskView = b.getOrCreateBubbleTaskView(taskViewFactory);
info.expandedView = (BubbleExpandedView) inflater.inflate(
R.layout.bubble_expanded_view, stackView, false /* attachToRoot */);
- info.expandedView.initialize(
- expandedViewManager, stackView, positioner, false /* isOverflow */,
- bubbleTaskView);
}
if (!populateCommonInfo(info, c, b, iconFactory)) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
index 8035e917d5b4..4ac066e4ffb0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
@@ -74,7 +74,6 @@ class BubbleViewInfoTest : ShellTestCase() {
private lateinit var bubbleStackView: BubbleStackView
private lateinit var bubbleBarLayerView: BubbleBarLayerView
private lateinit var bubblePositioner: BubblePositioner
- private lateinit var expandedViewManager: BubbleExpandedViewManager
private val bubbleTaskViewFactory = BubbleTaskViewFactory {
BubbleTaskView(mock<TaskView>(), mock<Executor>())
@@ -155,7 +154,6 @@ class BubbleViewInfoTest : ShellTestCase() {
bubbleController,
mainExecutor
)
- expandedViewManager = BubbleExpandedViewManager.fromBubbleController(bubbleController)
bubbleBarLayerView = BubbleBarLayerView(context, bubbleController, bubbleData)
}
@@ -165,7 +163,6 @@ class BubbleViewInfoTest : ShellTestCase() {
val info =
BubbleViewInfoTask.BubbleViewInfo.populate(
context,
- expandedViewManager,
bubbleTaskViewFactory,
bubblePositioner,
bubbleStackView,
@@ -193,9 +190,7 @@ class BubbleViewInfoTest : ShellTestCase() {
val info =
BubbleViewInfoTask.BubbleViewInfo.populateForBubbleBar(
context,
- expandedViewManager,
bubbleTaskViewFactory,
- bubblePositioner,
bubbleBarLayerView,
iconFactory,
bubble,
@@ -229,9 +224,7 @@ class BubbleViewInfoTest : ShellTestCase() {
val info =
BubbleViewInfoTask.BubbleViewInfo.populateForBubbleBar(
context,
- expandedViewManager,
bubbleTaskViewFactory,
- bubblePositioner,
bubbleBarLayerView,
iconFactory,
bubble,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index a26aa2bafe9b..6e3936576bb4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -169,7 +169,6 @@ import com.android.wm.shell.bubbles.BubbleData;
import com.android.wm.shell.bubbles.BubbleDataRepository;
import com.android.wm.shell.bubbles.BubbleEducationController;
import com.android.wm.shell.bubbles.BubbleEntry;
-import com.android.wm.shell.bubbles.BubbleExpandedViewManager;
import com.android.wm.shell.bubbles.BubbleLogger;
import com.android.wm.shell.bubbles.BubbleOverflow;
import com.android.wm.shell.bubbles.BubbleStackView;
@@ -1408,7 +1407,6 @@ public class BubblesTest extends SysuiTestCase {
.thenReturn(userContext);
BubbleViewInfoTask.BubbleViewInfo info = BubbleViewInfoTask.BubbleViewInfo.populate(context,
- BubbleExpandedViewManager.fromBubbleController(mBubbleController),
() -> new BubbleTaskView(mock(TaskView.class), mock(Executor.class)),
mPositioner,
mBubbleController.getStackView(),