呼叫介绍
呼叫分为主动呼叫和被动呼叫,主动呼叫也叫"去电",MO Call,表示用户通过UI上的拨号键盘拨出的电话。
被动呼叫叫做"来电",MT Call,表示其他打电话端打过来的电话,可以选择接听或者拒接或者missed。
一 去电流程(后面涉及到的代码展示都是基于Android Q)
有两种去电的方式(基于Android Q):
- 从UI(Dialer)使用TelecomManager中的placeCall将打电话的请求发给TelecomServer这边。
- 从其他App(比如VR,Nav提供的phone icon)直接调用Telecom提供的UserCallActivity来打电话。
这两种方式终会调用UserCallIntentProcessor的processIntent->processOutgoingCallIntent->sendIntentToDestination方法
该方法中会根据输入的参数isLocalInvocation来判断接下来是使用CallIntentProcessor.processIntent(第一种情况)还是TelecomManager的handleCallIntent(第二种情况)来处理后续拨打电话的流程。之后CallIntentProcessor.processOutgoingCallIntent来统一处理上面的两种情况,这里开始兵分两路:
1. CallsManager.startOutgoingCall--创建Call对象,然后起incall UI
2. sendNewOutgoingCallIntent,去创建connection
创建Connection的请求由ConnectionService的createConnection(同时对Connection添加监听,这样当底层上报的Call状态变化的时候,Connection就会监听到这边变化,然后将这个call状态变化上报给Telecom,这是后话)来发起,这里会根据当前通话的类型来区分创建Conneciton:
1. onCreateUnknownConnection -- 对应未知呼叫的Connection
2. onCreateIncomingConnection -- 对应来电的Connection
3. onCreateOutgoingConnection -- 对应去电的Connection
上述三个方法具体的实现由ConnectionService的子类来完成。
对于SIM-based 呼叫来说,ConnectionService的实现子类是TelephonyConnectionService, TelephonyConnectionService收到onCreateOutgoingCallConnetions后,在该Connectionservice中通过phone对象调用其dial方法(返回值就是一个connection),然后发给GsmCdmaCallTracker的dialGsm, 这个方法主要有两个作用:
- 将dial请求下发给RIL, 由RILJ发给RILC
- 创建创建Connection:new GsmCdmaConnection, 并将该connection返回,赋值给TelephonyConnectionService.placeOutgoingConnection中的变量:originalConnection,然后将该变量设置给TelephonyConnection。
也就是说Telephony拿到的Connetion,其实是从TelephoyFramework中创建的GsmCdmaConnection。
之后调用CommandsInfterface.dial(RIL实现了该接口)的dial来向Modem发起拨打电话的请求。
KeyLogs
05-18 14:23:31.977 D/RILJ ( 2401): [0462]> DIAL [SUB0]
05-18 14:23:31.996 D/RILJ ( 2401): [0462]< DIAL [SUB0]
RILJ发送的请求会在RILC中接收,之后RILC上报DIAL给RILJ,然后将Call状态变化的消息主动上报给RILJ:UNSOL_RESPONSE_CALL_STATE_CHANGED,在RadioIndication中接收这种主动上报的消息,其作用就是通知注册的观察者CallTracker有call状态变化,以便CallTracker根据这个call消息进行下一步Action。
GsmCdmaCallTracker中注册该变化,当监听到该Call状态变化的时候,会继续下发getCurrentCalls请求给RIL来查询当前Call的详细的信息,RILC返回回来的Call信息包括:
DIALING — Call state
toa=129 — 表示当前是国内呼叫
norm — 表示是个Gsm 呼叫
mo – 表示是去电 等等
KeyLogs
05-18 14:23:32.002 D/RILJ ( 2401): [0465]> GET_CURRENT_CALLS [SUB0]
05-18 14:23:32.004 D/RILJ ( 2401): [0465]< GET_CURRENT_CALLS {
[id=1,DIALING,toa=129,norm,mo,0,voc,noevp,,cli=1,,3,audioQuality=0] } [SUB0]
在下发getCurrentCalls的时候携带了一条消息:EVENT_POLL_CALLS_RESULT,当RILC上报回来该下发请求后,同时会将之前的message发送给对应的handler去处理,该消息的处理也在CallTracker.handlePollCalls->这里通过调用Phone.notifyPreciseCallStateChanged()将Call状态notify出去,在TelephonyConnection的setOriginalConnection中注册了观察者,去更新的时候会调用TelecomFramework下的Connection的对应的Set方法(setDialing(),setRinging,setActive .etc)通知之前在ConnectionService.createConnection添加的listener去onStateChanged, 之后就将Call状态变化通知到TelecomServer(ConnectionServiceWrapper)中, Wrapper通知到CallsManager,然后CallsManager通知在其中的观察者,比如IncallController,让其将call变化信息通过InCallService通知给Dialer APP去更新InCallUI。
当然CallsManager中添加的listener不止IncallController, 还有其他:
1. PhoneStateBroadcaster --- Send a {@link TelephonyManager#ACTION_PHONE_STATE_CHANGED} broadcast when the call state changes.
2. CallLogManager --- Helper class that provides functionality to write information about calls and their associated caller details to the call log. All logging activity will be performed asynchronously in a background thread to avoid locking on the main thread.
3. MissedCallNotifier --- Creates a notification for calls that the user missed (neither answered nor rejected)
4. HeadsetMediaButton --- Static class to handle listening to the headset media buttons.
5. StatusBarNotifier --- Manages the special status bar notifications used by the phone app
其中PhoneStateBroadcaster最终会将call state change变化发给TelephonyRegistry,由其发给其他component,对于那些希望监听Call状态变化来处理对应逻辑的component来说,只要通过下面的方式就可以监听到Call state变化:
- 获取到Telephony Service,拿到TelephonyManager引用
- 调用TelephonyManager的listen方法来监听希望监听的通话状态变化
- 重写listen方法的第一个参数类(PhoneStateListener或者其子类)中的onCallStateChanged方法
eg:
1. private TelephonyManager mTelephonyManager;
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
2. mTelephonyManager.listen(PhoneStateListener子类, PhoneStateListener.LISTEN_CALL_STATE);
3.
class XXX extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
........
}
}
需要注意的是:PhoneStateBroadcaster不仅仅是Telephony提供给其他Component监听call状态变化的一个接口,看其注释:
/**
* A listener class for monitoring changes in specific telephony states
* on the device, including service state, signal strength, message
* waiting indicator (voicemail), and others.
* <p>
* Override the methods for the state that you wish to receive updates for, and
* pass your PhoneStateListener object, along with bitwise-or of the LISTEN_
* flags to {@link TelephonyManager#listen TelephonyManager.listen()}. Methods are
* called when the state changes, as well as once on initial registration.
* <p>
* Note that access to some telephony information is
* permission-protected. Your application won't receive updates for protected
* information unless it has the appropriate permissions declared in
* its manifest file. Where permissions apply, they are noted in the
* appropriate LISTEN_ flags.
*/
它监听了Telephony支持的服务中的一切服务的变化,使得其他有需要的component通过上述的方式监听到Telephony中这些服务的变化,然后做相应的改变。