frameworks的通知如何传递到Systemui?
frameworks
notify()--->notifyAsUser()-->service.enqueueNotificationWithTag(); 即(NotificationManagerService.enqueueNotificationWithTag)
NotificationManagerService.java
enqueueNotificationWithTag()-->enqueueNotificationInternal()-->
mHandler.post(new EnqueueNotificationRunnable(userId, r));-->
mHandler.postDelayed(new PostNotificationRunnable(r.getKey()),
DELAY_FOR_ASSISTANT_TIME);-->
PostNotificationRunnable.run()-->mListeners.notifyPostedLocked(); 这里的mListeners是NotificationListeners ,是一个在NotificationManagerService中的内部类
NotificationListeners.notifyPostedLocked--notifyPosted()-->
listener.onNotificationPosted(sbnHolder, rankingUpdate);这里的mListeners是INotificationListener这个aidl,
protected class NotificationListenerWrapper extends INotificationListener.Stub
NotificationListenerWrapper 是 NotificationListenerService 的内部类
public abstract class NotificationListenerService extends Service
SystemUI:
public class NotificationListenerWithPlugins extends NotificationListenerService implements PluginListener
public class NotificationListener extends NotificationListenerWithPlugins
SystemUI\src\com\android\systemui\statusbar\NotificationListener.java
所以listener.onNotificationPosted最终调用的是SystemUI中NotificationListener.java的onNotificationPosted方法。
SystemUI 通知流程:
StatusBarNotification.java
Notification.java
NotificationData.java The list of currently displaying notifications
NotificationData.Entry
通知栏图标类 StatusBarIconView
1,NotificationListener.java ---》onNotificationPosted-->mEntryManager.addNotification()
当一个通知到来的时候,首先触发NotificationListener中的onNotificationPosted,然后继续调用NotificationEntryManager.addNotification()
2,NotificationEntryManager.addNotification(sbn, rankingMap)---》addNotificationInternal()
NotificationEntryManager.java
mNotificationData.updateRanking(ranking);//重启排序
NotificationData.Entry shadeEntry = createNotificationViews(notification);//创建通知entry
protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn)
throws InflationException {
if (CHATTY) {
Log.d(TAG, "NotificationEntryManager.java createNotificationViews(notification=" + sbn);
}
Log.d("lgy_debug_systemui", "createNotificationViews(notification=" + sbn);
NotificationData.Entry entry = new NotificationData.Entry(sbn);
Dependency.get(LeakDetector.class).trackInstance(entry);
entry.createIcons(mContext, sbn);//创建图标
// Construct the expanded view.
inflateViews(entry, mListContainer.getViewParentForNotification(entry));
return entry;
}
inflateViews--》RowInflaterTask().inflate()
new RowInflaterTask().inflate(mContext, parent, entry,
row -> {
bindRow(entry, pmUser, sbn, row);
updateNotification(entry, pmUser, sbn, row);
});‘’
RowInflaterTask.java
public void inflate(Context context, ViewGroup parent, NotificationData.Entry entry,
RowInflationFinishedListener listener) {
if (TRACE_ORIGIN) {
mInflateOrigin = new Throwable("inflate requested here");
}
mListener = listener;
AsyncLayoutInflater inflater = new AsyncLayoutInflater(context);
mEntry = entry;
entry.setInflationTask(this);
inflater.inflate(R.layout.status_bar_notification_row, parent, this);
}
private void bindRow(NotificationData.Entry entry, PackageManager pmUser,
StatusBarNotification sbn, ExpandableNotificationRow row) {
Log.d("lgy_debug_systemui","NotificationEntryManager.java bindRow 1111");
row.setExpansionLogger(this, entry.notification.getKey());
row.setGroupManager(mGroupManager);
row.setHeadsUpManager(mHeadsUpManager);
row.setOnExpandClickListener(mPresenter);
row.setInflationCallback(this);//给row绑定InflationCallback mCallback,会调用onAsyncInflationFinished方法
row.setLongPressListener(getNotificationLongClicker());//长按事件
mListContainer.bindRow(row);//下拉通知绑定视图view ExpandableNotificationRow
mRemoteInputManager.bindRow(row);
// Get the app name.
// Note that Notification.Builder#bindHeaderAppName has similar logic
// but since this field is used in the guts, it must be accurate.
// Therefore we will only show the application label, or, failing that, the
// package name. No substitutions.
final String pkg = sbn.getPackageName();
String appname = pkg;
try {
final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
PackageManager.MATCH_UNINSTALLED_PACKAGES
| PackageManager.MATCH_DISABLED_COMPONENTS);
if (info != null) {
appname = String.valueOf(pmUser.getApplicationLabel(info));
}
} catch (PackageManager.NameNotFoundException e) {
// Do nothing
}
row.setAppName(appname);
row.setOnDismissRunnable(() ->
performRemoveNotification(row.getStatusBarNotification()));
row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
if (ENABLE_REMOTE_INPUT) {
row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
}
row.setAppOpsOnClickListener(mOnAppOpsClickListener);
mCallback.onBindRow(entry, pmUser, sbn, row);
}
protected void updateNotification(NotificationData.Entry entry, PackageManager pmUser,
StatusBarNotification sbn, ExpandableNotificationRow row) {
Log.d("lgy_debug_systemui","NotificationEntryManager.java updateNotification ");
row.setNeedsRedaction(mLockscreenUserManager.needsRedaction(entry));
boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
boolean isUpdate = mNotificationData.get(entry.key) != null;
boolean wasLowPriority = row.isLowPriority();
row.setIsLowPriority(isLowPriority);
row.setLowPriorityStateUpdated(isUpdate && (wasLowPriority != isLowPriority));
// bind the click event to the content area
mNotificationClicker.register(row, sbn);//lgy
// Extract target SDK version.
try {
ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0);
entry.targetSdk = info.targetSdkVersion;
} catch (PackageManager.NameNotFoundException ex) {
Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
}
row.setLegacy(entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD
&& entry.targetSdk < Build.VERSION_CODES.LOLLIPOP);
entry.setIconTag(R.id.icon_is_pre_L, entry.targetSdk < Build.VERSION_CODES.LOLLIPOP);
entry.autoRedacted = entry.notification.getNotification().publicVersion == null;
entry.row = row;
entry.row.setOnActivatedListener(mPresenter);
boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(sbn,
mNotificationData.getImportance(sbn.getKey()));
boolean useIncreasedHeadsUp = useIncreasedCollapsedHeight
&& !mPresenter.isPresenterFullyCollapsed();
row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
row.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp);
row.updateNotification(entry);// ExpandableNotificationRow
}
public void updateNotification(NotificationData.Entry entry) {
Log.d("lgy_debug_systemui"," ExpandableNotificationRow.java updateNotification");
mEntry = entry;
mStatusBarNotification = entry.notification;
mNotificationInflater.inflateNotificationViews();
cacheIsSystemNotification();
}
status_bar_notification_row
NotificationEntryManager.java
@Override
public void onAsyncInflationFinished(NotificationData.Entry entry) {
mPendingNotifications.remove(entry.key);
// If there was an async task started after the removal, we don't want to add it back to
// the list, otherwise we might get leaks.
boolean isNew = mNotificationData.get(entry.key) == null;
if (CHATTY) {
Log.d(TAG, "onAsyncInflationFinished, isNew: " + isNew + ", removed: "
+ entry.row.isRemoved() + ", key: "
+ (entry != null ? entry.key : null));
}
if (isNew && !entry.row.isRemoved()) {
addEntry(entry);
} else if (!isNew && entry.row.hasLowPriorityStateUpdated()) {
mVisualStabilityManager.onLowPriorityUpdated(entry);
mPresenter.updateNotificationViews();//lgy systembar->updateNotificationViews
}
entry.row.setLowPriorityStateUpdated(false);
}
StatusBar.java
public void updateNotificationViews() {
Log.d("lgy_debug_systemui","StatusBar.java-->updateNotificationViews");
// The function updateRowStates depends on both of these being non-null, so check them here.
// We may be called before they are set from DeviceProvisionedController's callback.
if (mStackScroller == null || mScrimController == null) return;
// Do not modify the notifications during collapse.
if (isCollapsing()) {
addPostCollapseAction(this::updateNotificationViews);
return;
}
mViewHierarchyManager.updateNotificationViews();
updateSpeedBumpIndex();
updateFooter();
updateEmptyShadeView();
updateQsExpansionEnabled();
// Let's also update the icons
mNotificationIconAreaController.updateNotificationIcons();
}
更新图标,布局为notification_icon_area.xml
NotificationIconAreaController updateNotificationIcons
NotificationIconAreaController updateStatusBarIcons
NotificationIconAreaController updateIconsForLayout