Android 9.0系统源码_通知服务(二)系统状态栏是如何监听通知服务的各种通知事件的

前言

上一篇文章简单讲述了系统通知服务NotificationManagerService的启动流程,本篇文章我们将会具体梳理一下SystemUI组件系统状态栏StatusBar是如何监听通知服务的各种通知事件的。

一、StatusBar调用NotificationListener的setUpWithPresenter

1、我们在Android 9.0系统源码_SystemUI(一)SystemUI的启动流程系列文章有具体分析过SystemUI的启动流程,在状态栏StatusBar被创建之后,首先触发的便是start方法。

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

public class StatusBar extends SystemUI implements DemoMode,
        DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
        OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
        ColorExtractor.OnColorsChangedListener, ConfigurationListener, NotificationPresenter {
    
    protected NotificationListener mNotificationListener;
    protected NotificationEntryManager mEntryManager;

    @Override
    public void start() {
        ...代码省略...
        mNotificationListener =  Dependency.get(NotificationListener.class);
        mEntryManager = Dependency.get(NotificationEntryManager.class);
    	...代码省略...
        createAndAddWindows();//创建状态栏并添加到窗口上
    	...代码省略...
        // Set up the initial notification state.
        //监听NotificationManagerService的通知消息
        mNotificationListener.setUpWithPresenter(this, mEntryManager);
	   	...代码省略...
    }

}

在start方法中会获取NotificationListener实例对象,并调用该对象的setUpWithPresenter方法。

二、NotificationListener设置通知服务的回调方法。

1、NotificationListener的setUpWithPresenter方法如下所示。

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java

public class NotificationListener extends NotificationListenerWithPlugins {

    private static final String TAG = "NotificationListener";
    private final Context mContext;
    protected NotificationPresenter mPresenter;
    protected NotificationEntryManager mEntryManager;

    public NotificationListener(Context context) {
        mContext = context;
    }

    @Override
    public void onListenerConnected() {
 		...连接成功...
    }

    @Override
    public void onNotificationPosted(final StatusBarNotification sbn,
            final RankingMap rankingMap) {
     	...新的通知...
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn,
            final RankingMap rankingMap) {
 		...移除通知...
    }

    @Override
    public void onNotificationRankingUpdate(final RankingMap rankingMap) {
 		...更新通知...
    }

    public void setUpWithPresenter(NotificationPresenter presenter, NotificationEntryManager entryManager) {
        mPresenter = presenter;
        mEntryManager = entryManager;
        try {
            registerAsSystemService(mContext, new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()), UserHandle.USER_ALL);
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to register notification listener", e);
        }
    }
}

NotificationListener自身的各种回调方法会在特定情况下被通知服务所触发,而设置监听通知服务的setUpWithPresenter方法在给mPresenter和mEntryManager赋值之后,会进一步调用父类NotificationListenerWithPlugins的registerAsSystemService方法。

2、NotificationListenerWithPlugins的registerAsSystemService方法如下所示。

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java

public class NotificationListenerWithPlugins extends NotificationListenerService implements
        PluginListener<NotificationListenerController> {
    @Override
    public void registerAsSystemService(Context context, ComponentName componentName,
            int currentUser) throws RemoteException {
        super.registerAsSystemService(context, componentName, currentUser);
        Dependency.get(PluginManager.class).addPluginListener(this, NotificationListenerController.class);
    }
}

3、NotificationListenerWithPlugins会继续调用自己的父类NotificationListenerService的registerAsSystemService方法。

frameworks/base/core/java/android/service/notification/NotificationListenerService.java

public abstract class NotificationListenerService extends Service {
    
    protected NotificationListenerWrapper mWrapper = null;
    protected Context mSystemContext;
    private Handler mHandler;
    protected int mCurrentUser;

    public void registerAsSystemService(Context context, ComponentName componentName,
            int currentUser) throws RemoteException {
        if (mWrapper == null) {
            // 这就是要注册的Binder,也就一个回调
            mWrapper = new NotificationListenerWrapper();
        }
        mSystemContext = context;
        INotificationManager noMan = getNotificationInterface();
        mHandler = new MyHandler(context.getMainLooper());
        mCurrentUser = currentUser;
        //向通知服务NotificationManagerService注册回调
        noMan.registerListener(mWrapper, componentName, currentUser);
    }
    
    //获取通知服务
    protected final INotificationManager getNotificationInterface() {
        if (mNoMan == null) {
            mNoMan = INotificationManager.Stub.asInterface(
                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
        }
        return mNoMan;
    }
    
    //回调对象
    protected class NotificationListenerWrapper extends INotificationListener.Stub {
    
       @Override
        public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
                NotificationRankingUpdate update) {
         	...有通知事件...
        }
        @Override
        public void onListenerConnected(NotificationRankingUpdate update) {
         	...连接成功...
        }
     }
}

NotificationListenerService的registerAsSystemService方法首先创建一个类型为NotificationListenerWrapper的mWrapper对象,NotificationListenerWrapper是NotificationListenerService的内部类,该类实现了INotificationListener.Stub,然后会调用getNotificationInterface方法,获取NotificationManagerService对象实例并调用registerListener方法。

5、NotificationManagerService的registerListener方法如下所示。

public class NotificationManagerService extends SystemService {

 	private NotificationListeners mListeners;//主要用于管理通知的接收者
 	
  	void init(Looper looper, IPackageManager packageManager,
            PackageManager packageManagerClient,
            LightsManager lightsManager, NotificationListeners notificationListeners,
            NotificationAssistants notificationAssistants, ConditionProviders conditionProviders,
            ICompanionDeviceManager companionManager, SnoozeHelper snoozeHelper,
            NotificationUsageStats usageStats, AtomicFile policyFile,
            ActivityManager activityManager, GroupHelper groupHelper, IActivityManager am,
            UsageStatsManagerInternal appUsageStats, DevicePolicyManagerInternal dpm) {
            		...代码省略...
                    // This is a ManagedServices object that keeps track of the listeners.
        			mListeners = notificationListeners;
        			...代码省略...
           }
      @Override
      public void registerListener(final INotificationListener listener,
              final ComponentName component, final int userid) {
          enforceSystemOrSystemUI("INotificationManager.registerListener");
          mListeners.registerService(listener, component, userid);
      }
}

这里的mListeners,其实就是NotificationManagerService的init方法中提到类型为NotificationListeners的mListeners。

6、NotificationListeners是NotificationManagerService的内部类。

public class NotificationManagerService extends SystemService {

    public class NotificationListeners extends ManagedServices {
        private final ArraySet<ManagedServiceInfo> mLightTrimListeners = new ArraySet<>();
        public NotificationListeners(IPackageManager pm) {
            super(getContext(), mNotificationLock, mUserProfiles, pm);
        }

    }
}

7、我们在NotificationListeners类中并不能找到registerService方法,这是因为该方法定义在他的父类ManagedServices中。

frameworks/base/services/core/java/com/android/server/notification/ManagedServices.java

abstract public class ManagedServices {

    public void registerService(IInterface service, ComponentName component, int userid) {
        checkNotNull(service);
        //继续调用registerServiceImpl
        ManagedServiceInfo info = registerServiceImpl(service, component, userid);
        if (info != null) {
            onServiceAdded(info);
        }
    }
    
    private ManagedServiceInfo registerServiceImpl(final IInterface service,
            final ComponentName component, final int userid) {
        //调用newServiceInfo方法创建ManagedServiceInfo对象实例
        ManagedServiceInfo info = newServiceInfo(service, component, userid,
                true /*isSystem*/, null /*connection*/, Build.VERSION_CODES.LOLLIPOP);
        //将新创建的ManagedServiceInfo作为参数继续调用registerServiceImpl方法。
        return registerServiceImpl(info);
    }

    private ManagedServiceInfo newServiceInfo(IInterface service,
            ComponentName component, int userId, boolean isSystem, ServiceConnection connection,
            int targetSdkVersion) {
        //创建ManagedServiceInfo对象实例
        return new ManagedServiceInfo(service, component, userId, isSystem, connection,
                targetSdkVersion);
    }

|

8、ManagedServiceInfo 是 ManagedServices 的内部类。

abstract public class ManagedServices {
	public class ManagedServiceInfo implements IBinder.DeathRecipient {
	        public IInterface service;//指向的就是前面提到的NotificationListenerWrapper对象,是一个代理对象
	        public ComponentName component;
	        public int userid;
	        public boolean isSystem;
	        public ServiceConnection connection;
	        public int targetSdkVersion;
	 
	        public ManagedServiceInfo(IInterface service, ComponentName component,
	                int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion) {
	            this.service = service;
	            this.component = component;
	            this.userid = userid;
	            this.isSystem = isSystem;
	            this.connection = connection;
	            this.targetSdkVersion = targetSdkVersion;
	        }
	 }
 }       

结合ManagedServiceInfo的构造方法可知,最终时将前面提到的NotificationListenerWrapper对象赋值给了类型为IInterface的变量service,NotificationListenerWrapper是一个代理对象,该对象运行在SystemUI进程中用于接收系统通知。

9、在ManagedServiceInfo 对象创建完毕之后,会继续调用registerServiceImpl方法。

abstract public class ManagedServices {
    private final ArrayList<ManagedServiceInfo> mServices = new ArrayList<>();
    private ManagedServiceInfo registerServiceImpl(ManagedServiceInfo info) {
        synchronized (mMutex) {
            try {
                info.service.asBinder().linkToDeath(info, 0);
                mServices.add(info);
                return info;
            } catch (RemoteException e) {
                // already dead
            }
        }
        return null;
    }
}    

由上可知最终将ManagedServiceInfo实例对象存储在了类型为集合mServices中。

10、重新回到前面第7步,在创建完ManagedServiceInfo对象之后,如果创建的ManagedServiceInfo实例对象不为空,则会调用onServiceAdded方法。

abstract public class ManagedServices {
    private final ArrayList<ManagedServiceInfo> mServices = new ArrayList<>();
    public void registerService(IInterface service, ComponentName component, int userid) {
        checkNotNull(service);
        //继续调用registerServiceImpl
        ManagedServiceInfo info = registerServiceImpl(service, component, userid);
        if (info != null) {
            onServiceAdded(info);
        }
    }
    abstract protected void onServiceAdded(ManagedServiceInfo info); 
 }

11、onServiceAdded方法是一个抽象方法,具体实现是在前面提到的NotificationManagerService的内部类NotificationListeners中。

public class NotificationManagerService extends SystemService {

    public class NotificationListeners extends ManagedServices {
        @Override
        public void onServiceAdded(ManagedServiceInfo info) {
            final INotificationListener listener = (INotificationListener) info.service;
            final NotificationRankingUpdate update;
            synchronized (mNotificationLock) {
                update = makeRankingUpdateLocked(info);
            }
            try {
            	//注册成功,开始进行回调通知
                listener.onListenerConnected(update);
            } catch (RemoteException e) {
                // we tried
            }
        }
   }
}

绕了这么一大圈,总算是触发INotificationListener的onListenerConnected回调方法了,而INotificationListener的具体实现者我们前面有提到,就是NotificationListenerService的内部类NotificationListenerWrapper。

三、NotificationListener设置回调方法被触发。

1、NotificationListenerService$NotificationListenerWrapper类中和onListenerConnected回调方法相关的代码如下所示。

public abstract class NotificationListenerService extends Service {

    private Handler mHandler;
    
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        mHandler = new MyHandler(getMainLooper());
    }
    
    private final class MyHandler extends Handler {
    
        public static final int MSG_ON_LISTENER_CONNECTED = 3;

        public MyHandler(Looper looper) {
            super(looper, null, false);
        }

        @Override
        public void handleMessage(Message msg) {
            if (!isConnected) {
                return;
            }
            switch (msg.what) {
              	...代码省略...
                case MSG_ON_LISTENER_CONNECTED: {
                	//回调会NotificationListenerService的onListenerConnected方法。
                    onListenerConnected();
                } break;
               ...代码省略...
           }
    }
    
    public void onListenerConnected() {
        ...连接成功...
    }
    
    //回调对象
    protected class NotificationListenerWrapper extends INotificationListener.Stub {
    
       @Override
        public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
                NotificationRankingUpdate update) {
         	...有通知事件...
        }
        
        //和通知服务建立连接成功
        @Override
        public void onListenerConnected(NotificationRankingUpdate update) {
           // protect subclass from concurrent modifications of (@link mNotificationKeys}.
            Log.d("NotificationListenerService","onListenerConnected exec");
            synchronized (mLock) {
                applyUpdateLocked(update);
            }
            isConnected = true;
            //发送消息,触发MyHandler的handleMessage方法。
            mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_CONNECTED).sendToTarget();
        }
     }
}

NotificationListenerService$NotificationListenerWrapper的onListenerConnected方法会调用mHandler发送类型为MSG_ON_LISTENER_CONNECTED的消息,该消息会触发MyHandler的handleMessage方法,最终触发NotificationListenerService 类的onListenerConnected方法。由于NotificationListener就是继承自NotificationListenerService的,并且它还重写了onListenerConnected方法,这样回调就来到了它这边。

2、当通知服务NotificationManangerService收到其他的各种通知事件的时候,NotificationListenerWrapper的各个回调方法便会被触发,然后通过类型为MyHandler的mHandler发送对应的消息,进一步触发NotificationListenerService所对应的回调方法,也就是NotificationListener的回调方法。

public class NotificationListener extends NotificationListenerWithPlugins {

    private static final String TAG = "NotificationListener";
    private final Context mContext;
    protected NotificationPresenter mPresenter;
    protected NotificationEntryManager mEntryManager;

    public NotificationListener(Context context) {
        mContext = context;
    }

    @Override
    public void onListenerConnected() {
 		...连接成功...
    }

    @Override
    public void onNotificationPosted(final StatusBarNotification sbn,
            final RankingMap rankingMap) {
        if (sbn != null && !onPluginNotificationPosted(sbn, rankingMap)) {
            // 在主线程中进行更新
            mPresenter.getHandler().post(() -> {
                processForRemoteInput(sbn.getNotification(), mContext);
                String key = sbn.getKey();
                mEntryManager.removeKeyKeptForRemoteInput(key);
                boolean isUpdate = mEntryManager.getNotificationData().get(key) != null;
                // In case we don't allow child notifications, we ignore children of
                // notifications that have a summary, since` we're not going to show them
                // anyway. This is true also when the summary is canceled,
                // because children are automatically canceled by NoMan in that case.
                if (!ENABLE_CHILD_NOTIFICATIONS
                        && mPresenter.getGroupManager().isChildInGroupWithSummary(sbn)) {
                    if (DEBUG) {
                        Log.d(TAG, "Ignoring group child due to existing summary: " + sbn);
                    }

                    // Remove existing notification to avoid stale data.
                    if (isUpdate) {
                        mEntryManager.removeNotification(key, rankingMap);
                    } else {
                        mEntryManager.getNotificationData()
                                .updateRanking(rankingMap);
                    }
                    return;
                }
                //判断到来的通知是需要更新还是添加
                if (isUpdate) {
                    // 更新通知操作
                    mEntryManager.updateNotification(sbn, rankingMap);
                } else {
                    // 添加新通知操作
                    mEntryManager.addNotification(sbn, rankingMap);
                }
            });
        }
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn,
            final RankingMap rankingMap) {
 		...移除通知...
    }

    @Override
    public void onNotificationRankingUpdate(final RankingMap rankingMap) {
 		...更新通知...
    }

    public void setUpWithPresenter(NotificationPresenter presenter, NotificationEntryManager entryManager) {
        mPresenter = presenter;
        mEntryManager = entryManager;
        try {
            registerAsSystemService(mContext, new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()), UserHandle.USER_ALL);
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to register notification listener", e);
        }
    }
}

四、总结

系统状态栏是如何监听通知服务的各种通知事件的

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值