summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/OWNERS1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java47
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt79
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewFactory.kt23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java53
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java29
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleOverflowTest.java16
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt24
-rw-r--r--libs/hwui/apex/android_paint.cpp25
-rw-r--r--libs/hwui/apex/include/android/graphics/paint.h14
-rw-r--r--libs/hwui/libhwui.map.txt1
-rw-r--r--libs/input/SpriteIcon.cpp3
-rw-r--r--libs/input/SpriteIcon.h13
20 files changed, 356 insertions, 118 deletions
diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS
index e346b51a4f19..0c4fd140780e 100644
--- a/libs/WindowManager/Shell/OWNERS
+++ b/libs/WindowManager/Shell/OWNERS
@@ -2,3 +2,4 @@ xutan@google.com
# Give submodule owners in shell resource approval
per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com, nmusgrave@google.com, pbdr@google.com, tkachenkoi@google.com
+per-file res*/*/tv_*.xml = bronger@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.java
index 160f922dd928..55982dca79b3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.java
@@ -310,12 +310,16 @@ public class CrossActivityBackAnimation extends ShellBackAnimation {
float top = mapRange(progress, mEnteringStartRect.top, mStartTaskRect.top);
float width = mapRange(progress, mEnteringStartRect.width(), mStartTaskRect.width());
float height = mapRange(progress, mEnteringStartRect.height(), mStartTaskRect.height());
- float alpha = mapRange(progress, mEnteringProgress, 1.0f);
-
+ float alpha = mapRange(progress, getPreCommitEnteringAlpha(), 1.0f);
mEnteringRect.set(left, top, left + width, top + height);
applyTransform(mEnteringTarget.leash, mEnteringRect, alpha);
}
+ private float getPreCommitEnteringAlpha() {
+ return Math.max(smoothstep(ENTER_ALPHA_THRESHOLD, 0.7f, mEnteringProgress),
+ MIN_WINDOW_ALPHA);
+ }
+
private float getEnteringProgress() {
return mEnteringProgress * SCALE_FACTOR;
}
@@ -325,9 +329,7 @@ public class CrossActivityBackAnimation extends ShellBackAnimation {
if (mEnteringTarget != null && mEnteringTarget.leash != null) {
transformWithProgress(
mEnteringProgress,
- Math.max(
- smoothstep(ENTER_ALPHA_THRESHOLD, 0.7f, mEnteringProgress),
- MIN_WINDOW_ALPHA), /* alpha */
+ getPreCommitEnteringAlpha(),
mEnteringTarget.leash,
mEnteringRect,
-mWindowXShift,
@@ -336,6 +338,11 @@ public class CrossActivityBackAnimation extends ShellBackAnimation {
}
}
+ private float getPreCommitLeavingAlpha() {
+ return Math.max(1 - smoothstep(0, ENTER_ALPHA_THRESHOLD, mLeavingProgress),
+ MIN_WINDOW_ALPHA);
+ }
+
private float getLeavingProgress() {
return mLeavingProgress * SCALE_FACTOR;
}
@@ -345,9 +352,7 @@ public class CrossActivityBackAnimation extends ShellBackAnimation {
if (mClosingTarget != null && mClosingTarget.leash != null) {
transformWithProgress(
mLeavingProgress,
- Math.max(
- 1 - smoothstep(0, ENTER_ALPHA_THRESHOLD, mLeavingProgress),
- MIN_WINDOW_ALPHA),
+ getPreCommitLeavingAlpha(),
mClosingTarget.leash,
mClosingRect,
0,
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 7a4ad0a56022..da530d740d48 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
@@ -53,8 +53,6 @@ import com.android.launcher3.icons.BubbleIconFactory;
import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView;
import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
import com.android.wm.shell.common.bubbles.BubbleInfo;
-import com.android.wm.shell.taskview.TaskView;
-import com.android.wm.shell.taskview.TaskViewTaskController;
import java.io.PrintWriter;
import java.util.List;
@@ -403,13 +401,9 @@ public class Bubble implements BubbleViewProvider {
* Returns the existing {@link #mBubbleTaskView} if it's not {@code null}. Otherwise a new
* instance of {@link BubbleTaskView} is created.
*/
- public BubbleTaskView getOrCreateBubbleTaskView(Context context, BubbleController controller) {
+ public BubbleTaskView getOrCreateBubbleTaskView(BubbleTaskViewFactory taskViewFactory) {
if (mBubbleTaskView == null) {
- TaskViewTaskController taskViewTaskController = new TaskViewTaskController(context,
- controller.getTaskOrganizer(),
- controller.getTaskViewTransitions(), controller.getSyncTransactionQueue());
- TaskView taskView = new TaskView(context, taskViewTaskController);
- mBubbleTaskView = new BubbleTaskView(taskView, controller.getMainExecutor());
+ mBubbleTaskView = taskViewFactory.create();
}
return mBubbleTaskView;
}
@@ -514,14 +508,18 @@ public class Bubble implements BubbleViewProvider {
*
* @param callback the callback to notify one the bubble is ready to be displayed.
* @param context the context for the bubble.
- * @param controller the bubble controller.
+ * @param expandedViewManager the bubble expanded view manager.
+ * @param taskViewFactory the task view factory used to create the task view for the bubble.
+ * @param positioner the bubble positioner.
* @param stackView the view the bubble is added to, iff showing as floating.
* @param layerView the layer the bubble is added to, iff showing in the bubble bar.
- * @param iconFactory the icon factory use to create images for the bubble.
+ * @param iconFactory the icon factory used to create images for the bubble.
*/
void inflate(BubbleViewInfoTask.Callback callback,
Context context,
- BubbleController controller,
+ BubbleExpandedViewManager expandedViewManager,
+ BubbleTaskViewFactory taskViewFactory,
+ BubblePositioner positioner,
@Nullable BubbleStackView stackView,
@Nullable BubbleBarLayerView layerView,
BubbleIconFactory iconFactory,
@@ -531,7 +529,9 @@ public class Bubble implements BubbleViewProvider {
}
mInflationTask = new BubbleViewInfoTask(this,
context,
- controller,
+ expandedViewManager,
+ taskViewFactory,
+ positioner,
stackView,
layerView,
iconFactory,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 0aa89598cd10..5c6f73f0a4a2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -113,6 +113,7 @@ 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.TaskViewTaskController;
import com.android.wm.shell.taskview.TaskViewTransitions;
import com.android.wm.shell.transition.Transitions;
@@ -190,6 +191,8 @@ public class BubbleController implements ConfigurationChangeListener,
private final ShellCommandHandler mShellCommandHandler;
private final IWindowManager mWmService;
private final BubbleProperties mBubbleProperties;
+ private final BubbleTaskViewFactory mBubbleTaskViewFactory;
+ private final BubbleExpandedViewManager mExpandedViewManager;
// Used to post to main UI thread
private final ShellExecutor mMainExecutor;
@@ -333,6 +336,16 @@ public class BubbleController implements ConfigurationChangeListener,
mWmService = wmService;
mBubbleProperties = bubbleProperties;
shellInit.addInitCallback(this::onInit, this);
+ mBubbleTaskViewFactory = new BubbleTaskViewFactory() {
+ @Override
+ public BubbleTaskView create() {
+ TaskViewTaskController taskViewTaskController = new TaskViewTaskController(
+ context, organizer, taskViewTransitions, syncQueue);
+ TaskView taskView = new TaskView(context, taskViewTaskController);
+ return new BubbleTaskView(taskView, mainExecutor);
+ }
+ };
+ mExpandedViewManager = BubbleExpandedViewManager.fromBubbleController(this);
}
private void registerOneHandedState(OneHandedController oneHanded) {
@@ -802,7 +815,13 @@ public class BubbleController implements ConfigurationChangeListener,
try {
mAddedToWindowManager = true;
registerBroadcastReceiver();
- mBubbleData.getOverflow().initialize(this, isShowingAsBubbleBar());
+ if (isShowingAsBubbleBar()) {
+ mBubbleData.getOverflow().initializeForBubbleBar(
+ mExpandedViewManager, mBubblePositioner);
+ } else {
+ mBubbleData.getOverflow().initialize(
+ mExpandedViewManager, mStackView, mBubblePositioner);
+ }
// (TODO: b/273314541) some duplication in the inset listener
if (isShowingAsBubbleBar()) {
mWindowManager.addView(mLayerView, mWmLayoutParams);
@@ -984,7 +1003,9 @@ public class BubbleController implements ConfigurationChangeListener,
for (Bubble b : mBubbleData.getBubbles()) {
b.inflate(null /* callback */,
mContext,
- this,
+ mExpandedViewManager,
+ mBubbleTaskViewFactory,
+ mBubblePositioner,
mStackView,
mLayerView,
mBubbleIconFactory,
@@ -993,7 +1014,9 @@ public class BubbleController implements ConfigurationChangeListener,
for (Bubble b : mBubbleData.getOverflowBubbles()) {
b.inflate(null /* callback */,
mContext,
- this,
+ mExpandedViewManager,
+ mBubbleTaskViewFactory,
+ mBubblePositioner,
mStackView,
mLayerView,
mBubbleIconFactory,
@@ -1377,7 +1400,9 @@ public class BubbleController implements ConfigurationChangeListener,
bubble.inflate(
(b) -> mBubbleData.overflowBubble(Bubbles.DISMISS_RELOAD_FROM_DISK, bubble),
mContext,
- this,
+ mExpandedViewManager,
+ mBubbleTaskViewFactory,
+ mBubblePositioner,
mStackView,
mLayerView,
mBubbleIconFactory,
@@ -1431,7 +1456,9 @@ public class BubbleController implements ConfigurationChangeListener,
Bubble bubble = mBubbleData.getBubbles().get(i);
bubble.inflate(callback,
mContext,
- this,
+ mExpandedViewManager,
+ mBubbleTaskViewFactory,
+ mBubblePositioner,
mStackView,
mLayerView,
mBubbleIconFactory,
@@ -1506,8 +1533,14 @@ public class BubbleController implements ConfigurationChangeListener,
// Lazy init stack view when a bubble is created
ensureBubbleViewsAndWindowCreated();
bubble.setInflateSynchronously(mInflateSynchronously);
- bubble.inflate(b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade),
- mContext, this, mStackView, mLayerView,
+ bubble.inflate(
+ b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade),
+ mContext,
+ mExpandedViewManager,
+ mBubbleTaskViewFactory,
+ mBubblePositioner,
+ mStackView,
+ mLayerView,
mBubbleIconFactory,
false /* skipInflation */);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 6d3f0c32bcbb..6c2f925119f3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -37,10 +37,8 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.FrameworkStatsLog;
-import com.android.launcher3.icons.BubbleIconFactory;
import com.android.wm.shell.R;
import com.android.wm.shell.bubbles.Bubbles.DismissReason;
-import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
import com.android.wm.shell.common.bubbles.BubbleBarUpdate;
import com.android.wm.shell.common.bubbles.RemovedBubble;
@@ -180,7 +178,7 @@ public class BubbleData {
* This interface reports changes to the state and appearance of bubbles which should be applied
* as necessary to the UI.
*/
- interface Listener {
+ public interface Listener {
/** Reports changes have have occurred as a result of the most recent operation. */
void applyUpdate(Update update);
}
@@ -419,8 +417,10 @@ public class BubbleData {
/**
* When this method is called it is expected that all info in the bubble has completed loading.
- * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleController, BubbleStackView,
- * BubbleBarLayerView, BubbleIconFactory, boolean)
+ * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleExpandedViewManager,
+ * BubbleTaskViewFactory, BubblePositioner, BubbleStackView,
+ * com.android.wm.shell.bubbles.bar.BubbleBarLayerView,
+ * com.android.launcher3.icons.BubbleIconFactory, boolean)
*/
void notificationEntryUpdated(Bubble bubble, boolean suppressFlyout, boolean showInShade) {
mPendingBubbles.remove(bubble.getKey()); // No longer pending once we're here
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index 088660e4e8dc..df9ba63b4cc2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -184,7 +184,7 @@ public class BubbleExpandedView extends LinearLayout {
private boolean mIsOverflow;
private boolean mIsClipping;
- private BubbleController mController;
+ private BubbleExpandedViewManager mManager;
private BubbleStackView mStackView;
private BubblePositioner mPositioner;
@@ -261,7 +261,7 @@ public class BubbleExpandedView extends LinearLayout {
// the bubble again so we'll just remove it.
Log.w(TAG, "Exception while displaying bubble: " + getBubbleKey()
+ ", " + e.getMessage() + "; removing bubble");
- mController.removeBubble(getBubbleKey(), Bubbles.DISMISS_INVALID_INTENT);
+ mManager.removeBubble(getBubbleKey(), Bubbles.DISMISS_INVALID_INTENT);
}
});
mInitialized = true;
@@ -281,7 +281,7 @@ public class BubbleExpandedView extends LinearLayout {
if (mBubble != null && mBubble.isAppBubble()) {
// Let the controller know sooner what the taskId is.
- mController.setAppBubbleTaskId(mBubble.getKey(), mTaskId);
+ mManager.setAppBubbleTaskId(mBubble.getKey(), mTaskId);
}
// With the task org, the taskAppeared callback will only happen once the task has
@@ -301,7 +301,7 @@ public class BubbleExpandedView extends LinearLayout {
ProtoLog.d(WM_SHELL_BUBBLES, "onTaskRemovalStarted: taskId=%d bubble=%s",
taskId, getBubbleKey());
if (mBubble != null) {
- mController.removeBubble(mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED);
+ mManager.removeBubble(mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED);
}
if (mTaskView != null) {
// Release the surface
@@ -421,17 +421,20 @@ public class BubbleExpandedView extends LinearLayout {
* Initialize {@link BubbleController} and {@link BubbleStackView} here, this method must need
* to be called after view inflate.
*/
- void initialize(BubbleController controller, BubbleStackView stackView, boolean isOverflow,
+ void initialize(BubbleExpandedViewManager expandedViewManager,
+ BubbleStackView stackView,
+ BubblePositioner positioner,
+ boolean isOverflow,
@Nullable BubbleTaskView bubbleTaskView) {
- mController = controller;
+ mManager = expandedViewManager;
mStackView = stackView;
mIsOverflow = isOverflow;
- mPositioner = mController.getPositioner();
+ mPositioner = positioner;
if (mIsOverflow) {
mOverflowView = (BubbleOverflowContainerView) LayoutInflater.from(getContext()).inflate(
R.layout.bubble_overflow_container, null /* root */);
- mOverflowView.setBubbleController(mController);
+ mOverflowView.initialize(expandedViewManager, positioner);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
mExpandedViewContainer.addView(mOverflowView, lp);
mExpandedViewContainer.setLayoutParams(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
new file mode 100644
index 000000000000..b0d3cc4a5d5c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
@@ -0,0 +1,79 @@
+/*
+ * 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
+
+/** Manager interface for bubble expanded views. */
+interface BubbleExpandedViewManager {
+
+ val overflowBubbles: List<Bubble>
+ fun setOverflowListener(listener: BubbleData.Listener)
+ fun collapseStack()
+ fun updateWindowFlagsForBackpress(intercept: Boolean)
+ fun promoteBubbleFromOverflow(bubble: Bubble)
+ fun removeBubble(key: String, reason: Int)
+ fun dismissBubble(bubble: Bubble, reason: Int)
+ fun setAppBubbleTaskId(key: String, taskId: Int)
+ fun isStackExpanded(): Boolean
+ fun isShowingAsBubbleBar(): Boolean
+
+ companion object {
+ /**
+ * Convenience function for creating a [BubbleExpandedViewManager] that delegates to the
+ * given `controller`.
+ */
+ @JvmStatic
+ fun fromBubbleController(controller: BubbleController): BubbleExpandedViewManager {
+ return object : BubbleExpandedViewManager {
+
+ override val overflowBubbles: List<Bubble>
+ get() = controller.overflowBubbles
+
+ override fun setOverflowListener(listener: BubbleData.Listener) {
+ controller.setOverflowListener(listener)
+ }
+
+ override fun collapseStack() {
+ controller.collapseStack()
+ }
+
+ override fun updateWindowFlagsForBackpress(intercept: Boolean) {
+ controller.updateWindowFlagsForBackpress(intercept)
+ }
+
+ override fun promoteBubbleFromOverflow(bubble: Bubble) {
+ controller.promoteBubbleFromOverflow(bubble)
+ }
+
+ override fun removeBubble(key: String, reason: Int) {
+ controller.removeBubble(key, reason)
+ }
+
+ override fun dismissBubble(bubble: Bubble, reason: Int) {
+ controller.dismissBubble(bubble, reason)
+ }
+
+ override fun setAppBubbleTaskId(key: String, taskId: Int) {
+ controller.setAppBubbleTaskId(key, taskId)
+ }
+
+ override fun isStackExpanded(): Boolean = controller.isStackExpanded
+
+ override fun isShowingAsBubbleBar(): Boolean = controller.isShowingAsBubbleBar
+ }
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index e5d9acedc903..f32974e1765d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -56,19 +56,32 @@ class BubbleOverflow(private val context: Context, private val positioner: Bubbl
}
/** Call before use and again if cleanUpExpandedState was called. */
- fun initialize(controller: BubbleController, forBubbleBar: Boolean) {
- if (forBubbleBar) {
- createBubbleBarExpandedView()
- .initialize(controller, /* isOverflow= */ true, /* bubbleTaskView= */ null)
- } else {
- createExpandedView()
+ fun initialize(
+ expandedViewManager: BubbleExpandedViewManager,
+ stackView: BubbleStackView,
+ positioner: BubblePositioner
+ ) {
+ createExpandedView()
.initialize(
- controller,
- controller.stackView,
+ expandedViewManager,
+ stackView,
+ positioner,
/* isOverflow= */ true,
/* bubbleTaskView= */ null
)
- }
+ }
+
+ fun initializeForBubbleBar(
+ expandedViewManager: BubbleExpandedViewManager,
+ positioner: BubblePositioner
+ ) {
+ createBubbleBarExpandedView()
+ .initialize(
+ expandedViewManager,
+ positioner,
+ /* isOverflow= */ true,
+ /* bubbleTaskView= */ null
+ )
}
fun cleanUpExpandedState() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index 70cdc82c47ad..b06de4f4002c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -62,7 +62,8 @@ public class BubbleOverflowContainerView extends LinearLayout {
private ImageView mEmptyStateImage;
private int mHorizontalMargin;
private int mVerticalMargin;
- private BubbleController mController;
+ private BubbleExpandedViewManager mExpandedViewManager;
+ private BubblePositioner mPositioner;
private BubbleOverflowAdapter mAdapter;
private RecyclerView mRecyclerView;
private List<Bubble> mOverflowBubbles = new ArrayList<>();
@@ -70,7 +71,7 @@ public class BubbleOverflowContainerView extends LinearLayout {
private View.OnKeyListener mKeyListener = (view, i, keyEvent) -> {
if (keyEvent.getAction() == KeyEvent.ACTION_UP
&& keyEvent.getKeyCode() == KeyEvent.KEYCODE_BACK) {
- mController.collapseStack();
+ mExpandedViewManager.collapseStack();
return true;
}
return false;
@@ -126,8 +127,11 @@ public class BubbleOverflowContainerView extends LinearLayout {
setFocusableInTouchMode(true);
}
- public void setBubbleController(BubbleController controller) {
- mController = controller;
+ /** Initializes the view. Must be called after creation. */
+ public void initialize(BubbleExpandedViewManager expandedViewManager,
+ BubblePositioner positioner) {
+ mExpandedViewManager = expandedViewManager;
+ mPositioner = positioner;
}
public void show() {
@@ -149,9 +153,9 @@ public class BubbleOverflowContainerView extends LinearLayout {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- if (mController != null) {
+ if (mExpandedViewManager != null) {
// For the overflow to get key events (e.g. back press) we need to adjust the flags
- mController.updateWindowFlagsForBackpress(true);
+ mExpandedViewManager.updateWindowFlagsForBackpress(true);
}
setOnKeyListener(mKeyListener);
}
@@ -159,8 +163,8 @@ public class BubbleOverflowContainerView extends LinearLayout {
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- if (mController != null) {
- mController.updateWindowFlagsForBackpress(false);
+ if (mExpandedViewManager != null) {
+ mExpandedViewManager.updateWindowFlagsForBackpress(false);
}
setOnKeyListener(null);
}
@@ -177,15 +181,15 @@ public class BubbleOverflowContainerView extends LinearLayout {
mRecyclerView.addItemDecoration(new OverflowItemDecoration());
}
mAdapter = new BubbleOverflowAdapter(getContext(), mOverflowBubbles,
- mController::promoteBubbleFromOverflow,
- mController.getPositioner());
+ mExpandedViewManager::promoteBubbleFromOverflow,
+ mPositioner);
mRecyclerView.setAdapter(mAdapter);
mOverflowBubbles.clear();
- mOverflowBubbles.addAll(mController.getOverflowBubbles());
+ mOverflowBubbles.addAll(mExpandedViewManager.getOverflowBubbles());
mAdapter.notifyDataSetChanged();
- mController.setOverflowListener(mDataListener);
+ mExpandedViewManager.setOverflowListener(mDataListener);
updateEmptyStateVisibility();
updateTheme();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewFactory.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewFactory.kt
new file mode 100644
index 000000000000..230626f49c51
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewFactory.kt
@@ -0,0 +1,23 @@
+/*
+ * 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
+
+/** Factory for creating [BubbleTaskView]s. */
+fun interface BubbleTaskViewFactory {
+ /** Creates a new instance of [BubbleTaskView]. */
+ fun create(): BubbleTaskView
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
index 530ec5a6c9fe..21b70b8e32da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
@@ -62,7 +62,7 @@ public class BubbleTaskViewHelper {
}
private final Context mContext;
- private final BubbleController mController;
+ private final BubbleExpandedViewManager mExpandedViewManager;
private final BubbleTaskViewHelper.Listener mListener;
private final View mParentView;
@@ -142,7 +142,8 @@ public class BubbleTaskViewHelper {
// the bubble again so we'll just remove it.
Log.w(TAG, "Exception while displaying bubble: " + getBubbleKey()
+ ", " + e.getMessage() + "; removing bubble");
- mController.removeBubble(getBubbleKey(), Bubbles.DISMISS_INVALID_INTENT);
+ mExpandedViewManager.removeBubble(
+ getBubbleKey(), Bubbles.DISMISS_INVALID_INTENT);
}
mInitialized = true;
});
@@ -175,7 +176,7 @@ public class BubbleTaskViewHelper {
ProtoLog.d(WM_SHELL_BUBBLES, "onTaskRemovalStarted: taskId=%d bubble=%s",
taskId, getBubbleKey());
if (mBubble != null) {
- mController.removeBubble(mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED);
+ mExpandedViewManager.removeBubble(mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED);
}
if (mTaskView != null) {
mTaskView.release();
@@ -186,19 +187,19 @@ public class BubbleTaskViewHelper {
@Override
public void onBackPressedOnTaskRoot(int taskId) {
- if (mTaskId == taskId && mController.isStackExpanded()) {
+ if (mTaskId == taskId && mExpandedViewManager.isStackExpanded()) {
mListener.onBackPressed();
}
}
};
public BubbleTaskViewHelper(Context context,
- BubbleController controller,
+ BubbleExpandedViewManager expandedViewManager,
BubbleTaskViewHelper.Listener listener,
BubbleTaskView bubbleTaskView,
View parent) {
mContext = context;
- mController = controller;
+ mExpandedViewManager = expandedViewManager;
mListener = listener;
mParentView = parent;
mTaskView = bubbleTaskView.getTaskView();
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 5fc10a9f6b69..69119cf4338e 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
@@ -70,7 +70,9 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
private Bubble mBubble;
private WeakReference<Context> mContext;
- private WeakReference<BubbleController> mController;
+ private WeakReference<BubbleExpandedViewManager> mExpandedViewManager;
+ private WeakReference<BubbleTaskViewFactory> mTaskViewFactory;
+ private WeakReference<BubblePositioner> mPositioner;
private WeakReference<BubbleStackView> mStackView;
private WeakReference<BubbleBarLayerView> mLayerView;
private BubbleIconFactory mIconFactory;
@@ -84,7 +86,9 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
*/
BubbleViewInfoTask(Bubble b,
Context context,
- BubbleController controller,
+ BubbleExpandedViewManager expandedViewManager,
+ BubbleTaskViewFactory taskViewFactory,
+ BubblePositioner positioner,
@Nullable BubbleStackView stackView,
@Nullable BubbleBarLayerView layerView,
BubbleIconFactory factory,
@@ -93,7 +97,9 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
Executor mainExecutor) {
mBubble = b;
mContext = new WeakReference<>(context);
- mController = new WeakReference<>(controller);
+ mExpandedViewManager = new WeakReference<>(expandedViewManager);
+ mTaskViewFactory = new WeakReference<>(taskViewFactory);
+ mPositioner = new WeakReference<>(positioner);
mStackView = new WeakReference<>(stackView);
mLayerView = new WeakReference<>(layerView);
mIconFactory = factory;
@@ -109,11 +115,13 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
return null;
}
if (mLayerView.get() != null) {
- return BubbleViewInfo.populateForBubbleBar(mContext.get(), mController.get(),
- mLayerView.get(), mIconFactory, mBubble, mSkipInflation);
+ return BubbleViewInfo.populateForBubbleBar(mContext.get(), mExpandedViewManager.get(),
+ mTaskViewFactory.get(), mPositioner.get(), mLayerView.get(), mIconFactory,
+ mBubble, mSkipInflation);
} else {
- return BubbleViewInfo.populate(mContext.get(), mController.get(), mStackView.get(),
- mIconFactory, mBubble, mSkipInflation);
+ return BubbleViewInfo.populate(mContext.get(), mExpandedViewManager.get(),
+ mTaskViewFactory.get(), mPositioner.get(), mStackView.get(), mIconFactory,
+ mBubble, mSkipInflation);
}
}
@@ -135,7 +143,7 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
}
private boolean verifyState() {
- if (mController.get().isShowingAsBubbleBar()) {
+ if (mExpandedViewManager.get().isShowingAsBubbleBar()) {
return mLayerView.get() != null;
} else {
return mStackView.get() != null;
@@ -167,18 +175,23 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
Bitmap badgeBitmap;
@Nullable
- public static BubbleViewInfo populateForBubbleBar(Context c, BubbleController controller,
- BubbleBarLayerView layerView, BubbleIconFactory iconFactory, Bubble b,
+ public static BubbleViewInfo populateForBubbleBar(Context c,
+ BubbleExpandedViewManager expandedViewManager,
+ BubbleTaskViewFactory taskViewFactory,
+ BubblePositioner positioner,
+ BubbleBarLayerView layerView,
+ BubbleIconFactory iconFactory,
+ Bubble b,
boolean skipInflation) {
BubbleViewInfo info = new BubbleViewInfo();
if (!skipInflation && !b.isInflated()) {
- BubbleTaskView bubbleTaskView = b.getOrCreateBubbleTaskView(c, controller);
+ BubbleTaskView bubbleTaskView = 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(
- controller, false /* isOverflow */, bubbleTaskView);
+ expandedViewManager, positioner, false /* isOverflow */, bubbleTaskView);
}
if (!populateCommonInfo(info, c, b, iconFactory)) {
@@ -191,8 +204,13 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
@VisibleForTesting
@Nullable
- public static BubbleViewInfo populate(Context c, BubbleController controller,
- BubbleStackView stackView, BubbleIconFactory iconFactory, Bubble b,
+ public static BubbleViewInfo populate(Context c,
+ BubbleExpandedViewManager expandedViewManager,
+ BubbleTaskViewFactory taskViewFactory,
+ BubblePositioner positioner,
+ BubbleStackView stackView,
+ BubbleIconFactory iconFactory,
+ Bubble b,
boolean skipInflation) {
BubbleViewInfo info = new BubbleViewInfo();
@@ -201,13 +219,14 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
LayoutInflater inflater = LayoutInflater.from(c);
info.imageView = (BadgedImageView) inflater.inflate(
R.layout.bubble_view, stackView, false /* attachToRoot */);
- info.imageView.initialize(controller.getPositioner());
+ info.imageView.initialize(positioner);
- BubbleTaskView bubbleTaskView = b.getOrCreateBubbleTaskView(c, controller);
+ BubbleTaskView bubbleTaskView = b.getOrCreateBubbleTaskView(taskViewFactory);
info.expandedView = (BubbleExpandedView) inflater.inflate(
R.layout.bubble_expanded_view, stackView, false /* attachToRoot */);
info.expandedView.initialize(
- controller, stackView, false /* isOverflow */, bubbleTaskView);
+ expandedViewManager, stackView, positioner, false /* isOverflow */,
+ bubbleTaskView);
}
if (!populateCommonInfo(info, c, b, iconFactory)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 73a9cf456a6e..ebb8e3e2d207 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -36,8 +36,9 @@ import android.widget.FrameLayout;
import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.wm.shell.R;
import com.android.wm.shell.bubbles.Bubble;
-import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.bubbles.BubbleExpandedViewManager;
import com.android.wm.shell.bubbles.BubbleOverflowContainerView;
+import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.bubbles.BubbleTaskView;
import com.android.wm.shell.bubbles.BubbleTaskViewHelper;
import com.android.wm.shell.bubbles.Bubbles;
@@ -45,11 +46,7 @@ import com.android.wm.shell.taskview.TaskView;
import java.util.function.Supplier;
-/**
- * Expanded view of a bubble when it's part of the bubble bar.
- *
- * {@link BubbleController#isShowingAsBubbleBar()}
- */
+/** Expanded view of a bubble when it's part of the bubble bar. */
public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskViewHelper.Listener {
/**
* The expanded view listener notifying the {@link BubbleBarLayerView} about the internal
@@ -67,7 +64,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
private static final String TAG = BubbleBarExpandedView.class.getSimpleName();
private static final int INVALID_TASK_ID = -1;
- private BubbleController mController;
+ private BubbleExpandedViewManager mManager;
private boolean mIsOverflow;
private BubbleTaskViewHelper mBubbleTaskViewHelper;
private BubbleBarMenuViewController mMenuViewController;
@@ -133,20 +130,22 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
mMenuViewController.hideMenu(false /* animated */);
}
- /** Set the BubbleController on the view, must be called before doing anything else. */
- public void initialize(BubbleController controller, boolean isOverflow,
+ /** Initializes the view, must be called before doing anything else. */
+ public void initialize(BubbleExpandedViewManager expandedViewManager,
+ BubblePositioner positioner,
+ boolean isOverflow,
@Nullable BubbleTaskView bubbleTaskView) {
- mController = controller;
+ mManager = expandedViewManager;
mIsOverflow = isOverflow;
if (mIsOverflow) {
mOverflowView = (BubbleOverflowContainerView) LayoutInflater.from(getContext()).inflate(
R.layout.bubble_overflow_container, null /* root */);
- mOverflowView.setBubbleController(mController);
+ mOverflowView.initialize(expandedViewManager, positioner);
addView(mOverflowView);
} else {
mTaskView = bubbleTaskView.getTaskView();
- mBubbleTaskViewHelper = new BubbleTaskViewHelper(mContext, mController,
+ mBubbleTaskViewHelper = new BubbleTaskViewHelper(mContext, expandedViewManager,
/* listener= */ this, bubbleTaskView,
/* viewParent= */ this);
if (mTaskView.getParent() != null) {
@@ -178,13 +177,13 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
@Override
public void onOpenAppSettings(Bubble bubble) {
- mController.collapseStack();
+ mManager.collapseStack();
mContext.startActivityAsUser(bubble.getSettingsIntent(mContext), bubble.getUser());
}
@Override
public void onDismissBubble(Bubble bubble) {
- mController.dismissBubble(bubble, Bubbles.DISMISS_USER_REMOVED);
+ mManager.dismissBubble(bubble, Bubbles.DISMISS_USER_REMOVED);
}
});
mHandleView.setOnClickListener(view -> {
@@ -279,7 +278,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
if (mMenuViewController.isMenuVisible()) {
mMenuViewController.hideMenu(/* animated = */ true);
} else {
- mController.collapseStack();
+ mManager.collapseStack();
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleOverflowTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleOverflowTest.java
index f5b0174642d1..094af9652ea3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleOverflowTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleOverflowTest.java
@@ -18,7 +18,6 @@ package com.android.wm.shell.bubbles;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -45,18 +44,22 @@ public class BubbleOverflowTest extends ShellTestCase {
private TestableBubblePositioner mPositioner;
private BubbleOverflow mOverflow;
+ private BubbleExpandedViewManager mExpandedViewManager;
@Mock
private BubbleController mBubbleController;
+ @Mock
+ private BubbleStackView mBubbleStackView;
@Before
- public void setUp() throws Exception {
+ public void setUp() {
MockitoAnnotations.initMocks(this);
+ mExpandedViewManager = BubbleExpandedViewManager.fromBubbleController(mBubbleController);
mPositioner = new TestableBubblePositioner(mContext,
mContext.getSystemService(WindowManager.class));
when(mBubbleController.getPositioner()).thenReturn(mPositioner);
- when(mBubbleController.getStackView()).thenReturn(mock(BubbleStackView.class));
+ when(mBubbleController.getStackView()).thenReturn(mBubbleStackView);
mOverflow = new BubbleOverflow(mContext, mPositioner);
}
@@ -65,7 +68,7 @@ public class BubbleOverflowTest extends ShellTestCase {
public void test_initialize_forStack() {
assertThat(mOverflow.getExpandedView()).isNull();
- mOverflow.initialize(mBubbleController, /* forBubbleBar= */ false);
+ mOverflow.initialize(mExpandedViewManager, mBubbleStackView, mPositioner);
assertThat(mOverflow.getExpandedView()).isNotNull();
assertThat(mOverflow.getExpandedView().getBubbleKey()).isEqualTo(BubbleOverflow.KEY);
@@ -74,7 +77,7 @@ public class BubbleOverflowTest extends ShellTestCase {
@Test
public void test_initialize_forBubbleBar() {
- mOverflow.initialize(mBubbleController, /* forBubbleBar= */ true);
+ mOverflow.initializeForBubbleBar(mExpandedViewManager, mPositioner);
assertThat(mOverflow.getBubbleBarExpandedView()).isNotNull();
assertThat(mOverflow.getExpandedView()).isNull();
@@ -82,11 +85,10 @@ public class BubbleOverflowTest extends ShellTestCase {
@Test
public void test_cleanUpExpandedState() {
- mOverflow.initialize(mBubbleController, /* forBubbleBar= */ false);
+ mOverflow.initialize(mExpandedViewManager, mBubbleStackView, mPositioner);
assertThat(mOverflow.getExpandedView()).isNotNull();
mOverflow.cleanUpExpandedState();
assertThat(mOverflow.getExpandedView()).isNull();
}
-
}
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 1668e3712462..ae39fbcb4eed 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
@@ -44,6 +44,7 @@ import com.android.wm.shell.common.TaskStackListenerImpl
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
@@ -55,6 +56,7 @@ import org.mockito.kotlin.doThrow
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
+import java.util.concurrent.Executor
/** Tests for loading / inflating views & icons for a bubble. */
@SmallTest
@@ -65,11 +67,16 @@ class BubbleViewInfoTest : ShellTestCase() {
private lateinit var metadataFlagListener: Bubbles.BubbleMetadataFlagListener
private lateinit var iconFactory: BubbleIconFactory
private lateinit var bubble: Bubble
-
private lateinit var bubbleController: BubbleController
private lateinit var mainExecutor: ShellExecutor
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>())
+ }
@Before
fun setup() {
@@ -88,7 +95,7 @@ class BubbleViewInfoTest : ShellTestCase() {
val shellInit = ShellInit(mainExecutor)
val shellCommandHandler = ShellCommandHandler()
val shellController = ShellController(context, shellInit, shellCommandHandler, mainExecutor)
- val bubblePositioner = BubblePositioner(context, windowManager)
+ bubblePositioner = BubblePositioner(context, windowManager)
val bubbleData =
BubbleData(
context,
@@ -143,6 +150,7 @@ class BubbleViewInfoTest : ShellTestCase() {
bubbleController,
mainExecutor
)
+ expandedViewManager = BubbleExpandedViewManager.fromBubbleController(bubbleController)
bubbleBarLayerView = BubbleBarLayerView(context, bubbleController, bubbleData)
}
@@ -152,7 +160,9 @@ class BubbleViewInfoTest : ShellTestCase() {
val info =
BubbleViewInfoTask.BubbleViewInfo.populate(
context,
- bubbleController,
+ expandedViewManager,
+ bubbleTaskViewFactory,
+ bubblePositioner,
bubbleStackView,
iconFactory,
bubble,
@@ -178,7 +188,9 @@ class BubbleViewInfoTest : ShellTestCase() {
val info =
BubbleViewInfoTask.BubbleViewInfo.populateForBubbleBar(
context,
- bubbleController,
+ expandedViewManager,
+ bubbleTaskViewFactory,
+ bubblePositioner,
bubbleBarLayerView,
iconFactory,
bubble,
@@ -212,7 +224,9 @@ class BubbleViewInfoTest : ShellTestCase() {
val info =
BubbleViewInfoTask.BubbleViewInfo.populateForBubbleBar(
context,
- bubbleController,
+ expandedViewManager,
+ bubbleTaskViewFactory,
+ bubblePositioner,
bubbleBarLayerView,
iconFactory,
bubble,
diff --git a/libs/hwui/apex/android_paint.cpp b/libs/hwui/apex/android_paint.cpp
index cc79cba5e19c..5e73e7628568 100644
--- a/libs/hwui/apex/android_paint.cpp
+++ b/libs/hwui/apex/android_paint.cpp
@@ -14,12 +14,13 @@
* limitations under the License.
*/
-#include "android/graphics/paint.h"
+#include <SkBlendMode.h>
+#include <SkImageFilter.h>
+#include <hwui/Paint.h>
#include "TypeCast.h"
-
-#include <hwui/Paint.h>
-#include <SkBlendMode.h>
+#include "android/graphics/paint.h"
+#include "include/effects/SkImageFilters.h"
using namespace android;
@@ -43,6 +44,22 @@ static SkBlendMode convertBlendMode(ABlendMode blendMode) {
}
}
+static sk_sp<SkImageFilter> convertImageFilter(AImageFilter imageFilter) {
+ switch (imageFilter) {
+ case AIMAGE_FILTER_DROP_SHADOW_FOR_POINTER_ICON:
+ // Material Elevation Level 1 Drop Shadow.
+ sk_sp<SkImageFilter> key_shadow = SkImageFilters::DropShadow(
+ 0.0f, 1.0f, 2.0f, 2.0f, SkColorSetARGB(0x4D, 0x00, 0x00, 0x00), nullptr);
+ sk_sp<SkImageFilter> ambient_shadow = SkImageFilters::DropShadow(
+ 0.0f, 1.0f, 3.0f, 3.0f, SkColorSetARGB(0x26, 0x00, 0x00, 0x00), nullptr);
+ return SkImageFilters::Compose(ambient_shadow, key_shadow);
+ }
+}
+
void APaint_setBlendMode(APaint* paint, ABlendMode blendMode) {
TypeCast::toPaint(paint)->setBlendMode(convertBlendMode(blendMode));
}
+
+void APaint_setImageFilter(APaint* paint, AImageFilter imageFilter) {
+ TypeCast::toPaint(paint)->setImageFilter(convertImageFilter(imageFilter));
+}
diff --git a/libs/hwui/apex/include/android/graphics/paint.h b/libs/hwui/apex/include/android/graphics/paint.h
index 058db8d37619..36b7575d585d 100644
--- a/libs/hwui/apex/include/android/graphics/paint.h
+++ b/libs/hwui/apex/include/android/graphics/paint.h
@@ -26,6 +26,14 @@ __BEGIN_DECLS
*/
typedef struct APaint APaint;
+/**
+ * Predefined Image filter type.
+ */
+enum AImageFilter {
+ /** Drop shadow image filter for PointerIcons. */
+ AIMAGE_FILTER_DROP_SHADOW_FOR_POINTER_ICON = 0,
+};
+
/** Bitmap pixel format. */
enum ABlendMode {
/** replaces destination with zero: fully transparent */
@@ -42,6 +50,8 @@ ANDROID_API void APaint_destroyPaint(APaint* paint);
ANDROID_API void APaint_setBlendMode(APaint* paint, ABlendMode blendMode);
+ANDROID_API void APaint_setImageFilter(APaint* paint, AImageFilter imageFilter);
+
__END_DECLS
#ifdef __cplusplus
@@ -54,6 +64,10 @@ namespace graphics {
void setBlendMode(ABlendMode blendMode) { APaint_setBlendMode(mPaint, blendMode); }
+ void setImageFilter(AImageFilter imageFilter) {
+ APaint_setImageFilter(mPaint, imageFilter);
+ }
+
const APaint& get() const { return *mPaint; }
private:
diff --git a/libs/hwui/libhwui.map.txt b/libs/hwui/libhwui.map.txt
index fdb237387098..d03ceb471d6c 100644
--- a/libs/hwui/libhwui.map.txt
+++ b/libs/hwui/libhwui.map.txt
@@ -32,6 +32,7 @@ LIBHWUI { # platform-only /* HWUI isn't current a module, so all of these are st
APaint_createPaint;
APaint_destroyPaint;
APaint_setBlendMode;
+ APaint_setImageFilter;
ARegionIterator_acquireIterator;
ARegionIterator_releaseIterator;
ARegionIterator_isComplex;
diff --git a/libs/input/SpriteIcon.cpp b/libs/input/SpriteIcon.cpp
index b7e51e22a214..59e36e4b0d1e 100644
--- a/libs/input/SpriteIcon.cpp
+++ b/libs/input/SpriteIcon.cpp
@@ -34,6 +34,9 @@ bool SpriteIcon::draw(sp<Surface> surface) const {
graphics::Paint paint;
paint.setBlendMode(ABLEND_MODE_SRC);
+ if (drawNativeDropShadow) {
+ paint.setImageFilter(AIMAGE_FILTER_DROP_SHADOW_FOR_POINTER_ICON);
+ }
graphics::Canvas canvas(outBuffer, (int32_t)surface->getBuffersDataSpace());
canvas.drawBitmap(bitmap, 0, 0, &paint);
diff --git a/libs/input/SpriteIcon.h b/libs/input/SpriteIcon.h
index 5f085bbd2374..9e6cc81f0bb4 100644
--- a/libs/input/SpriteIcon.h
+++ b/libs/input/SpriteIcon.h
@@ -29,16 +29,22 @@ namespace android {
struct SpriteIcon {
inline SpriteIcon() : style(PointerIconStyle::TYPE_NULL), hotSpotX(0), hotSpotY(0) {}
inline SpriteIcon(const graphics::Bitmap& bitmap, PointerIconStyle style, float hotSpotX,
- float hotSpotY)
- : bitmap(bitmap), style(style), hotSpotX(hotSpotX), hotSpotY(hotSpotY) {}
+ float hotSpotY, bool drawNativeDropShadow)
+ : bitmap(bitmap),
+ style(style),
+ hotSpotX(hotSpotX),
+ hotSpotY(hotSpotY),
+ drawNativeDropShadow(drawNativeDropShadow) {}
graphics::Bitmap bitmap;
PointerIconStyle style;
float hotSpotX;
float hotSpotY;
+ bool drawNativeDropShadow;
inline SpriteIcon copy() const {
- return SpriteIcon(bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888), style, hotSpotX, hotSpotY);
+ return SpriteIcon(bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888), style, hotSpotX, hotSpotY,
+ drawNativeDropShadow);
}
inline void reset() {
@@ -46,6 +52,7 @@ struct SpriteIcon {
style = PointerIconStyle::TYPE_NULL;
hotSpotX = 0;
hotSpotY = 0;
+ drawNativeDropShadow = false;
}
inline bool isValid() const { return bitmap.isValid() && !bitmap.isEmpty(); }