拨号流程分析(第二篇)

本文详细分析了Android 8.0系统中拨号流程,从Dialer应用发起拨号请求,经过ITelecomService服务,再到CallsManager处理拨号,涉及到跨进程服务调用和广播。关键步骤包括:Dialer应用调用ITelecomService的placeCall,创建和更新Call对象,绑定InCallService服务等。整个流程中,startOutgoingCall用于拨号前的准备,placeOutgoingCall则负责将拨号请求传递给Modem处理。
摘要由CSDN通过智能技术生成

本文基于Android 8.0

ITelecomService接收拨号请求服务

上一节我们分析到TelecomManager的placeCall()实际是获取了ITelecomService服务的实例,调用了其placeCall()方法。ITelecomService服务的真正实现在TelecomServiceImpl.java,代码路径为:
/packages/services/Telecomm/src/com/android/server/telecom/TelecomServiceImpl.java
packages/services/Telecomm 是我们跟踪拨号流程涉及的第二个代码库,查看对应的Android.mk文件,此代码
库将编译出Telecom.apk应用程序,以后统一称其为Telecom 应用。
我们看一下AndroidManifest.xml文件:

<service android:name=".components.TelecomService"
     android:singleUser="true"
     android:process="system">
     <intent-filter>
          <action android:name="android.telecom.ITelecomService" />
     </intent-filter>
</service>

此服务运行在system_server系统进程空间,唯一指定的action为:android.telecom.ITelecomService

Context.TELECOM_ SERVICE 系统服务名“ telecom ”与服务定义的Action:android.telecom. ITelecomService 目前还没有对应起来,后面在Telecom 应用的解析中将重点分析。
到此, Dialer应用的com.android.dialer进程提供用户拨号界面并晌应用户的拨号请求,把拨号请求包装成action 为Intent.ACTION_CALL 的intent 对象。通过调用ITelecomService 服务提供的placeCall 接口, 将拨号请求intent 对象发送给了Telecom 应用(system_serve进程),完成了第一次跨进程的服务调用,传递的是包括拨号请求相关信息的intent 对象

继续关注TelecomServicelmpl.java 文件中的placeCall 方法中的逻辑,将响应Dialer应用发起的跨进程服务接口调用,其中的关键代码如下:

try {
   
    final Intent intent = new Intent(Intent.ACTION_CALL, handle);
    if (extras != null) {
   
        extras.setDefusable(true);
        intent.putExtras(extras);
    }
    mUserCallIntentProcessorFactory.create(mContext, userHandle)
            .processIntent(
                    intent, callingPackage, isSelfManaged ||
                            (hasCallAppOp && hasCallPermission));
} finally {
   
    Binder.restoreCallingIdentity(token);
}

首先通过mUserCallIntentProcessorFactory.create()创建UserCallIntentProcessor对象,并执行其processIntent方法,然后通过判断intent的action来调用processOutgoingCallIntent方法,继续调用sendBroadcastToReceiver 方法,此方法详情如下:

private boolean sendBroadcastToReceiver(Intent intent) {
   
    intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, false);
    intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
    intent.setClass(mContext, PrimaryCallReceiver.class);
    Log.d(this, "Sending broadcast as user to CallReceiver");
    mContext.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
    return true;
}

发出一个定向广播,由Telecom应用中的PrimaryCallReceiver对象接收

使用本地广播的目的主要是为了将同步处理转换成异步处理

跟进PrimaryCallReceiver 对象的onReceive 中的处理逻辑,将调用CalllntentProcessor类中的processOutgoingCalllntent 方法,其主要逻辑如下:

// 确保广播返回之前发送消息给CallsManager, 完成IncallUI通话界面的加载和显示
Call call = callsManager
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值