At the end of the previous article about how Android gets the music information of a third-party music player, it is mentioned that the information of the currently played song can be obtained by capturing the Notification sent by a third-party music player. First, analyze the Notification update mechanism.
Service involved:
StatusBarManagerService
Icationicationmanagerservice
Both services will be started in the frameworks/base/services/java/com/android/server/SystemServer. java file.
class ServerThread extends Thread { public void run() {...... StatusBarManagerService statusBar = null; NotificationManagerService notification = null;...... statusBar = new StatusBarManagerService(context, wm); ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);...... notification = new NotificationManagerService(context, statusBar, lights); ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);...... }}
The following describes the y process of Notification tracing.
1.
When a Notification is created in the Activity
NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); Notification n = new Notification(R.drawable.chat, "Hello,there!", System.currentTimeMillis()); n.flags = Notification.FLAG_AUTO_CANCEL; Intent i = new Intent(arg0.getContext(), NotificationShow.class);i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); //PendingIntentPendingIntent contentIntent = PendingIntent.getActivity( arg0.getContext(), R.string.app_name, i, PendingIntent.FLAG_UPDATE_CURRENT); n.setLatestEventInfo( arg0.getContext(), "Hello,there!", "Hello,there,I'm john.", contentIntent);nm.notify(R.string.app_name, n);
2. Call icationicationmanager. Y to enter the notify method.
public void notify(int id, Notification notification) { notify(null, id, notification); } public void notify(String tag, int id, Notification notification) {...... INotificationManager service = getService();...... service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id, notification, idOut, UserHandle.myUserId());...... }
3. getService () is called when notify (String tag, int id, Notification notification) is called ()
static public INotificationManager getService()78 {79 if (sService != null) {80 return sService;81 }82 IBinder b = ServiceManager.getService("notification");83 sService = INotificationManager.Stub.asInterface(b);84 return sService;85 }
It is found that ServiceManager. getService ("notification") is called, so that a binder object of icationicationmanagerservice is obtained from the beginning of the article. Get back to step 2 call service. enqueuenotifwitwithtag.
4. Enter enqueuenotifwithtag of icationicationmanagerservice
public void enqueueNotificationWithTag(String pkg, String basePkg, String tag, int id,1621 Notification notification, int[] idOut, int userId)1622 {1623 enqueueNotificationInternal(pkg, basePkg, Binder.getCallingUid(), Binder.getCallingPid(),1624 tag, id, notification, idOut, userId);1625 }1634 public void enqueueNotificationInternal(final String pkg, String basePkg, final int callingUid,1635 final int callingPid, final String tag, final int id, final Notification notification,1636 int[] idOut, int incomingUserId)1637 {......final StatusBarNotification n = new StatusBarNotification(1755 pkg, id, tag, callingUid, callingPid, score, notification, user);1792 mStatusBar.updateNotification(r.statusBarKey, n);1793 ...... }
In this method, the previously passed Notification is encapsulated into a StatusBarNotification object, and then mStatusBar. updateNotification is called to update. What is the mStatusBar?
5. The document mentioned at the beginning that icationicationmanagerservice will be added to the ServerThread, and its constructor will be called when the NotificationManagerService is created.
NotificationManagerService(Context context, StatusBarManagerService statusBar,1291 LightsService lights)1292 { ....... }
This will be passed in. The StatusBarManagerService just created in ServerThread. Therefore, we can call mStatusBar. updateNotification () in step 1 ().
6. The mStatusBar. updateNotification () method in StatusBarManagerService
public void updateNotification(IBinder key, StatusBarNotification notification) {512 synchronized (mNotifications) {516 mNotifications.put(key, notification);......519 mBar.updateNotification(key, notification);......524 }
Here, mBar. updateNotification () is called. What is mBar?
7. The mBar object in StatusBarManagerService
volatile IStatusBar mBar; // Callbacks from the status bar service.428 // ================================================================================429 public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,430 List
notificationKeys, List
notifications,431 int switches[], List
binders) {......
The above shows a registerStatusBar method that will pass in an IStatusBar object. Where can this method be called?
8. In StatusBarManagerService, we found that calling the mBar object is to process the StatusBar UI. Where is the StatusBar? In SystemUI. After retrieving the SystemUI code, we found that
In BaseStatusBar:
public void start() { mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications,250 switches, binders);}
Here, registerStatusBar, And the mCommandQueue parameter is the IStatusBar object.
9. mCommanQueue variable
protected CommandQueue mCommandQueue;
28/**29 * This class takes the functions from IStatusBar that come in on30 * binder pool threads and posts messages to get them onto the main31 * thread, and calls onto Callbacks. It also takes care of32 * coalescing these calls so they don't stack up. For the calls33 * are coalesced, note that they are all idempotent.34 */35public class CommandQueue extends IStatusBar.Stub{/**78 * These methods are called back on the main thread.79 */80 public interface Callbacks {81 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon);82 public void updateIcon(String slot, int index, int viewIndex,83 StatusBarIcon old, StatusBarIcon icon);84 public void removeIcon(String slot, int index, int viewIndex);85 public void addNotification(IBinder key, StatusBarNotification notification);86 public void updateNotification(IBinder key, StatusBarNotification notification);87 public void removeNotification(IBinder key);88 public void disable(int state);89 public void animateExpandNotificationsPanel();90 public void animateCollapsePanels(int flags);91 public void animateExpandSettingsPanel();92 public void setSystemUiVisibility(int vis, int mask);93 public void topAppWindowChanged(boolean visible);94 public void setImeWindowStatus(IBinder token, int vis, int backDisposition);95 public void setHardKeyboardStatus(boolean available, boolean enabled);96 public void toggleRecentApps();97 public void preloadRecentApps();98 public void showSearchPanel();99 public void hideSearchPanel();100 public void cancelPreloadRecentApps();101 public void setNavigationIconHints(int hints);102 public void setWindowState(int window, int state);103 }}
We found that this method inherits IStatusBar. stub, which contains a series of callback functions. These callback functions are implemented in BaseStatusBar
public abstract class BaseStatusBar extends SystemUI implements79 CommandQueue.Callbacks {
10. Return to Step 1. When mBar. updateNotification is called in StatusBarManagerService, The UpdateNotification method implemented in BaseStatusBar will be called based on the analysis of 7, 8, and 9.
updateNotification(IBinder key, StatusBarNotification notification) {......}
The Notification is displayed on the StatusBar.
This mainly involves the interaction between two icationicationmanagerservice and StatusBarManager.
Step 1.
When the system starts, StatusBarManagerService and icationicationmanagerservice are generated in ServerThread, And the StatusBarManagerService object is passed as a parameter to the icationicationmanagerservice constructor.
The system loads the application. In SystemUI, BaseStatusBar implements the callback function CommandQueue. Callbacks, and calls the StatusBarManagerService's registerStatusBar method to pass the CommandQueue object in.
Step 2
The notify method is called in the Activity, and the Notification is encapsulated into StatusBarNotification in icationicationmanagerservice.
Icationicationmanagerservice calls the updateNotification () of statusBarManagerService ().
Step 3
StatusBarManagerService calls the callback function implemented by CommandQueue and displays the Notification on SystemUI.
The next article will show how to capture Notification content to collect information about playing music from a third-party player.