Interface to represent overflow as bubble
Bug: 138116789 Test: manual - bubble behavior remains the same Test: atest SystemUITests Change-Id: I8c17ab9cddba5e3072274d57382d81657e47f7b8
This commit is contained in:
@@ -38,9 +38,11 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.shared.system.SysUiStatsLog;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -50,7 +52,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Encapsulates the data and UI elements of a bubble.
|
||||
*/
|
||||
class Bubble {
|
||||
class Bubble implements BubbleViewProvider {
|
||||
private static final String TAG = "Bubble";
|
||||
|
||||
private NotificationEntry mEntry;
|
||||
@@ -148,12 +150,12 @@ class Bubble {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
BadgedImageView getIconView() {
|
||||
public BadgedImageView getIconView() {
|
||||
return mIconView;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
BubbleExpandedView getExpandedView() {
|
||||
public BubbleExpandedView getExpandedView() {
|
||||
return mExpandedView;
|
||||
}
|
||||
|
||||
@@ -238,7 +240,7 @@ class Bubble {
|
||||
* Note that this contents visibility doesn't affect visibility at {@link android.view.View},
|
||||
* and setting {@code false} actually means rendering the expanded view in transparent.
|
||||
*/
|
||||
void setContentVisibility(boolean visibility) {
|
||||
public void setContentVisibility(boolean visibility) {
|
||||
if (mExpandedView != null) {
|
||||
mExpandedView.setContentVisibility(visibility);
|
||||
}
|
||||
@@ -481,4 +483,36 @@ class Bubble {
|
||||
public int hashCode() {
|
||||
return Objects.hash(mKey);
|
||||
}
|
||||
|
||||
public void logUIEvent(int bubbleCount, int action, float normalX, float normalY, int index) {
|
||||
if (this.getEntry() == null
|
||||
|| this.getEntry().getSbn() == null) {
|
||||
SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
|
||||
null /* package name */,
|
||||
null /* notification channel */,
|
||||
0 /* notification ID */,
|
||||
0 /* bubble position */,
|
||||
bubbleCount,
|
||||
action,
|
||||
normalX,
|
||||
normalY,
|
||||
false /* unread bubble */,
|
||||
false /* on-going bubble */,
|
||||
false /* isAppForeground (unused) */);
|
||||
} else {
|
||||
StatusBarNotification notification = this.getEntry().getSbn();
|
||||
SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
|
||||
notification.getPackageName(),
|
||||
notification.getNotification().getChannelId(),
|
||||
notification.getId(),
|
||||
index,
|
||||
bubbleCount,
|
||||
action,
|
||||
normalX,
|
||||
normalY,
|
||||
this.showInShade(),
|
||||
this.isOngoing(),
|
||||
false /* isAppForeground (unused) */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.systemui.bubbles;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
/**
|
||||
* Class for showing aged out bubbles.
|
||||
*/
|
||||
public class BubbleOverflow implements BubbleViewProvider {
|
||||
|
||||
private ImageView mOverflowBtn;
|
||||
private BubbleExpandedView mOverflowExpandedView;
|
||||
private LayoutInflater mInflater;
|
||||
private Context mContext;
|
||||
|
||||
public BubbleOverflow(Context context) {
|
||||
mContext = context;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
public void setUpOverflow(ViewGroup parentViewGroup) {
|
||||
mOverflowExpandedView = (BubbleExpandedView) mInflater.inflate(
|
||||
R.layout.bubble_expanded_view, parentViewGroup /* root */,
|
||||
false /* attachToRoot */);
|
||||
mOverflowExpandedView.setOverflow(true);
|
||||
|
||||
mOverflowBtn = (ImageView) mInflater.inflate(R.layout.bubble_overflow_button,
|
||||
parentViewGroup /* root */,
|
||||
false /* attachToRoot */);
|
||||
|
||||
setOverflowBtnTheme();
|
||||
mOverflowBtn.setVisibility(GONE);
|
||||
}
|
||||
|
||||
ImageView getBtn() {
|
||||
return mOverflowBtn;
|
||||
}
|
||||
|
||||
void setBtnVisible(int visible) {
|
||||
mOverflowBtn.setVisibility(visible);
|
||||
}
|
||||
|
||||
// TODO(b/149146374) Propagate theme change to bubbles in overflow.
|
||||
void setOverflowBtnTheme() {
|
||||
TypedArray ta = mContext.obtainStyledAttributes(
|
||||
new int[]{android.R.attr.colorBackgroundFloating});
|
||||
int bgColor = ta.getColor(0, Color.WHITE /* default */);
|
||||
ta.recycle();
|
||||
|
||||
InsetDrawable fg = new InsetDrawable(mOverflowBtn.getDrawable(), 28);
|
||||
ColorDrawable bg = new ColorDrawable(bgColor);
|
||||
AdaptiveIconDrawable adaptiveIcon = new AdaptiveIconDrawable(bg, fg);
|
||||
mOverflowBtn.setImageDrawable(adaptiveIcon);
|
||||
}
|
||||
|
||||
|
||||
public BubbleExpandedView getExpandedView() {
|
||||
return mOverflowExpandedView;
|
||||
}
|
||||
|
||||
public void setContentVisibility(boolean visible) {
|
||||
mOverflowExpandedView.setContentVisibility(visible);
|
||||
}
|
||||
|
||||
public void logUIEvent(int bubbleCount, int action, float normalX, float normalY,
|
||||
int index) {
|
||||
// TODO(b/149133814) Log overflow UI events.
|
||||
}
|
||||
|
||||
public View getIconView() {
|
||||
return mOverflowBtn;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return BubbleOverflowActivity.KEY;
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import javax.inject.Inject;
|
||||
* Must be public to be accessible to androidx...AppComponentFactory
|
||||
*/
|
||||
public class BubbleOverflowActivity extends Activity {
|
||||
public static final String KEY = "Overflow";
|
||||
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleOverflowActivity" : TAG_BUBBLES;
|
||||
|
||||
private LinearLayout mEmptyState;
|
||||
|
||||
@@ -33,8 +33,6 @@ import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorMatrix;
|
||||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.graphics.Paint;
|
||||
@@ -42,13 +40,9 @@ import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
import android.view.Choreographer;
|
||||
import android.view.DisplayCutout;
|
||||
@@ -63,7 +57,6 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -199,7 +192,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
private int mPointerHeight;
|
||||
private int mStatusBarHeight;
|
||||
private int mImeOffset;
|
||||
private Bubble mExpandedBubble;
|
||||
private BubbleViewProvider mExpandedBubble;
|
||||
private boolean mIsExpanded;
|
||||
|
||||
/** Whether the stack is currently on the left side of the screen, or animating there. */
|
||||
@@ -322,8 +315,8 @@ public class BubbleStackView extends FrameLayout {
|
||||
private Runnable mAfterMagnet;
|
||||
|
||||
private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||
private BubbleExpandedView mOverflowExpandedView;
|
||||
private ImageView mOverflowBtn;
|
||||
|
||||
private BubbleOverflow mBubbleOverflow;
|
||||
|
||||
public BubbleStackView(Context context, BubbleData data,
|
||||
@Nullable SurfaceSynchronizer synchronizer) {
|
||||
@@ -333,7 +326,6 @@ public class BubbleStackView extends FrameLayout {
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mTouchHandler = new BubbleTouchHandler(this, data, context);
|
||||
setOnTouchListener(mTouchHandler);
|
||||
mInflater = LayoutInflater.from(context);
|
||||
|
||||
Resources res = getResources();
|
||||
mMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered);
|
||||
@@ -407,12 +399,8 @@ public class BubbleStackView extends FrameLayout {
|
||||
.setStiffness(SpringForce.STIFFNESS_LOW)
|
||||
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
|
||||
mExpandedViewYAnim.addEndListener((anim, cancelled, value, velocity) -> {
|
||||
if (mIsExpanded) {
|
||||
if (mExpandedBubble == null) {
|
||||
mOverflowExpandedView.updateView();
|
||||
} else {
|
||||
mExpandedBubble.getExpandedView().updateView();
|
||||
}
|
||||
if (mIsExpanded && mExpandedBubble != null) {
|
||||
mExpandedBubble.getExpandedView().updateView();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -420,8 +408,12 @@ public class BubbleStackView extends FrameLayout {
|
||||
setFocusable(true);
|
||||
mBubbleContainer.bringToFront();
|
||||
|
||||
mBubbleOverflow = new BubbleOverflow(mContext);
|
||||
if (BubbleExperimentConfig.allowBubbleOverflow(mContext)) {
|
||||
setUpOverflow();
|
||||
mBubbleOverflow.setUpOverflow(this);
|
||||
mBubbleContainer.addView(mBubbleOverflow.getBtn(), 0,
|
||||
new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
|
||||
}
|
||||
|
||||
setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
|
||||
@@ -432,9 +424,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
// Update the insets after we're done translating otherwise position
|
||||
// calculation for them won't be correct.
|
||||
() -> {
|
||||
if (mExpandedBubble == null) {
|
||||
mOverflowExpandedView.updateInsets(insets);
|
||||
} else {
|
||||
if (mExpandedBubble != null) {
|
||||
mExpandedBubble.getExpandedView().updateInsets(insets);
|
||||
}
|
||||
});
|
||||
@@ -449,9 +439,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
// Reposition & adjust the height for new orientation
|
||||
if (mIsExpanded) {
|
||||
mExpandedViewContainer.setTranslationY(getExpandedViewY());
|
||||
if (mExpandedBubble == null) {
|
||||
mOverflowExpandedView.updateView();
|
||||
} else {
|
||||
if (mExpandedBubble != null) {
|
||||
mExpandedBubble.getExpandedView().updateView();
|
||||
}
|
||||
}
|
||||
@@ -516,40 +504,8 @@ public class BubbleStackView extends FrameLayout {
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpOverflow() {
|
||||
mOverflowExpandedView = (BubbleExpandedView) mInflater.inflate(
|
||||
R.layout.bubble_expanded_view, this /* root */, false /* attachToRoot */);
|
||||
mOverflowExpandedView.setOverflow(true);
|
||||
|
||||
mOverflowBtn = (ImageView) mInflater.inflate(R.layout.bubble_overflow_button,
|
||||
this /* root */,
|
||||
false /* attachToRoot */);
|
||||
|
||||
mBubbleContainer.addView(mOverflowBtn, 0,
|
||||
new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
|
||||
setOverflowBtnTheme();
|
||||
mOverflowBtn.setVisibility(GONE);
|
||||
}
|
||||
|
||||
// TODO(b/149146374) Propagate theme change to bubbles in overflow.
|
||||
private void setOverflowBtnTheme() {
|
||||
TypedArray ta = mContext.obtainStyledAttributes(
|
||||
new int[]{android.R.attr.colorBackgroundFloating});
|
||||
int bgColor = ta.getColor(0, Color.WHITE /* default */);
|
||||
ta.recycle();
|
||||
|
||||
InsetDrawable fg = new InsetDrawable(mOverflowBtn.getDrawable(), 28);
|
||||
ColorDrawable bg = new ColorDrawable(bgColor);
|
||||
AdaptiveIconDrawable adaptiveIcon = new AdaptiveIconDrawable(bg, fg);
|
||||
mOverflowBtn.setImageDrawable(adaptiveIcon);
|
||||
}
|
||||
|
||||
void showExpandedViewContents(int displayId) {
|
||||
if (mOverflowExpandedView != null
|
||||
&& mOverflowExpandedView.getVirtualDisplayId() == displayId) {
|
||||
mOverflowExpandedView.setContentVisibility(true);
|
||||
} else if (mExpandedBubble != null
|
||||
if (mExpandedBubble != null
|
||||
&& mExpandedBubble.getExpandedView().getVirtualDisplayId() == displayId) {
|
||||
mExpandedBubble.setContentVisibility(true);
|
||||
}
|
||||
@@ -573,7 +529,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
public void onThemeChanged() {
|
||||
setUpFlyout();
|
||||
if (BubbleExperimentConfig.allowBubbleOverflow(mContext)) {
|
||||
setOverflowBtnTheme();
|
||||
mBubbleOverflow.setOverflowBtnTheme();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -756,15 +712,22 @@ public class BubbleStackView extends FrameLayout {
|
||||
/**
|
||||
* The {@link BadgedImageView} that is expanded, null if one does not exist.
|
||||
*/
|
||||
BadgedImageView getExpandedBubbleView() {
|
||||
View getExpandedBubbleView() {
|
||||
return mExpandedBubble != null ? mExpandedBubble.getIconView() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link Bubble} that is expanded, null if one does not exist.
|
||||
*/
|
||||
@Nullable
|
||||
Bubble getExpandedBubble() {
|
||||
return mExpandedBubble;
|
||||
if (mExpandedBubble == null
|
||||
|| (BubbleExperimentConfig.allowBubbleOverflow(mContext)
|
||||
&& mExpandedBubble.getIconView() == mBubbleOverflow.getBtn()
|
||||
&& mExpandedBubble.getKey() == BubbleOverflowActivity.KEY)) {
|
||||
return null;
|
||||
}
|
||||
return (Bubble) mExpandedBubble;
|
||||
}
|
||||
|
||||
// via BubbleData.Listener
|
||||
@@ -818,7 +781,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
if (DEBUG_BUBBLE_STACK_VIEW) {
|
||||
Log.d(TAG, "Show overflow button.");
|
||||
}
|
||||
mOverflowBtn.setVisibility(VISIBLE);
|
||||
mBubbleOverflow.setBtnVisible(VISIBLE);
|
||||
if (apply) {
|
||||
mExpandedAnimationController.expandFromStack(() -> {
|
||||
updatePointerPosition();
|
||||
@@ -828,7 +791,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
if (DEBUG_BUBBLE_STACK_VIEW) {
|
||||
Log.d(TAG, "Collapsed. Hide overflow button.");
|
||||
}
|
||||
mOverflowBtn.setVisibility(GONE);
|
||||
mBubbleOverflow.setBtnVisible(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -849,7 +812,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
}
|
||||
|
||||
void showOverflow() {
|
||||
setSelectedBubble(null);
|
||||
setSelectedBubble(mBubbleOverflow);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -858,14 +821,14 @@ public class BubbleStackView extends FrameLayout {
|
||||
* position of any bubble.
|
||||
*/
|
||||
// via BubbleData.Listener
|
||||
public void setSelectedBubble(@Nullable Bubble bubbleToSelect) {
|
||||
public void setSelectedBubble(@Nullable BubbleViewProvider bubbleToSelect) {
|
||||
if (DEBUG_BUBBLE_STACK_VIEW) {
|
||||
Log.d(TAG, "setSelectedBubble: " + bubbleToSelect);
|
||||
}
|
||||
if (mExpandedBubble != null && mExpandedBubble.equals(bubbleToSelect)) {
|
||||
return;
|
||||
}
|
||||
final Bubble previouslySelected = mExpandedBubble;
|
||||
final BubbleViewProvider previouslySelected = mExpandedBubble;
|
||||
mExpandedBubble = bubbleToSelect;
|
||||
|
||||
if (mIsExpanded) {
|
||||
@@ -874,14 +837,11 @@ public class BubbleStackView extends FrameLayout {
|
||||
// expanded view becomes visible on the screen. See b/126856255
|
||||
mExpandedViewContainer.setAlpha(0.0f);
|
||||
mSurfaceSynchronizer.syncSurfaceAndRun(() -> {
|
||||
if (previouslySelected == null) {
|
||||
mOverflowExpandedView.setContentVisibility(false);
|
||||
} else {
|
||||
previouslySelected.setContentVisibility(false);
|
||||
}
|
||||
previouslySelected.setContentVisibility(false);
|
||||
updateExpandedBubble();
|
||||
updatePointerPosition();
|
||||
requestUpdate();
|
||||
|
||||
logBubbleEvent(previouslySelected,
|
||||
SysUiStatsLog.BUBBLE_UICHANGED__ACTION__COLLAPSED);
|
||||
logBubbleEvent(bubbleToSelect, SysUiStatsLog.BUBBLE_UICHANGED__ACTION__EXPANDED);
|
||||
@@ -941,8 +901,8 @@ public class BubbleStackView extends FrameLayout {
|
||||
if (mIsExpanded) {
|
||||
if (isIntersecting(mBubbleContainer, x, y)) {
|
||||
if (BubbleExperimentConfig.allowBubbleOverflow(mContext)
|
||||
&& isIntersecting(mOverflowBtn, x, y)) {
|
||||
return mOverflowBtn;
|
||||
&& isIntersecting(mBubbleOverflow.getBtn(), x, y)) {
|
||||
return mBubbleOverflow.getBtn();
|
||||
}
|
||||
// Could be tapping or dragging a bubble while expanded
|
||||
for (int i = 0; i < getBubbleCount(); i++) {
|
||||
@@ -1030,7 +990,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
|
||||
private void animateCollapse() {
|
||||
mIsExpanded = false;
|
||||
final Bubble previouslySelected = mExpandedBubble;
|
||||
final BubbleViewProvider previouslySelected = mExpandedBubble;
|
||||
beforeExpandedViewAnimation();
|
||||
|
||||
if (DEBUG_BUBBLE_STACK_VIEW) {
|
||||
@@ -1046,11 +1006,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
() -> {
|
||||
mBubbleContainer.setActiveController(mStackAnimationController);
|
||||
afterExpandedViewAnimation();
|
||||
if (previouslySelected == null) {
|
||||
mOverflowExpandedView.setContentVisibility(false);
|
||||
} else {
|
||||
previouslySelected.setContentVisibility(false);
|
||||
}
|
||||
previouslySelected.setContentVisibility(false);
|
||||
});
|
||||
|
||||
mExpandedViewXAnim.animateToFinalPosition(getCollapsedX());
|
||||
@@ -1093,7 +1049,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
mExpandedAnimateYDistance);
|
||||
}
|
||||
|
||||
private void notifyExpansionChanged(Bubble bubble, boolean expanded) {
|
||||
private void notifyExpansionChanged(BubbleViewProvider bubble, boolean expanded) {
|
||||
if (mExpandListener != null && bubble != null) {
|
||||
mExpandListener.onBubbleExpandChanged(expanded, bubble.getKey());
|
||||
}
|
||||
@@ -1613,11 +1569,8 @@ public class BubbleStackView extends FrameLayout {
|
||||
Log.d(TAG, "updateExpandedBubble()");
|
||||
}
|
||||
mExpandedViewContainer.removeAllViews();
|
||||
if (mIsExpanded) {
|
||||
BubbleExpandedView bev = mOverflowExpandedView;
|
||||
if (mExpandedBubble != null) {
|
||||
bev = mExpandedBubble.getExpandedView();
|
||||
}
|
||||
if (mIsExpanded && mExpandedBubble != null) {
|
||||
BubbleExpandedView bev = mExpandedBubble.getExpandedView();
|
||||
mExpandedViewContainer.addView(bev);
|
||||
bev.populateExpandedView();
|
||||
mExpandedViewContainer.setVisibility(VISIBLE);
|
||||
@@ -1636,9 +1589,7 @@ public class BubbleStackView extends FrameLayout {
|
||||
if (!mExpandedViewYAnim.isRunning()) {
|
||||
// We're not animating so set the value
|
||||
mExpandedViewContainer.setTranslationY(y);
|
||||
if (mExpandedBubble == null) {
|
||||
mOverflowExpandedView.updateView();
|
||||
} else {
|
||||
if (mExpandedBubble != null) {
|
||||
mExpandedBubble.getExpandedView().updateView();
|
||||
}
|
||||
} else {
|
||||
@@ -1693,15 +1644,16 @@ public class BubbleStackView extends FrameLayout {
|
||||
/**
|
||||
* Finds the bubble index within the stack.
|
||||
*
|
||||
* @param bubble the bubble to look up.
|
||||
* @param provider the bubble view provider with the bubble to look up.
|
||||
* @return the index of the bubble view within the bubble stack. The range of the position
|
||||
* is between 0 and the bubble count minus 1.
|
||||
*/
|
||||
int getBubbleIndex(@Nullable Bubble bubble) {
|
||||
if (bubble == null) {
|
||||
int getBubbleIndex(@Nullable BubbleViewProvider provider) {
|
||||
if (provider == null || provider.getKey() == BubbleOverflowActivity.KEY) {
|
||||
return 0;
|
||||
}
|
||||
return mBubbleContainer.indexOfChild(bubble.getIconView());
|
||||
Bubble b = (Bubble) provider;
|
||||
return mBubbleContainer.indexOfChild(b.getIconView());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1733,36 +1685,12 @@ public class BubbleStackView extends FrameLayout {
|
||||
* the user interaction is not specific to one bubble.
|
||||
* @param action the user interaction enum.
|
||||
*/
|
||||
private void logBubbleEvent(@Nullable Bubble bubble, int action) {
|
||||
if (bubble == null || bubble.getEntry() == null
|
||||
|| bubble.getEntry().getSbn() == null) {
|
||||
SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
|
||||
null /* package name */,
|
||||
null /* notification channel */,
|
||||
0 /* notification ID */,
|
||||
0 /* bubble position */,
|
||||
getBubbleCount(),
|
||||
action,
|
||||
getNormalizedXPosition(),
|
||||
getNormalizedYPosition(),
|
||||
false /* unread bubble */,
|
||||
false /* on-going bubble */,
|
||||
false /* isAppForeground (unused) */);
|
||||
} else {
|
||||
StatusBarNotification notification = bubble.getEntry().getSbn();
|
||||
SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
|
||||
notification.getPackageName(),
|
||||
notification.getNotification().getChannelId(),
|
||||
notification.getId(),
|
||||
getBubbleIndex(bubble),
|
||||
getBubbleCount(),
|
||||
action,
|
||||
getNormalizedXPosition(),
|
||||
getNormalizedYPosition(),
|
||||
bubble.showInShade(),
|
||||
bubble.isOngoing(),
|
||||
false /* isAppForeground (unused) */);
|
||||
private void logBubbleEvent(@Nullable BubbleViewProvider bubble, int action) {
|
||||
if (bubble == null) {
|
||||
return;
|
||||
}
|
||||
bubble.logUIEvent(getBubbleCount(), action, getNormalizedXPosition(),
|
||||
getNormalizedYPosition(), getBubbleIndex(bubble));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1770,14 +1698,10 @@ public class BubbleStackView extends FrameLayout {
|
||||
* a back key down/up event pair is forwarded to the bubble Activity.
|
||||
*/
|
||||
boolean performBackPressIfNeeded() {
|
||||
if (!isExpanded()) {
|
||||
if (!isExpanded() || mExpandedBubble == null) {
|
||||
return false;
|
||||
}
|
||||
if (mExpandedBubble == null) {
|
||||
return mOverflowExpandedView.performBackPressIfNeeded();
|
||||
} else {
|
||||
return mExpandedBubble.getExpandedView().performBackPressIfNeeded();
|
||||
}
|
||||
return mExpandedBubble.getExpandedView().performBackPressIfNeeded();
|
||||
}
|
||||
|
||||
/** For debugging only */
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.systemui.bubbles;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Interface to represent actual Bubbles and UI elements that act like bubbles, like BubbleOverflow.
|
||||
*/
|
||||
interface BubbleViewProvider {
|
||||
BubbleExpandedView getExpandedView();
|
||||
void setContentVisibility(boolean visible);
|
||||
View getIconView();
|
||||
void logUIEvent(int bubbleCount, int action, float normalX, float normalY, int index);
|
||||
String getKey();
|
||||
}
|
||||
Reference in New Issue
Block a user