telephonyRegistry = new TelephonyRegistry(context); ServiceManager.addService("telephony.registry", telephonyRegistry);从这个注册过程中看到, 该Service注册的名字为“telephony.registry”。
下面来看TelephonyRegistry的通知机制。
下面分别来介绍。
protected DefaultPhoneNotifier() { mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry")); }在这里,我们看到DefaultPhoneNotifier从ServiceManager中获取了TelephonyRegistry的服务,也就是说, DefaultPhoneNotifier是TelephonyRegistry的Client。
@GsmCallTracker.java private void updatePhoneState() { PhoneConstants.State oldState = mState; if (mRingingCall.isRinging()) { mState = PhoneConstants.State.RINGING; } else if (mPendingMO != null || !(mForegroundCall.isIdle() && mBackgroundCall.isIdle())) { mState = PhoneConstants.State.OFFHOOK; } else { mState = PhoneConstants.State.IDLE; } if (mState == PhoneConstants.State.IDLE && oldState != mState) { mVoiceCallEndedRegistrants.notifyRegistrants( new AsyncResult(null, null, null)); } else if (oldState == PhoneConstants.State.IDLE && oldState != mState) { mVoiceCallStartedRegistrants.notifyRegistrants ( new AsyncResult(null, null, null)); } if (mState != oldState) { //给GSMPhone发送通知 mPhone.notifyPhoneStateChanged(); } }上面的mPhone对象就是GSMPhone,接下来我们将会看到,GSMPhone会把通知转交给DefaultPhoneNotifier来处理:
@GSMPhone.java void notifyPhoneStateChanged() { mNotifier.notifyPhoneState(this); }这里的mNotifier就是创建GSMPhone对象时传递的DefaultPhoneNotifier对象,这样的话,就将通知发送到了DefaultPhoneNotifier内部:
@DefaultPhoneNotifier.java public void notifyPhoneState(Phone sender) { Call ringingCall = sender.getRingingCall(); String incomingNumber = ""; if (ringingCall != null && ringingCall.getEarliestConnection() != null){ incomingNumber = ringingCall.getEarliestConnection().getAddress(); } try { //将状态发送给TelephonyRegistry mRegistry.notifyCallState(convertCallState(sender.getState()), incomingNumber); } catch (RemoteException ex) { } }从这里我们看到,DefaultPhoneNotifier将当前GsmCallTracker中的状态(sender.getState())通过convertCallState()转换后,传递给TelephonyRegistry,这个转换的作用就是,将GsmCallTracker中的IDLE、RINGING、OFFHOOK状态转换为TelephonyManager中的对应状态:
@TelephonyManager.java public static final int CALL_STATE_IDLE = 0; public static final int CALL_STATE_RINGING = 1; public static final int CALL_STATE_OFFHOOK = 2;
就这样,DefaultPhoneNotifier作为TelephonyRegistry的Client,将当前通话状态传递给了TelephonyRegistry。
在TelephonyRegistry拿到消息后,需要向两个渠道分发消息,一个是通过系统广播,另一个是向自己注册的监听者。我们主要来看向监听者发送消息的流程。
@TelephonyRegistry.java public void listen(String pkgForDebug, IPhoneStateListener callback, int events, boolean notifyNow) { //获取调用者的UID,监测权限 int callerUid = UserHandle.getCallingUserId(); int myUid = UserHandle.myUserId(); if (events != 0) { //权限监测 checkListenerPermission(events); synchronized (mRecords) { Record r = null; find_and_add: { //获取当前监听者信息 IBinder b = callback.asBinder(); final int N = mRecords.size(); for (int i = 0; i < N; i++) { r = mRecords.get(i); if (b == r.binder) { break find_and_add; } } r = new Record(); r.binder = b; r.callback = callback; r.pkgForDebug = pkgForDebug; r.callerUid = callerUid; //添加当前的监听者信息 mRecords.add(r); } int send = events & (events ^ r.events); r.events = events; //需要立刻通知 if (notifyNow) { if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { //监听通话状态 try { r.callback.onServiceStateChanged(new ServiceState(mServiceState)); } catch (RemoteException ex) { remove(r.binder); } } if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { //监听信号改变 try { int gsmSignalStrength = mSignalStrength.getGsmSignalStrength(); r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 : gsmSignalStrength)); } catch (RemoteException ex) { remove(r.binder); } } if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { try { r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting); } catch (RemoteException ex) { remove(r.binder); } } if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { //监听呼叫转移状态 try { r.callback.onCallForwardingIndicatorChanged(mCallForwarding); } catch (RemoteException ex) { remove(r.binder); } } } } } else { remove(callback.asBinder()); } }上面的listen()操作,依次完成了如下动作:
经过这些操作,客户端就完成了对TelephonyRegistry的监听注册,等待接收通知。
@TelephonyRegistry.java public void notifyCallState(int state, String incomingNumber) { //权限检查 if (!checkNotifyPermission("notifyCallState()")) { return; } synchronized (mRecords) { mCallState = state; mCallIncomingNumber = incomingNumber; for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) { try { //通知所有监听者 r.callback.onCallStateChanged(state, incomingNumber); } catch (RemoteException ex) { mRemoveList.add(r.binder); } } } //发送广播通知 handleRemoveListLocked(); } broadcastCallStateChanged(state, incomingNumber); }在上面这个方法中,先对通知者进行权限检查,然后在mRecords中查找曾经注册了该事件的监听者,并调用他们的回调方法。最后,又将该消息发送到系统广播中。
至此,通话状态改变的消息就从GsmCallTracker通过DefaultPhoneNotifier传递给了TelephonyRegistry,并从此扩散。类似的,对于数据连接状态来说,将会由DcTracker通过DefaultPhoneNotifier传递给TelephonyRegistry,然后进行扩散。
或者可以这样理解,TelephonyRegistry作为一个中介,转发和扩散有关Radio的状态。如下图所示: