1.Android手机可能会有两张SIM卡,每张SIM卡是一个PhoneAccount,PhoneAccount对象是在哪里新建的?
TelecomAccountRegistry.java (packages\services\telephony\src\com\android\services\telephony)的registerPstnPhoneAccount方法PhoneAccount.builder(phoneAccountHandle, label).build()
2.Sim卡信息(包括颜色)是哪里设置的?
SubscriptionController的addSubInfoRecord方法,里面包括sim卡的信息,并且将这些信息保存到了TelephonyProvider数据库中。
3.桌面上电话图标打开的是哪个界面?
Activity是DialtactsActivity,星号对应的Fragment是SpeedDialFragment。加载数据的CursorLoader是ContactTileLoaderFactory.createStrequentPhoneOnlyLoader。Adapter是PhoneFavoritesTileAdapter,ListView的item是PhoneFavoriteSquareTileView。
4.INNER JOIN和Left Outer Join
A INNER Join B 完全连接,列出A和B中都存在的记录
A Left Outer Join B,列出A和B都存在的记录,也列出A中去除交集的部分
5.拨号数字UI
dialpad_fragment.xml ---> dialpad_view.xml--->dialpad_view_unthemed.xml--->dialpad.xml(这个里面有数字按键)
通话界面点击键盘出来的是InCallUI下面的DialpadFragment,而拨打电话的时候是diapad下面的DialpadFragment。
6.TelecomManager,TelephonyManager相关
TelecomManager和TelephonyManager都有getTelecomService方法,这个Service的实现在TelecomServiceImpl类中。
TelephonyManager有getITelephony方法,这个Service的实现是在PhoneInterfaceManager类中。
7.来电铃声
代码在DialerRingtoneManager.java
8.CallList
所有对Call的操作都在updateCallInMap方法中:如果状态是disconnected并且此call已经存在,更新mCallById、mCallMap、mCallByTelecomCall;如果状态不是IDLE和INVALID,更新mCallById、mCallMap、mCallByTelecomCall;剩下的状态将Call对象从mCallById、mCallMap、mCallByTelecomCall中移除。
调用updateCallInMap的方法有onCallRemoved、onDisconnect、onIncoming、clearOnDisconnect、onUpdateCall、finishDisconnectedCall。
调用过程为(InCallServiceImpl的server端为InCallController,而CallsManager会回调给InCallController,所以CallsManager对Call是真正的管理者,Dialer中的CallList数据来自CallsManager):
CallsManager将InCallController加入到mListeners中,并进行callback回调---》InCallController的updateCall---》InCallServiceBinder的updateCall---》InCallService的handleMessage如MSG_UPDATE_CALL---》Call(base/telecom)的fireCallDestroyed---》Phone(base/telecom)的fireCallRemoved---》InCallService(base/telecom)的内部类mPhoneListener的onCallRemoved被调用---》InCallServiceImpl的onCallRemoved---》InCallPresenter的onCallRemoved---》CallList的onCallRemoved
9.CallAudio相关
CallAudioModeStateMachine对象由CallsManager创建,在构造函数中默认为mUnfocusedState,然后send一个INITIALIZE的message,CallsManager的状态发生变化后会调用CallAudioManager的onCallEnteringActiveDialingOrConnecting方法,然后调用CallAudioModeStateMachine的sendMessageWithArgs(NEW_ACTIVE_OR_DIALING_CALL)------》CallAudioModeStateMachine的UnfocusedState收到NEW_ACTIVE_OR_DIALING_CALL后,进入mSimCallFocusState,之后会调用mCallAudioManager的setCallAudioRouteFocusState(HAS_FOCUS)------>CallAudioRouteStateMachine的sendMessageWithSessionInfo(SWITCH_FOCUS,HAS_FOCUS)------>CallAudioRouteStateMachine的ActiveEarpieceRoute的enter方法。
CallAudioRouteStateMachine对象由CallsManager创建然后初始化initialize,initialize方法中的getInitialAudioState初始化Audio,默认是ROUTE_EARPIECE,所以会调用到QuiescentEarpieceRoute的enter方法,
接听电话过程中插入耳机:WiredHeadsetManager收到headsetplugginchanged事件后,callback给事件接收者CallAudioRoutePeripheralAdapter,然后send消息CONNECT_WIRED_HEADSET给CallAudioRouteStateMachine,这样从ActiveEarpieceRoute切换到ActiveHeadsetRoute。
10.CallsManager是在TelecomSystem中新建的。
11.Telephony中有很多Call类,他们之间的关系是什么?
12.有时候会出现开机第一次默认勾选的APN不是第一个,如Vodafone的APN。
DcTracker在createAllApnList方法里面是按照id来排序去查找carriers,然后会将apn列一样的合并起来,印度Vodafone的APN中MMS和VodafoneLive! apn列一样,会被合并成一个,由于VodafoneLive!可以处理default类型,这样VodafoneLive!会被当作默认的apn,在Settings里面查找carriers表是按照name排序的所以Vodafone Connect是在第一个。就会出现第一次开机默认勾选第二个VodafoneLive!,恢复默认会变成第一个Vodafone Connet。
13.主叫流程
MOCall.png14.Phone相关的AIDL
aidl.png15.来一通电话,从头分析
看PstnIncomingCallNotifier的mHandler如何处理
16.通话中联系人名称从哪里来?
CallContact.png17.DcNetworkAgent是由谁来创建的?
PhoneSwitcher会调用到DcTracker的requestNetwork并传过来NetworkRequest对象。
requesetNetwork方法:a.通过NetworkRequest的networkCapabilities来得到对应的apnId,如APN_DEFAULT_ID,APN_IMS_ID;b.通过apnId得到ApnContext;c.调用ApnContext的incRefCount,这个方法会调用DcTracker的setEnabled方法
DcTracker的setEnabled方法:调用onEnableApn方法,onEnableApn方法会调用applyNewState方法,然后调用trySetupData方法,然后一直调用到trySetupData方法。
trySetupData方法:a.createDataConnection;b.DcAsyncChannel的bringUp方法
createDataConnection方法:a.makeDataConnection,新建DataConnection对象,并进入DcInactivieState;b.new DcAsyncChannel;c.DcSyncChannel的fullyConnectSync,设置了下srcMessager和dstMessager
DcAsyncChannel的bringUp方法:发消息EVENT_CONNECT给dstMessager,这个消息是DataConnection的当前状态DcInactiveState收到,先initConnection,再调用onConnect(调用RIL的setupDataCall,当此方法结束后会发送EVENT_SETUP_DATA_CONNECTION_DONE消息),进入DcActivatingState状态,当DcActivatingState收到EVENT_SETUP_DATA_CONNECTION_DONE消息时,进入DcActiveState状态,这个状态会新建DcNetworkAgent。
网友评论