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 phones
private 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>() {
@Override
public 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);
}
@Override
public 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);
}
@Override
public 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);
}
@Override
public void notifySignalStrength(Phone sender) {
int phoneId = sender.getPhoneId();
int subId = sender.getSubId();
if (DBG) {
// too chatty to log constantly
Rlog.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{
@UnsupportedAppUsage
protected 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状态的上报,再回调到各个添加了监听的应用中。