Merge "Use InteractionJankMonitor to instrument CUJs of NotificationShade"

This commit is contained in:
TreeHugger Robot
2020-09-29 18:31:17 +00:00
committed by Android (Google) Code Review
5 changed files with 104 additions and 3 deletions

View File

@@ -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();

View File

@@ -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;
}
}
}
}

View File

@@ -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,

View File

@@ -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

View File

@@ -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;