Android Notification从发送到显示的流程简析

admin 2024年3月29日23:47:51评论8 views字数 6791阅读22分38秒阅读模式
一、Notification框架结构

Notification在Android系统中扮演着重要的角色,主要作用包括显示接收到的信息、显示应用程序的状态以及提醒用户进行某项操作。除了下拉状态栏显示的通知信息外,通知还能带有声音、振动、通知灯、图片图标等丰富的信息。它可以帮助用户快速了解和处理应用程序的实时信息,提高用户的使用体验和效率。

Notification通知框架主要由三部分组成:发送/更新/取消通知的应用APP、系统通知服务NotificationManagerService和 通知监听器NotificationListenerService。应用可以调用NotificationManager.notify(int,Notification)发送通知到系统框架层,框架层中的NotificationManagerService对通知进行处理,如判断是否拦截通知、播放声音、振动、调用通知灯等,再将通知发送给各个通知监听器NotificationListenerService。SystemUI作为最重要的通知监听器,它在接收到通知后会对通知UI进行更新显示。

Android Notification从发送到显示的流程简析

二、Framework发送

Notification代码流程

应用在创建通知对应的NotificationChannel之后,就能调用NotificationManager.notify(int,Notification)发送通知。接下来我们分析Android 13中Notification相关的部分源码,了解通知从应用到系统框架,再从系统框架到通知监听器,最后从SystemUI监听器到显示通知的大概流程。

1、 APP通过NotificationManager.notify发送通知

Android Notification从发送到显示的流程简析

2、 NotificationManager的notify最终会调用 notifyAsUser,notifyAsUser会调用fixNotification校验通知声音和尝试修复校验裁剪通知图标ICON,接着调用service的enqueueNotificationWithTag方法。service是INotificationManager类型的代理服务,通过它的enqueueNotificationWithTag方法把通知发送给通知服务处理。

Android Notification从发送到显示的流程简析

3、 NotificationManagerService.java中的mService实现了INotificationManager.Stub,所以前面调用INotificationManager相关方法会调用到这里。

Android Notification从发送到显示的流程简析

Android Notification从发送到显示的流程简析

4、 mService的enqueueNotificationWithTag方法会调用到NotificationManagerService.enqueueNotificationInternal方法。

Android Notification从发送到显示的流程简析

enqueueNotificationInternal首先会检查包名是否null、通知是否null、发起通知的应用是否有权限;接着还会尝试修复notification、检测通知channel、调整前台服务通知的importance控制通知是否显示;

Android Notification从发送到显示的流程简析

还会将notification进一步封装为StatusBarNotification对象n和NotificationRecord对象r,、接着调用checkDisqualifyingFeatures检查通知速率和通知数量,最后将NotificationRecord对象r发送到一个异步线程 EnqueueNotificationRunnable 的run方法中去执行。

Android Notification从发送到显示的流程简析

5、 EnqueueNotificationRunnable.run方法会定义通知自动取消的时间任务,更新通知Group;并且把NotificationRecord对象r添加进mEnqueuedNotifications。最后把对象r的一些信息传给一个PostNotificationRunnable对象并run方法里执行。

Android Notification从发送到显示的流程简析

6、 PostNotificationRunnable.run方法会从前面添加了NotificationRecord对象r的mEnqueuedNotifications里取出NotificationRecord对象和StatusBarNotification对象、通知排序。

Android Notification从发送到显示的流程简析

然后调用buzzBeepBlinkLocked(r)处理通知声音、振动、通知灯,最后调用mListeners.notifyPostedLocked(r, old)方法。

Android Notification从发送到显示的流程简析

7、 NotificationListeners.notifyPostedLocked首先会做该通知是否显示的各种判断;根据通知生成NotificationRankingUpdate对象,该对象会post到监听器,用于通知排序;赋予Uri访问权限。最后如果显示通知的话会调用notifyPosted方法,其中参数info包含了注册的通知监听器服务,参数sbnToPost就是从NotificationRecord中提取的StatusBarNotification。

Android Notification从发送到显示的流程简析

8、 NotificationListeners.notifyPosted会调用INotificationListener.onNotificationPosted方法

Android Notification从发送到显示的流程简析

9、 NotificationListenerService.java中的NotificationListenerWrapper实现了

INotificationListener.Stub接口,所以INotificationListener.onNotificationPosted会调用到NotificationListenerWrapper的onNotificationPosted接口实现。

Android Notification从发送到显示的流程简析

最后会发送MSG_ON_NOTIFICATION_POSTED消息给NotificationListenerService的MyHandler,MyHandler收到该消息后会调用NotificationListenerService的onNotificationPosted处理。

Android Notification从发送到显示的流程简析

10、 NotificationListenerService是个抽象类,声明如下:

Android Notification从发送到显示的流程简析

它的onNotificationPosted方法没有具体的实现,所以onNotificationPosted的实现,通常由NotificationListenerService的子类完成。

Android Notification从发送到显示的流程简析

NotificationListenerService是所有通知监听类的父类,所有监听通知的类最终都会继承于它。通过调用它的onNotificationPosted方法把APP发送的通知分发给各个通知监听器。其中SystemUI作为最重要的通知监听器,在收到通知后会处理通知相关的UI显示。接下来我们继续分析SystemUI收到通知后显示通知的流程。

三、SystemUI接收显示Notification流程

1.前面分析到Framework通过调用NotificationListenerService的onNotificationPosted方法把APP发送的通知分发给各个通知监听器。SystemUI里的NotificationListenerWithPlugins类继承自NotificationListenerService,但NotificationListenerWithPlugins里面并没有实现onNotificationPosted方法。通过查找发现NotificationListener继承自NotificationListenerWithPlugins,并且实现了onNotificationPosted、onNotificationRemoved、onNotificationRankingUpdate等方法。

在Framework回调了NotificationListener的onNotificationPosted方法后,会调用NotificationListener.NotificationHandler的onNotificationPosted方法处理接收到StatusBarNotification。

Android Notification从发送到显示的流程简析

2.NotificationEntryManager的mNotifListener实现了

NotificationListener.NotificationHandler的onNotificationPosted方法。接着调用addNotification添加通知。

Android Notification从发送到显示的流程简析

3.addNotification 会继续调用addNotificationInternal。addNotificationInternal会调用updateRankingAndSort更新通知等级。

Android Notification从发送到显示的流程简析

接着将StatusBarNotification封装成NotificationEntry对象entry,并调用

mNotificationRowBinderLazy.get().inflateViews(entry, null, mInflationCallback)构建填充通知布局。

Android Notification从发送到显示的流程简析

4.这里执行inflateViews的是NotificationRowBinderImpl的inflateViews方法

Android Notification从发送到显示的流程简析

如果entry的ExpandableNotificationRow不存在就会调用mRowInflaterTaskProvider.get().inflate(mContext, parent, entry, RowInflationFinishedListener)去填充通知布局,此处实际调用的是RowInflaterTask的inflate方法。

Android Notification从发送到显示的流程简析

这里填充的布局是R.layout.status_bar_notification_row,它的根标签是ExpandableNotificationRow。

5.填充通知布局后会调用bindRow方法,该方法会和一些控制管理器绑定和继续完成填充通知布局。会依次调用NotifBindPipeline的manageRow方法 -> NotifBindPipeline.requestPipelineRun方法。

Android Notification从发送到显示的流程简析

requestPipelineRun方法会发送START_PIPELINE_MSG消息给mMainHandler。

Android Notification从发送到显示的流程简析

mMainHandler是NotifBindPipelineHandler类型,该消息会调用NotifBindPipeline的startPipeline方法。

Android Notification从发送到显示的流程简析

startPipeline方法接着会调用mStage.executeStage方法。BindStage是个抽象类,具体实现是RowContentBindStage的executeStage方法。

Android Notification从发送到显示的流程简析

RowContentBindStage的executeStage方法会调用mBinder.bindContent方法。mBinder是实现NotificationRowContentBinder接口的对象,具体实现类为NotificationContentInflater。也就是这里实际调用的是NotificationContentInflater的bindContent方法。该方法会调用异步线程AsyncInflationTask,AsyncInflationTask会依次调用inflateSmartReplyViews、apply -> applyRemoteView方法去加载通知布局。

Android Notification从发送到显示的流程简析

之后apply还会调用finishIfDone完成填充,主要是填充ExpandableNotificationRow的privateLayout和publicLayout。

Android Notification从发送到显示的流程简析

6.在上面填充完通知布局最后会调用NotificationRowBinderImpl的updateRow和inflateContentViews方法,updateRow方法会绑定一些点击事件,而inflateContentViews方法最后会回调inflationCallback.onAsyncInflationFinished方法。

Android Notification从发送到显示的流程简析

实际调用的是NotificationEntryManager.mInflationCallback的onAsyncInflationFinished方法,该方法会继续调用NotificationEntryManager.updateNotifications方法对通知的容器进行更新。

Android Notification从发送到显示的流程简析

updateNotifications会调用mPresenter.updateNotificationViews(reason)。

Android Notification从发送到显示的流程简析

7.mPresenter是实现了NotificationPresenter接口的类。mPresenter.updateNotificationViews方法的实现代码是StatusBarNotificationPresenter的updateNotificationViews方法。该方法会依次调用NotificationViewHierarchyManager的updateNotificationViews方法和NotificationPanelViewController的updateNotificationViews方法更新通知。

Android Notification从发送到显示的流程简析

8.NotificationViewHierarchyManager的updateNotificationViews方法会先取出可见的通知NotificationEntry。

Android Notification从发送到显示的流程简析

然后再根据需要调用mListContainer.removeContainerView(View)移除通知视图或调用mListContainer.addContainerView(View)将通知视图添加到通知容器NotificationStackScrollLayout,也就是将通知视图移除或添加到通知栏中,并对通知排序。

Android Notification从发送到显示的流程简析

9.NotificationPanelViewController的updateNotificationViews方法除了更新NotificationStackScrollLayout视图的信息,还会调用NotificationIconAreaController的updateNotificationIcons()方法更新各种Icon。

Android Notification从发送到显示的流程简析

Android Notification从发送到显示的流程简析

这几个更新Icon的方法都是调用updateIconsForLayout方法来实现的。

Android Notification从发送到显示的流程简析

updateIconsForLayout先从mNotificationEntries(来源于mNotificationStackScrollLayoutController)取出NotificationEntry,然后把NotificationEntry里的StatusBarIconView取出添加到toShow。

Android Notification从发送到显示的流程简析

最后调用hostLayout.addView(v, i, params)添加Icon到前面更新Icon的方法传入的NotificationIconContainer布局里。

到此通知已经显示在通知栏和状态栏中,整个流程分析完毕。

四、小结

本文简要分析了通知从发送到显示的基本流程。实际上,与通知(Notification)相关的代码相对众多,因此一些特定业务场景并未进行深入剖析,很多细节代码需要遇到具体问题再具体分析。对于这些内容感兴趣的朋友,可以针对特定的子业务流程展开进一步的分析。

参考链接:

https://developer.android.com/develop/ui/views/notifications

https://developer.android.com/reference/android/service/notification/NotificationListenerService

https://www.jianshu.com/p/914092161b4e

https://blog.csdn.net/qq_34211365/article/details/103398511

https://blog.csdn.net/z1804362542/article/details/127132720

https://blog.csdn.net/xiaowanbiao123/article/details/132654468

END

➤ 往期推荐

·frida入门使用介绍

·使用honggfuzz进行Android模糊测试

·蓝牙安全漏洞BLUFFS的原理解析及影响范围

·Android本地服务漏洞挖掘技术 - 下篇

原文始发于微信公众号(OPPO安珀实验室):Android Notification从发送到显示的流程简析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月29日23:47:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Android Notification从发送到显示的流程简析https://cn-sec.com/archives/2613188.html

发表评论

匿名网友 填写信息