Add logging for bubble UI events.

Bug: 123543171
Test: manual on local device using statsd_testdrive
Change-Id: I4d344d94e39f52fdd743b99390616c23c86a3a45
This commit is contained in:
Steven Wu
2019-01-29 11:30:39 -05:00
parent 6f6ab37890
commit a254dabcc8
2 changed files with 88 additions and 0 deletions

View File

@@ -5263,6 +5263,7 @@ message BubbleUIChanged {
PERMISSION_IGNORED = 12;
SWIPE_LEFT = 13;
SWIPE_RIGHT = 14;
STACK_EXPANDED = 15;
}
optional Action action = 6;

View File

@@ -27,7 +27,9 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.util.StatsLog;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -54,6 +56,9 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* Renders bubbles in a stack and handles animating expanded and collapsed states.
*/
@@ -240,16 +245,20 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
// Previously expanded, notify that this bubble is no longer expanded
notifyExpansionChanged(mExpandedBubble, false /* expanded */);
}
BubbleView prevBubble = mExpandedBubble;
mExpandedBubble = bubbleToExpand;
if (!mIsExpanded) {
// If we weren't previously expanded we should animate open.
animateExpansion(true /* expand */);
logBubbleEvent(mExpandedBubble, StatsLog.BUBBLE_UICHANGED__ACTION__EXPANDED);
} else {
// Otherwise just update the views
// TODO: probably animate / page to expanded one
updateExpandedBubble();
updatePointerPosition();
requestUpdate();
logBubbleEvent(prevBubble, StatsLog.BUBBLE_UICHANGED__ACTION__COLLAPSED);
logBubbleEvent(mExpandedBubble, StatsLog.BUBBLE_UICHANGED__ACTION__EXPANDED);
}
mExpandedBubble.getEntry().setShowInShadeWhenBubble(false);
notifyExpansionChanged(mExpandedBubble, true /* expanded */);
@@ -278,6 +287,7 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
ViewClippingUtil.setClippingDeactivated(bubbleView, true, mClippingParameters);
requestUpdate();
logBubbleEvent(bubbleView, StatsLog.BUBBLE_UICHANGED__ACTION__POSTED);
}
/**
@@ -300,6 +310,7 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
if (wasExpanded != mIsExpanded) {
notifyExpansionChanged(mExpandedBubble, mIsExpanded);
}
logBubbleEvent(bubbleView, StatsLog.BUBBLE_UICHANGED__ACTION__DISMISSED);
}
/**
@@ -308,6 +319,8 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
public void stackDismissed() {
collapseStack();
mBubbleContainer.removeAllViews();
logBubbleEvent(null /* no bubble associated with bubble stack dismiss */,
StatsLog.BUBBLE_UICHANGED__ACTION__STACK_DISMISSED);
}
/**
@@ -331,6 +344,7 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
entry.setShowInShadeWhenBubble(false);
requestUpdate();
}
logBubbleEvent(bubbleView, StatsLog.BUBBLE_UICHANGED__ACTION__UPDATED);
}
/**
@@ -366,6 +380,7 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
// TODO: Save opened bubble & move it to top of stack
animateExpansion(false /* shouldExpand */);
notifyExpansionChanged(mExpandedBubble, mIsExpanded);
logBubbleEvent(mExpandedBubble, StatsLog.BUBBLE_UICHANGED__ACTION__COLLAPSED);
}
}
@@ -382,6 +397,7 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
if (!mIsExpanded) {
mExpandedBubble = getTopBubble();
setExpandedBubble(mExpandedBubble);
logBubbleEvent(mExpandedBubble, StatsLog.BUBBLE_UICHANGED__ACTION__STACK_EXPANDED);
}
}
@@ -574,6 +590,9 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
.setStiffness(SpringForce.STIFFNESS_LOW)
.setDampingRatio(SPRING_DAMPING_RATIO),
/* destination */ null);
logBubbleEvent(null /* no bubble associated with bubble stack move */,
StatsLog.BUBBLE_UICHANGED__ACTION__STACK_MOVED);
}
/**
@@ -733,4 +752,72 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F
viewState.headsUpIsVisible = false;
viewState.applyToView(view);
}
/**
* @return the number of bubbles in the stack view.
*/
private int getBubbleCount() {
return mBubbleContainer.getChildCount();
}
/**
* Finds the bubble index within the stack.
*
* @param bubbleView the view of the bubble.
* @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.
*/
private int getBubbleIndex(BubbleView bubbleView) {
return mBubbleContainer.indexOfChild(bubbleView);
}
/**
* @return the normalized x-axis position of the bubble stack rounded to 4 decimal places.
*/
private float getNormalizedXPosition() {
return new BigDecimal(getPosition().x / mDisplaySize.x)
.setScale(4, RoundingMode.CEILING.HALF_UP)
.floatValue();
}
/**
* @return the normalized y-axis position of the bubble stack rounded to 4 decimal places.
*/
private float getNormalizedYPosition() {
return new BigDecimal(getPosition().y / mDisplaySize.y)
.setScale(4, RoundingMode.CEILING.HALF_UP)
.floatValue();
}
/**
* Logs the bubble UI event.
*
* @param bubble the bubble that is being interacted on. Null value indicates that
* the user interaction is not specific to one bubble.
* @param action the user interaction enum.
*/
private void logBubbleEvent(@Nullable BubbleView bubble, int action) {
if (bubble == null) {
StatsLog.write(StatsLog.BUBBLE_UI_CHANGED,
null /* package name */,
null /* notification channel */,
0 /* notification ID */,
0 /* bubble position */,
getBubbleCount(),
action,
getNormalizedXPosition(),
getNormalizedYPosition());
} else {
StatusBarNotification notification = bubble.getEntry().notification;
StatsLog.write(StatsLog.BUBBLE_UI_CHANGED,
notification.getPackageName(),
notification.getNotification().getChannelId(),
notification.getId(),
getBubbleIndex(bubble),
getBubbleCount(),
action,
getNormalizedXPosition(),
getNormalizedYPosition());
}
}
}