Merge "Log HUN view changes and actual removal"
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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"
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user