Merge "Log HUN view changes and actual removal"

This commit is contained in:
Jay Aliomer
2022-01-25 18:06:53 +00:00
committed by Android (Google) Code Review
14 changed files with 149 additions and 16 deletions

View File

@@ -320,7 +320,7 @@ public abstract class AlertingNotificationManager implements NotificationLifetim
* @param updatePostTime whether or not to refresh the post time
*/
public void updateEntry(boolean updatePostTime) {
mLogger.logUpdateEntry(updatePostTime);
mLogger.logUpdateEntry(mEntry.getKey(), updatePostTime);
long currentTime = mClock.currentTimeMillis();
mEarliestRemovaltime = currentTime + mMinimumDisplayTime;

View File

@@ -424,7 +424,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
@Override
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear) {
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
Runnable onFinishRunnable) {
enableAppearDrawing(true);
mIsHeadsUpAnimation = isHeadsUpAppear;
if (mDrawingAppearAnimation) {

View File

@@ -358,7 +358,12 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
Runnable onFinishedRunnable,
AnimatorListenerAdapter animationListener);
public abstract void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear);
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear) {
performAddAnimation(delay, duration, isHeadsUpAppear, null);
}
public abstract void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
Runnable onEndRunnable);
/**
* Set the notification appearance to be below the speed bump.

View File

@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.row
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel.INFO
import com.android.systemui.log.LogLevel.WARNING
import com.android.systemui.log.dagger.NotificationLog
import javax.inject.Inject
@@ -50,7 +49,7 @@ class NotifBindPipelineLogger @Inject constructor(
}
fun logRequestPipelineRowNotSet(notifKey: String) {
buffer.log(TAG, WARNING, {
buffer.log(TAG, INFO, {
str1 = notifKey
}, {
"Row is not set so pipeline will not run. notif = $str1"

View File

@@ -241,6 +241,13 @@ public abstract class StackScrollerDecorView extends ExpandableView {
setContentVisible(true);
}
@Override
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
Runnable endRunnable) {
// TODO: use delay and duration
setContentVisible(true);
}
@Override
public boolean needsClippingToShelf() {
return false;

View File

@@ -39,7 +39,8 @@ public class MediaContainerView extends ExpandableView {
}
@Override
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear) {
public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
Runnable onEnd) {
// No animation, it doesn't need it, this would be local
}
}

View File

@@ -5658,6 +5658,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
}
protected void setLogger(StackStateLogger logger) {
mStateAnimator.setLogger(logger);
}
/**
* A listener that is notified when the empty space below the notifications is clicked on
*/

View File

@@ -184,6 +184,7 @@ public class NotificationStackScrollLayoutController {
private final SectionHeaderController mSilentHeaderController;
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
private final InteractionJankMonitor mJankMonitor;
private final StackStateLogger mStackStateLogger;
private NotificationStackScrollLayout mView;
private boolean mFadeNotificationsOnDismiss;
@@ -660,7 +661,9 @@ public class NotificationStackScrollLayoutController {
NotificationRemoteInputManager remoteInputManager,
VisualStabilityManager visualStabilityManager,
ShadeController shadeController,
InteractionJankMonitor jankMonitor) {
InteractionJankMonitor jankMonitor,
StackStateLogger stackLogger) {
mStackStateLogger = stackLogger;
mAllowLongPress = allowLongPress;
mNotificationGutsManager = notificationGutsManager;
mVisibilityProvider = visibilityProvider;
@@ -712,6 +715,7 @@ public class NotificationStackScrollLayoutController {
public void attach(NotificationStackScrollLayout view) {
mView = view;
mView.setLogger(mStackStateLogger);
mView.setController(this);
mView.setTouchHandler(new TouchHandler());
mView.setStatusBar(mStatusBar);

View File

@@ -86,6 +86,7 @@ public class StackStateAnimator {
private NotificationShelf mShelf;
private float mStatusBarIconLocation;
private int[] mTmpLocation = new int[2];
private StackStateLogger mLogger;
public StackStateAnimator(NotificationStackScrollLayout hostLayout) {
mHostLayout = hostLayout;
@@ -113,6 +114,10 @@ public class StackStateAnimator {
};
}
protected void setLogger(StackStateLogger logger) {
mLogger = logger;
}
public boolean isRunning() {
return !mAnimatorSet.isEmpty();
}
@@ -337,6 +342,12 @@ public class StackStateAnimator {
ArrayList<NotificationStackScrollLayout.AnimationEvent> animationEvents) {
for (NotificationStackScrollLayout.AnimationEvent event : animationEvents) {
final ExpandableView changingView = (ExpandableView) event.mChangingView;
boolean loggable = false;
String key = null;
if (changingView instanceof ExpandableNotificationRow && mLogger != null) {
loggable = true;
key = ((ExpandableNotificationRow) changingView).getEntry().getKey();
}
if (event.animationType ==
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_ADD) {
@@ -407,10 +418,22 @@ public class StackStateAnimator {
if (event.headsUpFromBottom) {
mTmpState.yTranslation = mHeadsUpAppearHeightBottom;
} else {
Runnable onAnimationEnd = null;
if (loggable) {
String finalKey = key;
onAnimationEnd = () -> mLogger.appearAnimationEnded(finalKey);
}
changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_APPEAR,
true /* isHeadsUpAppear */);
true /* isHeadsUpAppear */, onAnimationEnd);
}
mHeadsUpAppearChildren.add(changingView);
// this only captures HEADS_UP_APPEAR animations, but HUNs can appear with normal
// ADD animations, which would not be logged here.
if (loggable) {
mLogger.logHUNViewAppearing(
((ExpandableNotificationRow) changingView).getEntry().getKey());
}
mTmpState.applyToView(changingView);
} else if (event.animationType == NotificationStackScrollLayout
.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR ||
@@ -453,10 +476,21 @@ public class StackStateAnimator {
// We need to add the global animation listener, since once no animations are
// running anymore, the panel will instantly hide itself. We need to wait until
// the animation is fully finished for this though.
Runnable postAnimation = endRunnable;
if (loggable) {
mLogger.logHUNViewDisappearing(key);
Runnable finalEndRunnable = endRunnable;
String finalKey1 = key;
postAnimation = () -> {
mLogger.disappearAnimationEnded(finalKey1);
if (finalEndRunnable != null) finalEndRunnable.run();
};
}
long removeAnimationDelay = changingView.performRemoveAnimation(
ANIMATION_DURATION_HEADS_UP_DISAPPEAR,
0, 0.0f, true /* isHeadsUpAppear */, targetLocation,
endRunnable, getGlobalAnimationFinishedListener());
postAnimation, getGlobalAnimationFinishedListener());
mAnimationProperties.delay += removeAnimationDelay;
} else if (endRunnable != null) {
endRunnable.run();

View File

@@ -0,0 +1,44 @@
package com.android.systemui.statusbar.notification.stack
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel
import com.android.systemui.log.dagger.NotificationHeadsUpLog
import javax.inject.Inject
class StackStateLogger @Inject constructor(
@NotificationHeadsUpLog private val buffer: LogBuffer
) {
fun logHUNViewDisappearing(key: String) {
buffer.log(TAG, LogLevel.INFO, {
str1 = key
}, {
"Heads up view disappearing $str1 "
})
}
fun logHUNViewAppearing(key: String) {
buffer.log(TAG, LogLevel.INFO, {
str1 = key
}, {
"Heads up notification view appearing $str1 "
})
}
fun disappearAnimationEnded(key: String) {
buffer.log(TAG, LogLevel.INFO, {
str1 = key
}, {
"Heads up notification disappear animation ended $str1 "
})
}
fun appearAnimationEnded(key: String) {
buffer.log(TAG, LogLevel.INFO, {
str1 = key
}, {
"Heads up notification appear animation ended $str1 "
})
}
}
private const val TAG = "StackScroll"

View File

@@ -184,6 +184,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
entry.setHeadsUp(false);
setEntryPinned((HeadsUpEntry) alertEntry, false /* isPinned */);
EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 0 /* visible */);
mLogger.logNotificationActuallyRemoved(entry.getKey());
for (OnHeadsUpChangedListener listener : mListeners) {
listener.onHeadsUpStateChanged(entry, false);
}

View File

@@ -73,6 +73,14 @@ class HeadsUpManagerLogger @Inject constructor(
})
}
fun logNotificationActuallyRemoved(key: String) {
buffer.log(TAG, INFO, {
str1 = key
}, {
"notification removed $str1 "
})
}
fun logUpdateNotification(key: String, alert: Boolean, hasEntry: Boolean) {
buffer.log(TAG, INFO, {
str1 = key
@@ -83,11 +91,12 @@ class HeadsUpManagerLogger @Inject constructor(
})
}
fun logUpdateEntry(updatePostTime: Boolean) {
fun logUpdateEntry(key: String, updatePostTime: Boolean) {
buffer.log(TAG, INFO, {
str1 = key
bool1 = updatePostTime
}, {
"update entry updatePostTime: $bool1"
"update entry $key updatePostTime: $bool1"
})
}

View File

@@ -137,6 +137,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@Mock private VisualStabilityManager mVisualStabilityManager;
@Mock private ShadeController mShadeController;
@Mock private InteractionJankMonitor mJankMonitor;
@Mock private StackStateLogger mStackLogger;
@Captor
private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor;
@@ -191,7 +192,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mRemoteInputManager,
mVisualStabilityManager,
mShadeController,
mJankMonitor
mJankMonitor,
mStackLogger
);
when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(true);

View File

@@ -23,14 +23,20 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -40,12 +46,14 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.statusbar.AlertingNotificationManager;
import com.android.systemui.statusbar.AlertingNotificationManagerTest;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -58,10 +66,15 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest {
private HeadsUpManager mHeadsUpManager;
private boolean mLivesPastNormalTime;
private UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake();
@Mock private HeadsUpManager.HeadsUpEntry mAlertEntry;
@Mock private NotificationEntry mEntry;
@Mock private StatusBarNotification mSbn;
@Mock private Notification mNotification;
@Mock private HeadsUpManagerLogger mLogger;
private final class TestableHeadsUpManager extends HeadsUpManager {
TestableHeadsUpManager(Context context) {
super(context, mock(HeadsUpManagerLogger.class));
TestableHeadsUpManager(Context context, HeadsUpManagerLogger logger) {
super(context, logger);
mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
}
@@ -73,10 +86,12 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest {
@Before
public void setUp() {
initMocks(this);
mAccessibilityMgr = mDependency.injectMockDependency(AccessibilityManagerWrapper.class);
mDependency.injectTestDependency(UiEventLogger.class, mUiEventLoggerFake);
mHeadsUpManager = new TestableHeadsUpManager(mContext);
when(mEntry.getSbn()).thenReturn(mSbn);
when(mSbn.getNotification()).thenReturn(mNotification);
mHeadsUpManager = new TestableHeadsUpManager(mContext, mLogger);
super.setUp();
mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
mHeadsUpManager.mHandler = mTestHandler;
@@ -87,6 +102,13 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest {
mTestHandler.removeCallbacksAndMessages(null);
}
@Test
public void testHunRemovedLogging() {
mAlertEntry.mEntry = mEntry;
mHeadsUpManager.onAlertEntryRemoved(mAlertEntry);
verify(mLogger, times(1)).logNotificationActuallyRemoved(eq(mEntry.getKey()));
}
@Test
public void testShowNotification_autoDismissesWithAccessibilityTimeout() {
doReturn(TEST_A11Y_AUTO_DISMISS_TIME).when(mAccessibilityMgr)