本文基于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