TelephonyRegistry在AOSP中的路径为:frameworks\base\services\core\java\com\android\server,它是作为安卓电话子系统中所有状态监听回调的集中管理的地方,应用对电话相关状态的监听主要注册在这里。它继承自ITelephonyRegistry.Stub,作为系统服务,在SystemServer.java中创建,并加入ServiceManager中
public static void main(String[] args){new SystemServer().run();}//在run()方法中,调用startOtherServices()//startOtherServices()中private void startOtherServices(){...telephonyRegistry = new TelephonyRegistry(context, new TelephonyRegistry.ConfigurationProvider());ServiceManager.addService("telephony.registry", telephonyRegistry);...}
下面进入TelephonyRegistry的源码中查看,里面一大堆记录各种状态的数组,数组的长度取决于激活的卡的数量,
private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();private final ArrayList<Record> mRecords = new ArrayList<Record>();private int mNumPhones;private int[] mCallState;private String[] mCallIncomingNumber;private ServiceState[] mServiceState;private int[] mVoiceActivationState;private int[] mDataActivationState;private boolean[] mUserMobileDataState;private TelephonyDisplayInfo[] mTelephonyDisplayInfos;private SignalStrength[] mSignalStrength;private boolean[] mMessageWaiting;private boolean[] mCallForwarding;private int[] mDataActivity;// Connection state of default APN type data (i.e. internet) of phonesprivate int[] mDataConnectionState;private CellIdentity[] mCellIdentity;private int[] mDataConnectionNetworkType;private ArrayList<List<CellInfo>> mCellInfo = null;private Map<Integer, List<EmergencyNumber>> mEmergencyNumberList;private EmergencyNumber[] mOutgoingSmsEmergencyNumber;private EmergencyNumber[] mOutgoingCallEmergencyNumber;private CallQuality[] mCallQuality;private CallAttributes[] mCallAttributes;
其中最关键的就是mRecords,它是对客户端Binder注册进来的回调的实例的封装:
private Record add(IBinder binder, int callingUid, int callingPid, boolean doesLimitApply) {Record r;synchronized (mRecords) {final int N = mRecords.size();// While iterating through the records, keep track of how many we have from this pid.int numRecordsForPid = 0;for (int i = 0; i < N; i++) {r = mRecords.get(i);if (binder == r.binder) {// Already existed.return r;}if (r.callerPid == callingPid) {numRecordsForPid++;}}// If we've exceeded the limit for registrations, log an error and quit.int registrationLimit = mConfigurationProvider.getRegistrationLimit();if (doesLimitApply&& registrationLimit >= 1&& numRecordsForPid >= registrationLimit) {String errorMsg = "Pid " + callingPid + " has exceeded the number of permissible"+ " registered listeners. Ignoring request to add.";loge(errorMsg);if (mConfigurationProvider.isRegistrationLimitEnabledInPlatformCompat(callingUid)) {throw new IllegalStateException(errorMsg);}} else if (doesLimitApply && numRecordsForPid>= PhoneStateListener.DEFAULT_PER_PID_REGISTRATION_LIMIT / 2) {// Log the warning independently of the dynamically set limit -- apps shouldn't be// doing this regardless of whether we're throwing them an exception for it.Rlog.w(TAG, "Pid " + callingPid + " has exceeded half the number of permissible"+ " registered listeners. Now at " + numRecordsForPid);}r = new Record();r.binder = binder;r.deathRecipient = new TelephonyRegistryDeathRecipient(binder);try {binder.linkToDeath(r.deathRecipient, 0);} catch (RemoteException e) {if (VDBG) log("LinkToDeath remote exception sending to r=" + r + " e=" + e);// Binder already died. Return null.return null;}mRecords.add(r);if (DBG) log("add new record");}return r;}
在addOnSubscriptionsChangedListener中会被调用,而在各个notifyXXX方法中,会遍历该mRecords,调用对应的回调方法。
public void notifyCallState(int phoneId, int subId, int state, String incomingNumber) {if (!checkNotifyPermission("notifyCallState()")) {return;}if (VDBG) {log("notifyCallState: subId=" + subId+ " state=" + state + " incomingNumber=" + incomingNumber);}synchronized (mRecords) {if (validatePhoneId(phoneId)) {mCallState[phoneId] = state;mCallIncomingNumber[phoneId] = incomingNumber;for (Record r : mRecords) {if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&(r.subId == subId) &&(r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {try {String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId);r.callback.onCallStateChanged(state, incomingNumberOrEmpty);} catch (RemoteException ex) {mRemoveList.add(r.binder);}}}}handleRemoveListLocked();}broadcastCallStateChanged(state, incomingNumber, phoneId, subId);}
通过代码搜索,发现TelephonyRegistry只在SystemServer中使用了,所以其他任何形式的访问必须通过其对应的客户端代理来进行访问。ITelephonyRegistry的客户端在TelephonyRegistryManager中:
public class TelephonyRegistryManager{private static ITelephonyRegistry sRegistry;public TelephonyRegistryManager(@NonNull Context context) {mContext = context;if (sRegistry == null) {sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));}}}
TelephonyRegistryManager中的许多方法都是对sRegistry调用的封装,例如提供给应用添加监听的方法:
public void listenForSubscriber(int subId, @NonNull String pkg, @NonNull String featureId,@NonNull PhoneStateListener listener, int events, boolean notifyNow) {try {// subId from PhoneStateListener is deprecated Q on forward, use the subId from// TelephonyManager instance. Keep using subId from PhoneStateListener for pre-Q.if (Compatibility.isChangeEnabled(LISTEN_CODE_CHANGE)) {// Since mSubId in PhoneStateListener is deprecated from Q on forward, this is// the only place to set mSubId and its for "informational" only.listener.mSubId = (events == PhoneStateListener.LISTEN_NONE)? SubscriptionManager.INVALID_SUBSCRIPTION_ID : subId;} else if (listener.mSubId != null) {subId = listener.mSubId;}sRegistry.listenForSubscriber(subId, pkg, featureId, listener.callback, events, notifyNow);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}
该方法在TelephonyManager中的listen()方法中被调用。
public class TelephonyManager{public void listen(PhoneStateListener listener, int events) {if (mContext == null) return;boolean notifyNow = (getITelephony() != null);TelephonyRegistryManager telephonyRegistry =(TelephonyRegistryManager)mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);if (telephonyRegistry != null) {telephonyRegistry.listenForSubscriber(mSubId, getOpPackageName(), getAttributionTag(),listener, events, notifyNow);} else {Rlog.w(TAG, "telephony registry not ready.");}}}
为啥可以调用mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE)来获取TelephonyRegistryManger的实例呢?原来在SystemServiceRegistry中,TelephonyRegistryManager类被注册为SystemService了:
static{registerService(Context.TELEPHONY_REGISTRY_SERVICE, TelephonyRegistryManager.class,new CachedServiceFetcher<TelephonyRegistryManager>() {@Overridepublic TelephonyRegistryManager createService(ContextImpl ctx) {return new TelephonyRegistryManager(ctx);}});}
继续搜索TelephonyRegistryManager的使用,发现在DefaultPhoneNotifier中,TelephonyRegistryManager作为私有成员变量使用,而且DefaultPhoneNotifier中的各种notifyXXX方法都是对TelephonyRegistryManager的方法的封装:
public class DefaultPhoneNotifier implements PhoneNotifier {private TelephonyRegistryManager mTelephonyRegistryMgr;//在构造方法中通过context.getSystemService()实例化public DefaultPhoneNotifier(Context context) {mTelephonyRegistryMgr = (TelephonyRegistryManager) context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);}@Overridepublic void notifyPhoneState(Phone sender) {Call ringingCall = sender.getRingingCall();int subId = sender.getSubId();int phoneId = sender.getPhoneId();String incomingNumber = "";if (ringingCall != null && ringingCall.getEarliestConnection() != null) {incomingNumber = ringingCall.getEarliestConnection().getAddress();}mTelephonyRegistryMgr.notifyCallStateChanged(subId, phoneId,PhoneConstantConversions.convertCallState(sender.getState()), incomingNumber);}@Overridepublic void notifyServiceState(Phone sender) {ServiceState ss = sender.getServiceState();int phoneId = sender.getPhoneId();int subId = sender.getSubId();Rlog.d(LOG_TAG, "notifyServiceState: mRegistryMgr=" + mTelephonyRegistryMgr + " ss="+ ss + " sender=" + sender + " phondId=" + phoneId + " subId=" + subId);if (ss == null) {ss = new ServiceState();ss.setStateOutOfService();}mTelephonyRegistryMgr.notifyServiceStateChanged(subId, phoneId, ss);}@Overridepublic void notifySignalStrength(Phone sender) {int phoneId = sender.getPhoneId();int subId = sender.getSubId();if (DBG) {// too chatty to log constantlyRlog.d(LOG_TAG, "notifySignalStrength: mRegistryMgr=" + mTelephonyRegistryMgr+ " ss=" + sender.getSignalStrength() + " sender=" + sender);}mTelephonyRegistryMgr.notifySignalStrengthChanged(subId, phoneId,sender.getSignalStrength());}}
继续追踪DefaultPhoneNotifier的使用,发现在PhoneFactory中,作为静态成员变量:
class PhoneFactory{static private PhoneNorifier sPhoneNotifier;public static void makeDefaultPhone(Context context) {···sPhoneNotifier = new DefaultPhoneNotifier(context)···}private static Phone createPhone(Context context, int phoneId) {int phoneType = TelephonyManager.getPhoneType(RILConstants.PREFERRED_NETWORK_MODE);Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " phoneId = " + phoneId);// We always use PHONE_TYPE_CDMA_LTE now.if (phoneType == PHONE_TYPE_CDMA) phoneType = PHONE_TYPE_CDMA_LTE;TelephonyComponentFactory injectedComponentFactory =TelephonyComponentFactory.getInstance().inject(GsmCdmaPhone.class.getName());return injectedComponentFactory.makePhone(context,sCommandsInterfaces[phoneId], sPhoneNotifier, phoneId, phoneType,TelephonyComponentFactory.getInstance());}public static SipPhone makeSipPhone(String sipUri) {return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier);}}
发现DefaultPhoneNotifier主要用于构造Phone对象时,作为参数传进去。那就进Phone的源码里看看:
class Phone{@UnsupportedAppUsageprotected PhoneNotifier mNotifier;}
原来Phone类里,有个PhoneNotifier类型的protected成员变量。,我们再看看 mNotifier在Phone类中如何使用的:
class Phone{public void notifyPhoneStateChanged() {mNotifier.notifyPhoneState(this);}public void notifyDisconnect(Connection cn) {mDisconnectRegistrants.notifyResult(cn);mNotifier.notifyDisconnectCause(this, cn.getDisconnectCause(),cn.getPreciseDisconnectCause());}public void notifyLocationChanged(CellIdentity cellIdentity) {mNotifier.notifyCellLocation(this, cellIdentity);}...}
就此一切就都明朗了,应用通过实现PhoneStateListener接口,调用TelephonyManager的listen()方法,将回调监听添加到TelephonyRegistry系统服务中,然后,各个Phone实例通过调用内部mNotifier的各种notifyXXX方法,来实现Telephony状态的上报,再回调到各个添加了监听的应用中。
