link:
Android P Notification(1) 之 removeNotification
Android P Notification(2) 之 发送通知慢
Android P Notification(3) 之 Fullscreen intent被拦截
NotificationManagerService原理分析
1.通知log流程
在event log中搜索 notification_可以看到通知各个时间段log
大概有 notification_enqueue -- notification_expansion --notification_visibility -- notification_clicked -- notification_canceled
//notification_enqueue 把通知放入队列,要注意status 0 post 1 update,因此看event log可能会有几个,1个post ,另外都update
//notification_visibility代表通知时可见的,在下拉通知时会触发,其他情况也有
//notification_expansion在灭屏亮屏,滑动后会触发
//notification_clicked 点击通知时会打印此log
//notification_canceled 调用NotificationManager.cancel(ID)会触发此发现,注意和notification_cancel不是一个东西
在Android P中发送通知时发现event log只打印了notification_enqueue,并不会打印后面的 notification_expansion --notification_visibility ,因此发送时间应该是
app发送通知时间---notification_enqueue时间--到SystemUI.createNotificationViews才是正确的时间,而不是从notification_enqueue到notification_visibility
@ /frameworks/base/services/core/java/com/android/server/EventLogTags.logtags
59# when a NotificationManager.notify is called. status: 0=post, 1=update, 2=ignored
602750 notification_enqueue (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3),(status|1)
7427511 notification_expansion (key|3),(user_action|1),(expanded|1),(lifespan|1),(freshness|1),(exposure|1)
7627520 notification_clicked (key|3),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1)
79# when a notification has been canceled
8027530 notification_canceled (key|3),(reason|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1),(count|1),(listener|3)
81# replaces 27510 with a row per notification
8227531 notification_visibility (key|3),(visibile|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1)
83# a notification emited noise, vibration, or light
8427532 notification_alert (key|3),(buzz|1),(beep|1),(blink|1)
@out/target/common/obj/JAVA_LIBRARIES/services.core_intermediates/src/java/com/android/server/EventLogTags.java
public static void writeNotificationEnqueue(int uid, int pid, String pkg, int id, String tag, int userid, String notification, int status) {
android.util.EventLog.writeEvent(NOTIFICATION_ENQUEUE, uid, pid, pkg, id, tag, userid, notification, status);
}
public static void writeNotificationCancel(int uid, int pid, String pkg, int id, String tag, int userid, int requiredFlags, int forbiddenFlags, int reason, String listener) {
android.util.EventLog.writeEvent(NOTIFICATION_CANCEL, uid, pid, pkg, id, tag, userid, requiredFlags, forbiddenFlags, reason, listener);
}
public static void writeNotificationCancelAll(int uid, int pid, String pkg, int userid, int requiredFlags, int forbiddenFlags, int reason, String listener) {
android.util.EventLog.writeEvent(NOTIFICATION_CANCEL_ALL, uid, pid, pkg, userid, requiredFlags, forbiddenFlags, reason, listener);
}
public static void writeNotificationPanelRevealed(int items) {
android.util.EventLog.writeEvent(NOTIFICATION_PANEL_REVEALED, items);
}
public static void writeNotificationPanelHidden() {
android.util.EventLog.writeEvent(NOTIFICATION_PANEL_HIDDEN);
}
public static void writeNotificationVisibilityChanged(String newlyvisiblekeys, String nolongervisiblekeys) {
android.util.EventLog.writeEvent(NOTIFICATION_VISIBILITY_CHANGED, newlyvisiblekeys, nolongervisiblekeys);
}
public static void writeNotificationExpansion(String key, int userAction, int expanded, int lifespan, int freshness, int exposure) {
android.util.EventLog.writeEvent(NOTIFICATION_EXPANSION, key, userAction, expanded, lifespan, freshness, exposure);
}
public static void writeNotificationClicked(String key, int lifespan, int freshness, int exposure) {
android.util.EventLog.writeEvent(NOTIFICATION_CLICKED, key, lifespan, freshness, exposure);
}
public static void writeNotificationActionClicked(String key, int actionIndex, int lifespan, int freshness, int exposure) {
android.util.EventLog.writeEvent(NOTIFICATION_ACTION_CLICKED, key, actionIndex, lifespan, freshness, exposure);
}
public static void writeNotificationCanceled(String key, int reason, int lifespan, int freshness, int exposure, String listener) {
android.util.EventLog.writeEvent(NOTIFICATION_CANCELED, key, reason, lifespan, freshness, exposure, listener);
}
public static void writeNotificationVisibility(String key, int visibile, int lifespan, int freshness, int exposure, int rank) {
android.util.EventLog.writeEvent(NOTIFICATION_VISIBILITY, key, visibile, lifespan, freshness, exposure, rank);
}
public static void writeNotificationAlert(String key, int buzz, int beep, int blink) {
android.util.EventLog.writeEvent(NOTIFICATION_ALERT, key, buzz, beep, blink);
}
public static void writeNotificationAutogrouped(String key) {
android.util.EventLog.writeEvent(NOTIFICATION_AUTOGROUPED, key);
}
public static void writeNotificationUnautogrouped(String key) {
android.util.EventLog.writeEvent(NOTIFICATION_UNAUTOGROUPED, key);
}
2.问题实例
碰到过一个bug关于来电通知慢的问题,大概要8s才显示通知,而正常显示应该是2s左右
分析步骤:
1.确认IncallUI收到电话到发出通知时间,如果没问题,证明tele没问题
2.确认notification_enqueue 到notification_visibility时间,确认framework notification 收到通知到显示在界面上的时间
在Android P中发送通知时发现event log只打印了notification_enqueue,并不会打印后面的 notification_expansion --notification_visibility ,因此发送时间应该是
app发送通知时间---notification_enqueue时间--到SystemUI.createNotificationViews才是正确的时间,而不是从notification_enqueue到notification_visibility
打开 SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java DEBUG开关用来调试
3.发现notification_enqueue 到notification_visibility时间时间太久,导致
4.搜索systemUI pid查看main log发现,主线程一直在做其他事情,SystemUI主线程太忙导致,通知很慢
5.解决SystemUI移除循环耗时的地方