Android设备上的呼叫流程

呼叫介绍

呼叫分为主动呼叫和被动呼叫,主动呼叫也叫"去电",MO Call,表示用户通过UI上的拨号键盘拨出的电话。
被动呼叫叫做"来电",MT Call,表示其他打电话端打过来的电话,可以选择接听或者拒接或者missed。

一 去电流程(后面涉及到的代码展示都是基于Android Q)

有两种去电的方式(基于Android Q):

  1. 从UI(Dialer)使用TelecomManager中的placeCall将打电话的请求发给TelecomServer这边。
  2. 从其他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, 这个方法主要有两个作用:

  1. 将dial请求下发给RIL, 由RILJ发给RILC
  2. 创建创建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变化:

  1. 获取到Telephony Service,拿到TelephonyManager引用
  2. 调用TelephonyManager的listen方法来监听希望监听的通话状态变化
  3. 重写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中这些服务的变化,然后做相应的改变。

流程图

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值