//SystemBars.java(通知栏) :
@Override
public void start() {
if (DEBUG) Log.d(TAG, "start");
mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
mServiceMonitor.start(); //回调到SystemBars的onNoService()方法
}
@Override
public void onNoService() {
if (DEBUG) Log.d(TAG, "onNoService");
createStatusBarFromConfig();
}
//<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
//得到/systemUI/res/value/config.xml中的config_statusBarComponent属性值
final String clsName = mContext.getString(R.string.config_statusBarComponent);
Class<?> cls = null;
try {
//加载PhoneStatusBar类
cls = mContext.getClassLoader().loadClass(clsName);
} catch (Throwable t) {
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
//获取PhoneStatusBar的实例
mStatusBar = (BaseStatusBar) cls.newInstance();
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
}
//PhoneStatusBar.java
public void start() {
//获取WindowManager的对象
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
updateDisplaySize();
mScrimSrcModeEnabled = mContext.getResources().getBoolean(
R.bool.config_status_bar_scrim_behind_use_src);
//调用BaseStatusBar中的start()方法
super.start();
.......
addNavigationBar();//实例化导航条
// 实例化PhoneStatusBarPolicy来设置或更新所有的图标
mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController,
mUserInfoController, mBluetoothController);
mIconPolicy.setCurrentUserSetup(mUserSetup);
mSettingsObserver.onChange(false);
....
}
//BaseStatusBar.java
public void start() {
......
// 实例化iconLiist,这时的iconList为空值
StatusBarIconList iconList = new StatusBarIconList();
//通过CommandQueue实现StatusBarManagerService与SystemUI的通信
mCommandQueue = new CommandQueue(this, iconList);
int[] switches = new int[8];
ArrayList<IBinder> binders = new ArrayList<IBinder>();
try {
//将iconlist注册到StatusBarManagerService中
mBarService.registerStatusBar(mCommandQueue, iconList, switches, binders);
} catch (RemoteException ex) {
}
//初始化statusbar,notification,quickSetting等View控件
createAndAddWindows();
.........
try {
//NotificationListenerService主要实现StatusBarServiceManager和SystemUI的Notification控制通道
//当StatusBarServiceManager收到Notification时,通过此通道通知SystemUI显示Notification的变化
mNotificationListener.registerAsSystemService(mContext,
new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()),
UserHandle.USER_ALL);
} catch (RemoteException e) {
Log.e(TAG, "Unable to register notification listener", e);
}
.....
}
//实现StatusBarServiceManager与SystemUI的Notification的控制通道
private final NotificationListenerService mNotificationListener =
new NotificationListenerService() {
@Override
public void onListenerConnected() {
if (DEBUG) Log.d(TAG, "onListenerConnected");
final StatusBarNotification[] notifications = getActiveNotifications();
final RankingMap currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
for (StatusBarNotification sbn : notifications) {
addNotification(sbn, currentRanking, null);
}
}
});
}
//Notification处理流程,App中会获取NotificationManager的对象,调用notify()方法
//NotificationManager.java
//参数tag表示该notification的标识符,每个notification的id都是唯一的
public void notify(String tag, int id, Notification notification)
{
int[] idOut = new int[1];
//service为NotificationManagerService的实例,在SystemServer中启动
INotificationManager service = getService();
//获取信息发送者的包名
String pkg = mContext.getPackageName();
...
try {
//将包名,tag,id,notification实例一并提交给NotificationManagerService
//tag,id一起确定通知的意图,包名则保证来自两个应用程序的相同的notification不会产生冲突
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
stripped, idOut, UserHandle.myUserId());
...
} catch (RemoteException e) {
}
}
//NotificationManagerService.java
public void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
Notification notification, int[] idOut, int userId) throws RemoteException {
enqueueNotificationInternal(pkg, opPkg, Binder.getCallingUid(),
Binder.getCallingPid(), tag, id, notification, idOut, userId);
}
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
final int callingPid, final String tag, final int id, final Notification notification,
int[] idOut, int incomingUserId) {
//安全性检查,获取包名的UID,与PackageManager中拥有相同包名的应用程序的UID进行比较,若不一样则抛出运行时异常
checkCallerIsSystemOrSameApp(pkg);
//判断是否是系统应用或者通知是否来自Android系统服务
final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg);
...
//倘若发送者所在的应用已经被禁止发送通知,则将此通知信息分数设置为垃圾分数(-1000),
if (ENABLE_BLOCKED_NOTIFICATIONS && !noteNotificationOp(pkg, callingUid)) {
if (!isSystemNotification) {
r.score = JUNK_SCORE;
Slog.e(TAG, "Suppressing notification from package " + pkg
+ " by user request.");
mUsageStats.registerBlocked(r);
}
}
//如果当前不是系统应用,且不是已注册的服务
//限制每个应用程序最多能提交50个通知,防止恶意软件通过注册大量的通知导致系统瘫痪
if (!isSystemNotification && !isNotificationFromListener) {
synchronized (mNotificationList) {
int count = 0;
final int N = mNotificationList.size();
for (int i=0; i<N; i++) {
...
}
}
}
.......
mHandler.post(new Runnable() {
@Override
public void run() {
synchronized (mNotificationList) {
//根据notification的重要性设置优先级别
notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN,
Notification.PRIORITY_MAX);
...
//根据优先级对通知进行打分,范围在-20 -- 20之间,分数过低则会被忽略
final int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER;
//创建StatusBarNotification,包装与此通知有关的信息,该对象是通知在StatusBarManagerService中的存在形式
final StatusBarNotification n = new StatusBarNotification(
pkg, opPkg, id, tag, callingUid, callingPid, score, notification,
user);
//创建NotificationRecord实例用于包装所有与此通知相关的信息,该对象是通知在NotificationManagerService中的存在形式
NotificationRecord r = new NotificationRecord(n, score);
//获取与新通知具有相同意图而被替换的notification
NotificationRecord old = mNotificationsByKey.get(n.getKey());
if (old != null) {
//保留排列信息
r.copyRankingInformation(old);
}
....
//获取具有相同意图的通知在mNotificationList中的位置,
int index = indexOfNotificationLocked(n.getKey());
if (index < 0) {
//若该通知不存在,则将新通知添加到列表中
mNotificationList.add(r);
mUsageStats.registerPostedByApp(r);
} else {
//否则将旧通知替换成新通知
old = mNotificationList.get(index);
mNotificationList.set(index, r);
mUsageStats.registerUpdatedByApp(r, old);
//保留原通知的状态,并设置当前通知所在的应用程序为正在运行的服务
notification.flags |=
old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
}
....
//若通知信息用于描述一个正在运行的服务则为其添加FLAG_ONGOING_EVENT和
//FLAG_NO_CLEAR两个标记,确保不会被用户删除
if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
notification.flags |= Notification.FLAG_ONGOING_EVENT
| Notification.FLAG_NO_CLEAR;
}
....
if (notification.getSmallIcon() != null) {
StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
//通知观察者通知消息有更新
mListeners.notifyPostedLocked(n, oldSbn);
} else {
...
}
//处理notification的声音和振动逻辑
buzzBeepBlinkLocked(r);
}
}
});
idOut[0] = id;
}
public void notifyPostedLocked(StatusBarNotification sbn, StatusBarNotification oldSbn) {
StatusBarNotification sbnClone = null;
StatusBarNotification sbnCloneLight = null;
for (final ManagedServiceInfo info : mServices) {
boolean sbnVisible = isVisibleToListener(sbn, info);
boolean oldSbnVisible = oldSbn != null ? isVisibleToListener(oldSbn, info) : false;
....
//启动发送操作
mHandler.post(new Runnable() {
@Override
public void run() {
notifyPosted(info, sbnToPost, update);
}
});
}
}
private void notifyPosted(final ManagedServiceInfo info,
final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate) {
//表示启用IPC通信
final INotificationListener listener = (INotificationListener)info.service;
StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
try {
//将notification通知到SystemUI,该方法在NotificationListenerService中
listener.onNotificationPosted(sbnHolder, rankingUpdate);
} catch (RemoteException ex) {
Log.e(TAG, "unable to notify listener (posted): " + listener, ex);
}
}
@Override
public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
NotificationRankingUpdate update) {
...
try {
//将通过Binder机制传过来的数据重新组装成一些现实View所需要的数据
Notification.Builder.rebuild(getContext(), sbn.getNotification());
...
} catch (IllegalArgumentException e) {
...
}
synchronized (mWrapper) {
applyUpdate(update);
try {
if (sbn != null) {//若通知对象不为空
//传送通知,会远程调用BaseStatusBar中的方法
NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
} else {
NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
}
}
...
}
}
BaseStatusBar.java
@Override
public void onNotificationPosted(final StatusBarNotification sbn,
final RankingMap rankingMap) {
if (sbn != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
...
if (!ENABLE_CHILD_NOTIFICATIONS
&& mGroupManager.isChildInGroupWithSummary(sbn)) {
if (isUpdate) {
removeNotification(key, rankingMap);
} else {
mNotificationData.updateRanking(rankingMap);
}
return;
}
if (isUpdate) {
//更新通知
updateNotification(sbn, rankingMap);
} else {
//添加通知
addNotification(sbn, rankingMap, null /* oldEntry */);
}
}
});
}
}
@Override
public void start() {
if (DEBUG) Log.d(TAG, "start");
mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
mServiceMonitor.start(); //回调到SystemBars的onNoService()方法
}
@Override
public void onNoService() {
if (DEBUG) Log.d(TAG, "onNoService");
createStatusBarFromConfig();
}
//<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
//得到/systemUI/res/value/config.xml中的config_statusBarComponent属性值
final String clsName = mContext.getString(R.string.config_statusBarComponent);
Class<?> cls = null;
try {
//加载PhoneStatusBar类
cls = mContext.getClassLoader().loadClass(clsName);
} catch (Throwable t) {
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
//获取PhoneStatusBar的实例
mStatusBar = (BaseStatusBar) cls.newInstance();
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
}
//PhoneStatusBar.java
public void start() {
//获取WindowManager的对象
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
updateDisplaySize();
mScrimSrcModeEnabled = mContext.getResources().getBoolean(
R.bool.config_status_bar_scrim_behind_use_src);
//调用BaseStatusBar中的start()方法
super.start();
.......
addNavigationBar();//实例化导航条
// 实例化PhoneStatusBarPolicy来设置或更新所有的图标
mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController,
mUserInfoController, mBluetoothController);
mIconPolicy.setCurrentUserSetup(mUserSetup);
mSettingsObserver.onChange(false);
....
}
//BaseStatusBar.java
public void start() {
......
// 实例化iconLiist,这时的iconList为空值
StatusBarIconList iconList = new StatusBarIconList();
//通过CommandQueue实现StatusBarManagerService与SystemUI的通信
mCommandQueue = new CommandQueue(this, iconList);
int[] switches = new int[8];
ArrayList<IBinder> binders = new ArrayList<IBinder>();
try {
//将iconlist注册到StatusBarManagerService中
mBarService.registerStatusBar(mCommandQueue, iconList, switches, binders);
} catch (RemoteException ex) {
}
//初始化statusbar,notification,quickSetting等View控件
createAndAddWindows();
.........
try {
//NotificationListenerService主要实现StatusBarServiceManager和SystemUI的Notification控制通道
//当StatusBarServiceManager收到Notification时,通过此通道通知SystemUI显示Notification的变化
mNotificationListener.registerAsSystemService(mContext,
new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()),
UserHandle.USER_ALL);
} catch (RemoteException e) {
Log.e(TAG, "Unable to register notification listener", e);
}
.....
}
//实现StatusBarServiceManager与SystemUI的Notification的控制通道
private final NotificationListenerService mNotificationListener =
new NotificationListenerService() {
@Override
public void onListenerConnected() {
if (DEBUG) Log.d(TAG, "onListenerConnected");
final StatusBarNotification[] notifications = getActiveNotifications();
final RankingMap currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
for (StatusBarNotification sbn : notifications) {
addNotification(sbn, currentRanking, null);
}
}
});
}
//Notification处理流程,App中会获取NotificationManager的对象,调用notify()方法
//NotificationManager.java
//参数tag表示该notification的标识符,每个notification的id都是唯一的
public void notify(String tag, int id, Notification notification)
{
int[] idOut = new int[1];
//service为NotificationManagerService的实例,在SystemServer中启动
INotificationManager service = getService();
//获取信息发送者的包名
String pkg = mContext.getPackageName();
...
try {
//将包名,tag,id,notification实例一并提交给NotificationManagerService
//tag,id一起确定通知的意图,包名则保证来自两个应用程序的相同的notification不会产生冲突
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
stripped, idOut, UserHandle.myUserId());
...
} catch (RemoteException e) {
}
}
//NotificationManagerService.java
public void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
Notification notification, int[] idOut, int userId) throws RemoteException {
enqueueNotificationInternal(pkg, opPkg, Binder.getCallingUid(),
Binder.getCallingPid(), tag, id, notification, idOut, userId);
}
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
final int callingPid, final String tag, final int id, final Notification notification,
int[] idOut, int incomingUserId) {
//安全性检查,获取包名的UID,与PackageManager中拥有相同包名的应用程序的UID进行比较,若不一样则抛出运行时异常
checkCallerIsSystemOrSameApp(pkg);
//判断是否是系统应用或者通知是否来自Android系统服务
final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
final boolean isNotificationFromListener = mListeners.isListenerPackage(pkg);
...
//倘若发送者所在的应用已经被禁止发送通知,则将此通知信息分数设置为垃圾分数(-1000),
if (ENABLE_BLOCKED_NOTIFICATIONS && !noteNotificationOp(pkg, callingUid)) {
if (!isSystemNotification) {
r.score = JUNK_SCORE;
Slog.e(TAG, "Suppressing notification from package " + pkg
+ " by user request.");
mUsageStats.registerBlocked(r);
}
}
//如果当前不是系统应用,且不是已注册的服务
//限制每个应用程序最多能提交50个通知,防止恶意软件通过注册大量的通知导致系统瘫痪
if (!isSystemNotification && !isNotificationFromListener) {
synchronized (mNotificationList) {
int count = 0;
final int N = mNotificationList.size();
for (int i=0; i<N; i++) {
...
}
}
}
.......
mHandler.post(new Runnable() {
@Override
public void run() {
synchronized (mNotificationList) {
//根据notification的重要性设置优先级别
notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN,
Notification.PRIORITY_MAX);
...
//根据优先级对通知进行打分,范围在-20 -- 20之间,分数过低则会被忽略
final int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER;
//创建StatusBarNotification,包装与此通知有关的信息,该对象是通知在StatusBarManagerService中的存在形式
final StatusBarNotification n = new StatusBarNotification(
pkg, opPkg, id, tag, callingUid, callingPid, score, notification,
user);
//创建NotificationRecord实例用于包装所有与此通知相关的信息,该对象是通知在NotificationManagerService中的存在形式
NotificationRecord r = new NotificationRecord(n, score);
//获取与新通知具有相同意图而被替换的notification
NotificationRecord old = mNotificationsByKey.get(n.getKey());
if (old != null) {
//保留排列信息
r.copyRankingInformation(old);
}
....
//获取具有相同意图的通知在mNotificationList中的位置,
int index = indexOfNotificationLocked(n.getKey());
if (index < 0) {
//若该通知不存在,则将新通知添加到列表中
mNotificationList.add(r);
mUsageStats.registerPostedByApp(r);
} else {
//否则将旧通知替换成新通知
old = mNotificationList.get(index);
mNotificationList.set(index, r);
mUsageStats.registerUpdatedByApp(r, old);
//保留原通知的状态,并设置当前通知所在的应用程序为正在运行的服务
notification.flags |=
old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
}
....
//若通知信息用于描述一个正在运行的服务则为其添加FLAG_ONGOING_EVENT和
//FLAG_NO_CLEAR两个标记,确保不会被用户删除
if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
notification.flags |= Notification.FLAG_ONGOING_EVENT
| Notification.FLAG_NO_CLEAR;
}
....
if (notification.getSmallIcon() != null) {
StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
//通知观察者通知消息有更新
mListeners.notifyPostedLocked(n, oldSbn);
} else {
...
}
//处理notification的声音和振动逻辑
buzzBeepBlinkLocked(r);
}
}
});
idOut[0] = id;
}
public void notifyPostedLocked(StatusBarNotification sbn, StatusBarNotification oldSbn) {
StatusBarNotification sbnClone = null;
StatusBarNotification sbnCloneLight = null;
for (final ManagedServiceInfo info : mServices) {
boolean sbnVisible = isVisibleToListener(sbn, info);
boolean oldSbnVisible = oldSbn != null ? isVisibleToListener(oldSbn, info) : false;
....
//启动发送操作
mHandler.post(new Runnable() {
@Override
public void run() {
notifyPosted(info, sbnToPost, update);
}
});
}
}
private void notifyPosted(final ManagedServiceInfo info,
final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate) {
//表示启用IPC通信
final INotificationListener listener = (INotificationListener)info.service;
StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
try {
//将notification通知到SystemUI,该方法在NotificationListenerService中
listener.onNotificationPosted(sbnHolder, rankingUpdate);
} catch (RemoteException ex) {
Log.e(TAG, "unable to notify listener (posted): " + listener, ex);
}
}
@Override
public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
NotificationRankingUpdate update) {
...
try {
//将通过Binder机制传过来的数据重新组装成一些现实View所需要的数据
Notification.Builder.rebuild(getContext(), sbn.getNotification());
...
} catch (IllegalArgumentException e) {
...
}
synchronized (mWrapper) {
applyUpdate(update);
try {
if (sbn != null) {//若通知对象不为空
//传送通知,会远程调用BaseStatusBar中的方法
NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
} else {
NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
}
}
...
}
}
BaseStatusBar.java
@Override
public void onNotificationPosted(final StatusBarNotification sbn,
final RankingMap rankingMap) {
if (sbn != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
...
if (!ENABLE_CHILD_NOTIFICATIONS
&& mGroupManager.isChildInGroupWithSummary(sbn)) {
if (isUpdate) {
removeNotification(key, rankingMap);
} else {
mNotificationData.updateRanking(rankingMap);
}
return;
}
if (isUpdate) {
//更新通知
updateNotification(sbn, rankingMap);
} else {
//添加通知
addNotification(sbn, rankingMap, null /* oldEntry */);
}
}
});
}
}