最近遇到voice phone在切phone时通话自动挂断的问题。
在android8.0上还没有这个问题。
android8.1在GsmCdmaphone.reset()函数添加了一行如下代码,导致framwork层清空通话信息。
gsmCdmaConnection.ondisconnect().
通过查谷歌的代码提交记录,谷歌在android8.1上的一次提交添加了这行代码。是在执行测试代码时,对reset()函数做的优化。这个优化是否合理这里就不讨论了。这个修改只是针对framwork层清空了所有通话connection,导致所有通话自动挂断。如果此通话在底层切phone的时候,仍然存在,那么久导致底层和上层的通话状态不一致。
这个不一致在某些产品拨紧急号码拨号时触发。为何不是所有产品?请注意只有通话是走GsmCdmaPhone拨出时才会建立gsmCdmaConnection。而目前很多情况下紧急号码都是走IMSphone呼出,此时底层虽然紧急号码目前还是走CS呼出不是走IMS,但是上层的connection是IMSphone维护。IMSphone不关注GSM CDMAphone切换。(你切你的,能耐我何。。。。)所以紧急号码也就不会在框架层被自动清除。
那么切phone自动挂断电话的log如下:
04-02 16:35:48.721 2584 2584 D QtiGsmCdmaPhone: handleMessage: Event: 39
04-02 16:35:48.721 2584 2584 D GsmCdmaPhone: [GsmCdmaPhone][0]EVENT_VOICE_RADIO_TECH_CHANGED: newVoiceTech=3
04-02 16:35:48.721 2584 2584 D GsmCdmaPhone: [GsmCdmaPhone][0]phoneObjectUpdater: newVoiceRadioTech=3
04-02 16:35:48.721 2584 2584 D GsmCdmaPhone: [GsmCdmaPhone][0]Switching Voice Phone : CDMA >>> GSM
04-02 16:35:48.721 2584 2584 D GsmCdmaPhone: [GsmCdmaPhone][0]Precise phone type 1
04-02 16:35:48.721 2584 2584 D RILJ : setPhoneType=1 old value=2 [SUB0]
04-02 16:35:48.722 2584 2584 D TelephonyManager: setTelephonyProperty: success phoneId=0 property=gsm.current.phone-type value: 1 propVal=1,1
04-02 16:35:48.723 2584 2584 D IccCardProxy: [0]Setting radio tech UMTS
04-02 16:35:48.734 2584 2584 D GsmCdmaCallTracker: reset
04-02 16:35:48.735 2584 2584 D GsmCdmaConnection: onDisconnect: cause=36
函数调用序列如下:
GsmCdmaPhone 初始化时GsmCdmaPhone.initOnce()->CommandInterface.registerForVoiceRadioTechchanged(EVENT_RIL_RADIO_TECH_CHANGED)-》mVoiceRadioTechChangeRegistrants.add()。即当RadioIndication.java的voiceRadipTechChanged函数被调用时,
RadioIndication.voiceRadipTechChanged()->RIL.mVoiceRadioTechChangeRegistrants.notifyRegistrants()-GsmCdmaPhone->handleMessage(EVENT_RIL_RADIO_TECH_CHANGED)->GsmCdmaPhone.phoneObjectUpdater(newVoiceTech)->GsmCdmaPhone.switchVoiceRadioTech()->GsmCdmaPhone.switchPhoneType()->GsmCdmaCallTracker.updatePhoneType()->GsmCdmaCallTracker.reset()->GsmCdmaConnection.onDisconnect(Error_UNSPECIFIED)->GsmCdmaPhone.notifyDisconnect() and GsmCdmaCall.connectionDisconnected()
GsmCdmaPhone.notifyDisconnect() 通知谁呢?
CallManager.registerForPhoneStates()->Phone.registerForDisconnect(Event_DISCONNECT)
则会触发CallManager.handleMessage(EVENT_DISCONNECT)->mDisconnectRegistrants.notifyRegistarants()
好了又来一层CallManager 通知谁呢,CallNotifier.registerForNofifications()->CallManager.registerForDisconnect(PHONE_DISCONNECT)
这部分打印的流程:
触发流程2选1
情况1
/ 2580 2580 D Telephony: GsmConnection: Disconnected with cause DisconnectCause [ Code: (ERROR) Label: () Description: () Reason: (ERROR_UNSPECIFIED) Tone: (27) ]
情况2
/ 2580 2580 D Telephony: FailureSignalingConnection: Disconnected with cause DisconnectCause [ Code: (ERROR) Label: () Description: () Reason: (Phone is null, ERROR_UNSPECIFIED) Tone: (27) ]: (SBC.oSC)->CS.crCo->H.CS.crCo->H.CS.crCo.pICR@E-AZs_0_0_0
1916 2122 D Telecom : ConnectionServiceWrapper: ConnectionService -> Telecom[com.android.phone/com.android.services.telephony.TelephonyConnectionService]: setDisconnected
04-02 16:35:24.676 1937 2644 I Telecom : Event: RecordEntry TC@1: SET_DISCONNECTED, disconnected set explicitly> DisconnectCause [ Code: (ERROR) Label: () Description: () Reason: (ERROR_UNSPECIFIED) Tone: (27) ]: CSW.sDc@AG8
04-02 16:35:24.687 1937 2644 I Telecom : CallAudioManager: is ConfURI call disconnected = false call = [TC@1, DISCONNECTED, com.android.phone/com.android.services.telephony.TelephonyConnectionService, tel:**, A, childs(0), has_parent(false), [Capabilities: CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO], [Properties:]]: CSW.sDc@AG8
04-02 16:35:24.693 1937 2644 I Telecom : InCallController: Sending updateCall [TC@1, DISCONNECTED, com.android.phone/com.android.services.telephony.TelephonyConnectionService, tel:**, A, childs(0), has_parent(false), [Capabilities: CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO], [Properties:]]: CSW.sDc@AG8
04-02 16:35:24.784 1937 2644 I Telecom : Event: RecordEntry TC@1: DESTROYED, null: CSW.rC@AHA
04-02 16:35:24.790 1937 2644 I Telecom : InCallController: onCallRemoved: [TC@1, DISCONNECTED, null, tel:**, A, childs(0), has_parent(false), [Capabilities: CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO], [Properties:]]: CSW.rC@AHA
相关函数调用如下:
在ConnectionService.addconnection()时conncetion.addConnectionListener(mConncetionListener).则Connection.setDisconnected->listener.onDisconnceted即 ConncetionService.mConncetionListener.onDisconnected()->ConncetionServiceAdapter.setDisconnected()->通过binder机制到服务端ConnectionServiceWrapper.IconncetionServiceAdapter.setDisconnected()->CallsManager.markCallAsDisconnected()->CallsManager.setCallState()->Call.setState and CallsManagerListener.onCallStateChanged()