Merge "Use InteractionJankMonitor to instrument CUJs of NotificationShade"
This commit is contained in:
committed by
Android (Google) Code Review
commit
46c6d7279b
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.stack;
|
||||
|
||||
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING;
|
||||
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
|
||||
import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT;
|
||||
import static com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.ANCHOR_SCROLLING;
|
||||
@@ -73,6 +74,7 @@ import android.widget.ScrollView;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.graphics.ColorUtils;
|
||||
import com.android.internal.jank.InteractionJankMonitor;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.keyguard.KeyguardSliceView;
|
||||
import com.android.settingslib.Utils;
|
||||
@@ -97,7 +99,6 @@ import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||
import com.android.systemui.statusbar.notification.ShadeViewRefactor;
|
||||
import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
||||
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||
@@ -260,6 +261,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
private boolean mDismissAllInProgress;
|
||||
private boolean mFadeNotificationsOnDismiss;
|
||||
private FooterDismissListener mFooterDismissListener;
|
||||
private boolean mFlingAfterUpEvent;
|
||||
|
||||
/**
|
||||
* Was the scroller scrolled to the top when the down motion was observed?
|
||||
@@ -3789,6 +3791,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
|
||||
float currentOverScrollTop = getCurrentOverScrollAmount(true);
|
||||
if (currentOverScrollTop == 0.0f || initialVelocity > 0) {
|
||||
mFlingAfterUpEvent = true;
|
||||
setFinishScrollingCallback(() -> {
|
||||
mFlingAfterUpEvent = false;
|
||||
InteractionJankMonitor.getInstance()
|
||||
.end(CUJ_NOTIFICATION_SHADE_SCROLL_FLING);
|
||||
setFinishScrollingCallback(null);
|
||||
});
|
||||
fling(-initialVelocity);
|
||||
} else {
|
||||
onOverScrollFling(false, initialVelocity);
|
||||
@@ -3840,6 +3849,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean isFlingAfterUpEvent() {
|
||||
return mFlingAfterUpEvent;
|
||||
}
|
||||
|
||||
@ShadeViewRefactor(RefactorComponent.INPUT)
|
||||
protected boolean isInsideQsContainer(MotionEvent ev) {
|
||||
return ev.getY() < mQsContainer.getBottom();
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.stack;
|
||||
import static android.service.notification.NotificationStats.DISMISSAL_SHADE;
|
||||
import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
|
||||
|
||||
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING;
|
||||
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
|
||||
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
|
||||
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnEmptySpaceClickListener;
|
||||
@@ -47,6 +48,7 @@ import android.view.WindowInsets;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.jank.InteractionJankMonitor;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.UiEvent;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
@@ -1556,6 +1558,14 @@ public class NotificationStackScrollLayoutController {
|
||||
if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
|
||||
mView.setCheckForLeaveBehind(true);
|
||||
}
|
||||
|
||||
// When swiping directly on the NSSL, this would only get an onTouchEvent.
|
||||
// We log any touches other than down, which will be captured by onTouchEvent.
|
||||
// In the intercept we only start tracing when it's not a down (otherwise that down
|
||||
// would be duplicated when intercepted).
|
||||
if (scrollWantsIt && ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
|
||||
InteractionJankMonitor.getInstance().begin(CUJ_NOTIFICATION_SHADE_SCROLL_FLING);
|
||||
}
|
||||
return swipeWantsIt || scrollWantsIt || expandWantsIt;
|
||||
}
|
||||
|
||||
@@ -1611,7 +1621,32 @@ public class NotificationStackScrollLayoutController {
|
||||
if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
|
||||
mView.setCheckForLeaveBehind(true);
|
||||
}
|
||||
traceJankOnTouchEvent(ev.getActionMasked(), scrollerWantsIt);
|
||||
return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt;
|
||||
}
|
||||
|
||||
private void traceJankOnTouchEvent(int action, boolean scrollerWantsIt) {
|
||||
// Handle interaction jank monitor cases.
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (scrollerWantsIt) {
|
||||
InteractionJankMonitor.getInstance()
|
||||
.begin(CUJ_NOTIFICATION_SHADE_SCROLL_FLING);
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (scrollerWantsIt && !mView.isFlingAfterUpEvent()) {
|
||||
InteractionJankMonitor.getInstance()
|
||||
.end(CUJ_NOTIFICATION_SHADE_SCROLL_FLING);
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (scrollerWantsIt) {
|
||||
InteractionJankMonitor.getInstance()
|
||||
.cancel(CUJ_NOTIFICATION_SHADE_SCROLL_FLING);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.systemui.statusbar.phone;
|
||||
|
||||
import static android.view.View.GONE;
|
||||
|
||||
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE;
|
||||
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
|
||||
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
|
||||
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
|
||||
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
|
||||
@@ -62,6 +64,7 @@ import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.jank.InteractionJankMonitor;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.util.LatencyTracker;
|
||||
@@ -1139,6 +1142,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
onQsExpansionStarted();
|
||||
mInitialHeightOnTouch = mQsExpansionHeight;
|
||||
mQsTracking = true;
|
||||
traceQsJank(true /* startTracing */, false /* wasCancelled */);
|
||||
mNotificationStackScrollLayoutController.cancelLongPress();
|
||||
}
|
||||
break;
|
||||
@@ -1170,6 +1174,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
&& shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) {
|
||||
mView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
mQsTracking = true;
|
||||
traceQsJank(true /* startTracing */, false /* wasCancelled */);
|
||||
onQsExpansionStarted();
|
||||
notifyExpandingFinished();
|
||||
mInitialHeightOnTouch = mQsExpansionHeight;
|
||||
@@ -1202,6 +1207,19 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
&& x < stackScrollerX + mNotificationStackScrollLayoutController.getWidth();
|
||||
}
|
||||
|
||||
private void traceQsJank(boolean startTracing, boolean wasCancelled) {
|
||||
InteractionJankMonitor monitor = InteractionJankMonitor.getInstance();
|
||||
if (startTracing) {
|
||||
monitor.begin(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
|
||||
} else {
|
||||
if (wasCancelled) {
|
||||
monitor.cancel(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
|
||||
} else {
|
||||
monitor.end(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initDownStates(MotionEvent event) {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
mOnlyAffordanceInThisMotion = false;
|
||||
@@ -1315,9 +1333,9 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
final int action = event.getActionMasked();
|
||||
if (action == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
|
||||
&& mBarState != KEYGUARD && !mQsExpanded && mQsExpansionEnabled) {
|
||||
|
||||
// Down in the empty area while fully expanded - go to QS.
|
||||
mQsTracking = true;
|
||||
traceQsJank(true /* startTracing */, false /* wasCancelled */);
|
||||
mConflictingQsExpansionGesture = true;
|
||||
onQsExpansionStarted();
|
||||
mInitialHeightOnTouch = mQsExpansionHeight;
|
||||
@@ -1405,6 +1423,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
return;
|
||||
}
|
||||
mExpectingSynthesizedDown = true;
|
||||
InteractionJankMonitor.getInstance().begin(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
|
||||
onTrackingStarted();
|
||||
updatePanelExpanded();
|
||||
}
|
||||
@@ -1474,6 +1493,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mQsTracking = true;
|
||||
traceQsJank(true /* startTracing */, false /* wasCancelled */);
|
||||
mInitialTouchY = y;
|
||||
mInitialTouchX = x;
|
||||
onQsExpansionStarted();
|
||||
@@ -1513,6 +1533,9 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
if (fraction != 0f || y >= mInitialTouchY) {
|
||||
flingQsWithCurrentVelocity(y,
|
||||
event.getActionMasked() == MotionEvent.ACTION_CANCEL);
|
||||
} else {
|
||||
traceQsJank(false /* startTracing */,
|
||||
event.getActionMasked() == MotionEvent.ACTION_CANCEL);
|
||||
}
|
||||
if (mQsVelocityTracker != null) {
|
||||
mQsVelocityTracker.recycle();
|
||||
@@ -1893,7 +1916,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
* @see #flingSettings(float, int, Runnable, boolean)
|
||||
*/
|
||||
public void flingSettings(float vel, int type) {
|
||||
flingSettings(vel, type, null, false /* isClick */);
|
||||
flingSettings(vel, type, null /* onFinishRunnable */, false /* isClick */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1923,6 +1946,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
if (onFinishRunnable != null) {
|
||||
onFinishRunnable.run();
|
||||
}
|
||||
traceQsJank(false /* startTracing */, type != FLING_EXPAND /* wasCancelled */);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1947,11 +1971,17 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
setQsExpansion((Float) animation.getAnimatedValue());
|
||||
});
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
private boolean mIsCanceled;
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
notifyExpandingStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
mIsCanceled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mAnimatingQS = false;
|
||||
@@ -1961,6 +1991,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
if (onFinishRunnable != null) {
|
||||
onFinishRunnable.run();
|
||||
}
|
||||
traceQsJank(false /* startTracing */, mIsCanceled /* wasCancelled */);
|
||||
}
|
||||
});
|
||||
// Let's note that we're animating QS. Moving the animator here will cancel it immediately,
|
||||
|
||||
@@ -49,6 +49,7 @@ import android.view.WindowInsets;
|
||||
import android.view.WindowInsetsController;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.internal.jank.InteractionJankMonitor;
|
||||
import com.android.internal.view.FloatingActionMode;
|
||||
import com.android.internal.widget.FloatingToolbar;
|
||||
import com.android.systemui.R;
|
||||
@@ -145,6 +146,7 @@ public class NotificationShadeWindowView extends FrameLayout {
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
setWillNotDraw(!DEBUG);
|
||||
InteractionJankMonitor.getInstance().init(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE;
|
||||
import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
|
||||
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
|
||||
import static com.android.systemui.classifier.Classifier.UNLOCK;
|
||||
@@ -40,6 +41,7 @@ import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.internal.jank.InteractionJankMonitor;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.util.LatencyTracker;
|
||||
import com.android.systemui.DejankUtils;
|
||||
@@ -109,6 +111,7 @@ public abstract class PanelViewController {
|
||||
private boolean mMotionAborted;
|
||||
private boolean mUpwardsWhenThresholdReached;
|
||||
private boolean mAnimatingOnDown;
|
||||
private boolean mHandlingPointerUp;
|
||||
|
||||
private ValueAnimator mHeightAnimator;
|
||||
private ObjectAnimator mPeekAnimator;
|
||||
@@ -356,6 +359,9 @@ public abstract class PanelViewController {
|
||||
|
||||
protected void startExpandMotion(float newX, float newY, boolean startTracking,
|
||||
float expandedHeight) {
|
||||
if (!mHandlingPointerUp) {
|
||||
InteractionJankMonitor.getInstance().begin(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
|
||||
}
|
||||
mInitialOffsetOnTouch = expandedHeight;
|
||||
mInitialTouchY = newY;
|
||||
mInitialTouchX = newX;
|
||||
@@ -571,6 +577,7 @@ public abstract class PanelViewController {
|
||||
target = getMaxPanelHeight() - getClearAllHeightWithPadding();
|
||||
}
|
||||
if (target == mExpandedHeight || getOverExpansionAmount() > 0f && expand) {
|
||||
InteractionJankMonitor.getInstance().end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
|
||||
notifyExpandingFinished();
|
||||
return;
|
||||
}
|
||||
@@ -622,7 +629,12 @@ public abstract class PanelViewController {
|
||||
}
|
||||
setAnimator(null);
|
||||
if (!mCancelled) {
|
||||
InteractionJankMonitor.getInstance()
|
||||
.end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
|
||||
notifyExpandingFinished();
|
||||
} else {
|
||||
InteractionJankMonitor.getInstance()
|
||||
.cancel(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
|
||||
}
|
||||
notifyBarPanelExpansionChanged();
|
||||
}
|
||||
@@ -1272,7 +1284,9 @@ public abstract class PanelViewController {
|
||||
final float newY = event.getY(newIndex);
|
||||
final float newX = event.getX(newIndex);
|
||||
mTrackingPointer = event.getPointerId(newIndex);
|
||||
mHandlingPointerUp = true;
|
||||
startExpandMotion(newX, newY, true /* startTracking */, mExpandedHeight);
|
||||
mHandlingPointerUp = false;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
@@ -1330,6 +1344,12 @@ public abstract class PanelViewController {
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
addMovement(event);
|
||||
endMotionEvent(event, x, y, false /* forceCancel */);
|
||||
InteractionJankMonitor monitor = InteractionJankMonitor.getInstance();
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
|
||||
monitor.end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
|
||||
} else {
|
||||
monitor.cancel(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return !mGestureWaitForTouchSlop || mTracking;
|
||||
|
||||
Reference in New Issue
Block a user