TelephonyFramework跨进程逻辑(来电,去电绑定流程)_android

TelephonyFramework跨进程逻辑

通话相关代码名称统一约定及运行进程汇总

路径

统称

进程

packages/app/Dialer

Dialer

com.android.dialer

packages/service/telecomm

telecom

system_service

packages/service/telephony

TeleService

com.android.phone

framework/base/telecomm

framework

无进程只是提供调用framwork

framework/opt/Telephony

telephony

system_service或com.android.phone

Telephony Framework 四个跨进程类逻辑

  1. IInCallSerivce.aidl
  2. IInCallAdapter.aidl
  3. IConnectionSerivce.aidl
  4. IConnectionServiceAdapter.aidl

1 . IInCallSerivce实现的位置在framework中的InCallSerive中,他的作用是提供telecom去访问framework的方法,也就是更新数据.。

2 . IInCallAdapter实现的位置在Telecom中InCallAdapter中实现.他的作用是提供framwork来访问telecom,而framwork吧InCallAdapter设置进入就Call对象,只需要拨号时调用Call内部的方法就可以通过framwork访问telecom,Call内部携带者InCallAdapter对象
第一步第二步的作用就是互相绑定。

3 . IConnectionSerivce实现位置在framework中的ConnectionSerivce中,他的作用是访问telecom访问framewok,在访问TeleService,数据下发。

4 . IConnectionSerivceAdapter实现的位置在telecom中的ConnectionSerivceWrapper中实现,他的作用是传递给framewok进行数据上报。

第三步第四步的作用也是互相绑定

4个类的绑定顺序

我们来看下绑定顺序,绑定是按来电,去电先后顺序绑定的

先说一下去电绑定,直接看代码

第一次绑定InCallSerivce 的入口是在CallManager.java中的startOutgoingCall()方法,进入内部会调用一个addCall()方法中,在addCall方法内部就做一个处理他循环一些监听,比如InCallContrller等等..

这一快只是入口

去电绑定

流程图:

TelephonyFramework跨进程逻辑(来电,去电绑定流程)_跨进程_02

开始绑定InCallSerivce 和 InCallAdapter

如果要看代码请进入《 ​​来电入口​​ 》

if (!mContext.bindServiceAsUser(intent, mServiceConnection,   //开启服务  调用InCallServiceImpl
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE |
Context.BIND_ABOVE_CLIENT,
UserHandle.CURRENT)) {

这里启动的是InCallSerivceImpl而内部实现了IInCallSerivce.aidl,通过IBinder返回。我们重点看一下传入的mServiceConnection对象他继承了SerivceConnection,如果传入这个对象就可以回调里面的serviceConnection方法他内部携带了一个binder。

private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.startSession("ICSBC.oSC");
synchronized (mLock) {
try {
Log.d(this, "onServiceConnected: %s %b %b", name, mIsBound, mIsConnected);
mIsBound = true;
if (mIsConnected) {//是否连接
// Only proceed if we are supposed to be connected.只有当我们被认为是有联系的时候才继续。 成功后调用InCallServer
onConnected(service);
}
} finally {
Log.endSession();
}
}
}



private boolean onConnected(InCallServiceInfo info, IBinder service) {
//进入Framework/base/Telecom //获取IInCallSerivce服务并保存
IInCallService inCallService = IInCallService.Stub.asInterface(service);
mInCallServices.put(info, inCallService);

try {
// 让绑定的服务,可以通过 InCallAdapter 跨进程 访问 system 进程 (因为当前就是在系统进程)
// InCallAdapter 是一个 Binder。
// 需要对Android 通过 Binder实现跨进程调用有一定了解
// 还有对Android 的AIDL由一定了解 调用到了Framework/base/telecom InCallServce
inCallService.setInCallAdapter(
new InCallAdapter( //如果启动InCallUi挂断时会回调进入这个Adapter。调用到了Framework/base/telecom InCallServce
mCallsManager,
mCallIdMapper,
mLock,
info.getComponentName().getPackageName()));
} catch (RemoteException e) {
Log.e(this, e, "Failed to set the in-call adapter.");
Trace.endSection();
return false;
}

//成功连接后,将 world 状态发送到服务。
List<Call> calls = orderCallsWithChildrenFirst(mCallsManager.getCalls());

int numCallsSent = 0;
//将之前保存的Call对象通过inCallService发出去
for (Call call : calls) {
try {

boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
addCall(call);
numCallsSent += 1;
//添加调用 注意这里Call对象的转换,将com.android.serivce.telecom.Call转换为可跨进程传递对象,android.telecom.parcelableCall
inCallService.addCall(ParcelableCallUtils.toParcelableCall(
call,
true /* includeVideoProvider */,
mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(),
includeRttCall));
} catch (RemoteException ignored) {
}
}
try {
//通知Call相关状态发送变化
inCallService.onCallAudioStateChanged(mCallsManager.getAudioState());
inCallService.onCanAddCallChanged(mCallsManager.canAddCall());
} catch (RemoteException ignored) {
}
Log.i(this, "%s calls sent to InCallService.", numCallsSent);
Trace.endSection();
return true;
}

我们需要重点看一下setInCallAdapter喝addCall着两个绑定,

setInCallAdapter提供给framwrork去调用最后设置在Call对象中,这里的Adapter是为消息下发处理的
addCall吧Telecomm Call对象转换成序列化对象 ,这个入口也是拨号调启InCallUi的入口

绑定玩IInCallSerivce和IInCallAdapter接下来就是绑定,IConnectionSerivce和IConnectionSerivceAdapter

绑定IConnectionSerivce的入口在CallManager.java中的placeOutgoingCall()方法他会进入Call的startCreateConnection,再通过创建CreateConnectionProcessor对象进入process方法,这个对象会获取一个ConnectionServiceWapper对象,进入createConneciton进行绑定

开始绑定IConnectionService和IConnectionSerivceAdapter

最终绑定入口在ConnectionSerivceWapper类中

看一下代码

public void createConnection(final Call call, final CreateConnectionResponse response) {//创建链接就是一个绑定服务的过程
....
......
.........
//绑定
mBinder.bind(callback, call);
}

这里的mBinder是ConnectionServiceWapper的父类的内部列Bilder2

void bind(BindCallback callback, Call call) {
.....
//在类里面绑定成功后mBinder.bind(callback, call);在父类ServiceBinder类里面mCallbacks.add(callback);吧回调用集合给装载起来,然后进行便利数据
//成功获取到aidl接口后将其赋值mServiceInterface,
mCallbacks.add(callback);
if (mServiceConnection == null) {
Intent serviceIntent = new Intent(mServiceAction).setComponent(mComponentName);
ServiceConnection connection = new ServiceBinderConnection(call);

Log.addEvent(call, LogUtils.Events.BIND_CS, mComponentName);
final int bindingFlags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
final boolean isBound;
if (mUserHandle != null) {// 进行绑定
isBound = mContext.bindServiceAsUser(serviceIntent, connection, bindingFlags, //如果绑定成功调用connection方法 这里绑定是绑定了framework/base/telepony
mUserHandle);//绑定的是TelephonyConnectionService
} else {
isBound = mContext.bindService(serviceIntent, connection, bindingFlags);
}
if (!isBound) {
handleFailedConnection();
return;
}
} else {
......
}
}
}

我们重点看一下mContext.bindSerivceAsUser().这里启动的就是framework中的ConnectionService服务,再继续看携带的数据connection对象,这里的SerivceBinderConnection,继承自SerivceConnection,我们看一下serviceConnection方法,

@Override
public void onServiceConnected(ComponentName componentName, IBinder binder) {
try {
synchronized (mLock) {
mCall = null;
if (mIsBindingAborted) {
clearAbort();
logServiceDisconnected("onServiceConnected");
mContext.unbindService(this);
handleFailedConnection();
return;
}
if (binder != null) {
mServiceDeathRecipient = new ServiceDeathRecipient(componentName);
try {

binder.linkToDeath(mServiceDeathRecipient, 0);
mServiceConnection = this;
setBinder(binder);// 触发bind(BindCallback callback, Call call) 中 callback 的 onSuccess 与framework/Telecom绑定进行通信
handleSuccessfulConnection(); //回调进入子类,内部循环了mCallback进入ConnectionServiceWrapper中的BindCallback
//整个绑定过程,只做2件事,一是给远程服务提供访问自己的接口,二是利用远程接口创建一个通话链接。
// 这2件事都是跨进程进行的。远程服务访问自己的接口是
} catch (RemoteException e) {
Log.w(this, "onServiceConnected: %s died.");
if (mServiceDeathRecipient != null) {
mServiceDeathRecipient.binderDied();
}
}
}
}
} finally {
Log.endSession();
}
}

我们这里重点关注一些setBinder方法内部调用了子类一个方法

protected void setServiceInterface(IBinder binder) {
mServiceInterface = IConnectionService.Stub.asInterface(binder);//保存binder对象
Log.v(this, "Adding Connection Service Adapter.");
addConnectionServiceAdapter(mAdapter);//这个mAdapter 给远程服务提供访问自己的接口
}

private void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
if (isServiceValid("addConnectionServiceAdapter")) {
try {
//在类里面绑定成功后mBinder.bind(callback, call);在父类ServiceBinder类里面mCallbacks.add(callback);吧回调用集合给装载起来,然后进行便利数据
//成功获取到aidl接口后将其赋值mServiceInterface,
logOutgoing("addConnectionServiceAdapter %s", adapter);
mServiceInterface.addConnectionServiceAdapter(adapter, Log.getExternalSession());
} catch (RemoteException e) {
}
}
}

这里的mAdapter就是实现IConnectionSerivceAdapter的对象,传给framework进行绑定。在来看handleSuccessfulConnection()方法,这个方法处理了createConnection传入的CallBack对象。

private void handleSuccessfulConnection() {
for (BindCallback callback : mCallbacks) {
callback.onSuccess();
}
mCallbacks.clear();
}

public void createConnection(final Call call, final CreateConnectionResponse response) {//创建链接就是一个绑定服务的过程
BindCallback callback = new BindCallback() {// 链接创建成功后 onSuccess 会被调用
@Override
public void onSuccess() {
...........
................
.......................
//通过通话相关信息的创建,ConnectionRequest支持系列化和反序列化
ConnectionRequest connectionRequest = new ConnectionRequest.Builder()
.setAccountHandle(call.getTargetPhoneAccount())
.setAddress(call.getHandle())
.setExtras(extras)
.setVideoState(call.getVideoState())
.setTelecomCallId(callId)//关键点

.setShouldShowIncomingCallUi(
!mCallsManager.shouldShowSystemIncomingCallUi(call))
.setRttPipeFromInCall(call.getInCallToCsRttPipeForCs())
.setRttPipeToInCall(call.getCsToInCallRttPipeForCs())
.build();//建造者模式的应用,创建对象

try {

mServiceInterface.createConnection( // 通过远程接口创建链接 利用远程接口创建一个通话链接 属于第二次宽进程访问
call.getConnectionManagerPhoneAccount(),
callId,
connectionRequest,
call.shouldAttachToExistingConnection(),
call.isUnknown(),
Log.getExternalSession());

} catch (RemoteException e) {
mPendingResponses.remove(callId).handleCreateConnectionFailure(
new DisconnectCause(DisconnectCause.ERROR, e.toString()));
}
}
};
//绑定
mBinder.bind(callback, call);
}

这里主要看createConnection他的作用就是创建连接,拨号入口framework会进入teleService进行拨号

来电绑定

流程图:

TelephonyFramework跨进程逻辑(来电,去电绑定流程)_跨进程_03

来电从rild进入直到TeleService进程中的PstnIncomingCallNotifier.java中的Handler这里面会调用TelecomManager中的addNewIncomingCall()方法。

TelecomManager.from(mPhone.getContext()).addNewIncomingCall(handle, extras);

这里的TelecomManager.from();他内部是这样的

return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

获取phone进程中获取TelephonyManager对象。

这一步跨进程是获取一个系统服务,Telecom服务这个类就是TelecomSerivceImpl.java,这个服务在开机时就会启动,放在系统服务中。我们看一下代码 : addNewIncomingCall()方法

private ITelecomService getTelecomService() {
if (mTelecomServiceOverride != null) {
return mTelecomServiceOverride;
}
return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
}

public void addNewIncomingCall(PhoneAccountHandle phoneAccount, Bundle extras) {
try {
if (isServiceConnected()) {
getTelecomService().addNewIncomingCall(
phoneAccount, extras == null ? new Bundle() : extras);
}
} catch (RemoteException e) {
Log.e(TAG, "RemoteException adding a new incoming call: " + phoneAccount, e);
}
}

这里调用进入Telecom的TelecomServiceImpl.java中的addNewIncomingCall()方法

/**
* @see android.telecom.TelecomManager#addNewIncomingCall
*/
@Override
public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
try {
synchronized (mLock) {
if (phoneAccountHandle != null &&
phoneAccountHandle.getComponentName() != null) {
if (isCallerSimCallManager() && TelephonyUtil.isPstnComponentName(
phoneAccountHandle.getComponentName())) {

} else {
mAppOpsManager.checkPackage(
Binder.getCallingUid(),
phoneAccountHandle.getComponentName().getPackageName());
// Make sure it doesn't cross the UserHandle boundary
enforceUserHandleMatchesCaller(phoneAccountHandle);
enforcePhoneAccountIsRegisteredEnabled(phoneAccountHandle,
Binder.getCallingUserHandle());
if (isSelfManagedConnectionService(phoneAccountHandle)) {
// Self-managed phone account, ensure it has MANAGE_OWN_CALLS.
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.MANAGE_OWN_CALLS,
"Self-managed phone accounts must have MANAGE_OWN_CALLS " +
"permission.");
}
}
long token = Binder.clearCallingIdentity();
try {
Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);
intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
phoneAccountHandle);
intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, true);
if (extras != null) {
extras.setDefusable(true);
intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
}
mCallIntentProcessorAdapter.processIncomingCallIntent(
mCallsManager, intent);
} finally {
Binder.restoreCallingIdentity(token);
}
} else {
Log.w(this, "Null phoneAccountHandle. Ignoring request to add new" +
" incoming call");
}
}
} finally {
Log.endSession();
}
}

我们直接看这里的跳转一步一步走到绑定位置,就不复制代码了

直接来看绑定逻辑在CallManager.java中调用attemptNextPhoneAccount()

mService.createConnection(mCall, CreateConnectionProcessor.this); // 开始进行链接,核心过程

开始绑定IConnectionSerivce 和 IConnectionServiceAdapter

进入ContentSerivceWrapper.java中

public void createConnection(final Call call, final CreateConnectionResponse response) {//创建链接就是一个绑定服务的过程
....
......
.........
//绑定
mBinder.bind(callback, call);
}

这里的mBinder是ConnectionServiceWapper的父类的内部列Bilder2

void bind(BindCallback callback, Call call) {
.....
//在类里面绑定成功后mBinder.bind(callback, call);在父类ServiceBinder类里面mCallbacks.add(callback);吧回调用集合给装载起来,然后进行便利数据
//成功获取到aidl接口后将其赋值mServiceInterface,
mCallbacks.add(callback);
if (mServiceConnection == null) {
Intent serviceIntent = new Intent(mServiceAction).setComponent(mComponentName);
ServiceConnection connection = new ServiceBinderConnection(call);

Log.addEvent(call, LogUtils.Events.BIND_CS, mComponentName);
final int bindingFlags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
final boolean isBound;
if (mUserHandle != null) {// 进行绑定
isBound = mContext.bindServiceAsUser(serviceIntent, connection, bindingFlags, //如果绑定成功调用connection方法 这里绑定是绑定了framework/base/telepony
mUserHandle);//绑定的是TelephonyConnectionService
} else {
isBound = mContext.bindService(serviceIntent, connection, bindingFlags);
}
if (!isBound) {
handleFailedConnection();
return;
}
} else {
......
}
}
}

我们重点看一下mContext.bindSerivceAsUser().这里启动的就是framework中的ConnectionService服务,再继续看携带的数据connection对象,这里的SerivceBinderConnection,继承自SerivceConnection,我们看一下serviceConnection方法,

@Override
public void onServiceConnected(ComponentName componentName, IBinder binder) {
try {
synchronized (mLock) {
mCall = null;
if (mIsBindingAborted) {
clearAbort();
logServiceDisconnected("onServiceConnected");
mContext.unbindService(this);
handleFailedConnection();
return;
}
if (binder != null) {
mServiceDeathRecipient = new ServiceDeathRecipient(componentName);
try {

binder.linkToDeath(mServiceDeathRecipient, 0);
mServiceConnection = this;
setBinder(binder);// 触发bind(BindCallback callback, Call call) 中 callback 的 onSuccess 与framework/Telecom绑定进行通信
handleSuccessfulConnection(); //回调进入子类,内部循环了mCallback进入ConnectionServiceWrapper中的BindCallback
//整个绑定过程,只做2件事,一是给远程服务提供访问自己的接口,二是利用远程接口创建一个通话链接。
// 这2件事都是跨进程进行的。远程服务访问自己的接口是
} catch (RemoteException e) {
Log.w(this, "onServiceConnected: %s died.");
if (mServiceDeathRecipient != null) {
mServiceDeathRecipient.binderDied();
}
}
}
}
} finally {
Log.endSession();
}
}

我们这里重点关注一些setBinder方法内部调用了子类一个方法

protected void setServiceInterface(IBinder binder) {
mServiceInterface = IConnectionService.Stub.asInterface(binder);//保存binder对象
Log.v(this, "Adding Connection Service Adapter.");
addConnectionServiceAdapter(mAdapter);//这个mAdapter 给远程服务提供访问自己的接口
}

private void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
if (isServiceValid("addConnectionServiceAdapter")) {
try {
//在类里面绑定成功后mBinder.bind(callback, call);在父类ServiceBinder类里面mCallbacks.add(callback);吧回调用集合给装载起来,然后进行便利数据
//成功获取到aidl接口后将其赋值mServiceInterface,
logOutgoing("addConnectionServiceAdapter %s", adapter);
mServiceInterface.addConnectionServiceAdapter(adapter, Log.getExternalSession());
} catch (RemoteException e) {
}
}
}

这里的mAdapter就是实现IConnectionSerivceAdapter的对象,传给framework进行绑定。在来看handleSuccessfulConnection()方法,这个方法处理了createConnection传入的CallBack对象。

private void handleSuccessfulConnection() {
for (BindCallback callback : mCallbacks) {
callback.onSuccess();
}
mCallbacks.clear();
}

public void createConnection(final Call call, final CreateConnectionResponse response) {//创建链接就是一个绑定服务的过程
BindCallback callback = new BindCallback() {// 链接创建成功后 onSuccess 会被调用
@Override
public void onSuccess() {
...........
................
.......................
//通过通话相关信息的创建,ConnectionRequest支持系列化和反序列化
ConnectionRequest connectionRequest = new ConnectionRequest.Builder()
.setAccountHandle(call.getTargetPhoneAccount())
.setAddress(call.getHandle())
.setExtras(extras)
.setVideoState(call.getVideoState())
.setTelecomCallId(callId)//关键点

.setShouldShowIncomingCallUi(
!mCallsManager.shouldShowSystemIncomingCallUi(call))
.setRttPipeFromInCall(call.getInCallToCsRttPipeForCs())
.setRttPipeToInCall(call.getCsToInCallRttPipeForCs())
.build();//建造者模式的应用,创建对象

try {

mServiceInterface.createConnection( // 通过远程接口创建链接 利用远程接口创建一个通话链接 属于第二次宽进程访问
call.getConnectionManagerPhoneAccount(),
callId,
connectionRequest,
call.shouldAttachToExistingConnection(),
call.isUnknown(),
Log.getExternalSession());

} catch (RemoteException e) {
mPendingResponses.remove(callId).handleCreateConnectionFailure(
new DisconnectCause(DisconnectCause.ERROR, e.toString()));
}
}
};
//绑定
mBinder.bind(callback, call);
}

这里主要看createConnection这里直接进入了framework的ConnectionService的里面的createConnection我们继续来看代码

ConnectionService.java

private void createConnection(
final PhoneAccountHandle callManagerAccount,
final String callId,
final ConnectionRequest request,
boolean isIncoming,
boolean isUnknown) {

Connection connection = null;
if (isHandover) {
PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null
? (PhoneAccountHandle) request.getExtras().getParcelable(
TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT) : null;
if (!isIncoming) {
connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request);
} else {
connection = onCreateIncomingHandoverConnection(fromPhoneAccountHandle, request);
}
} else {
//
connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
: isIncoming ? onCreateIncomingConnection(callManagerAccount, request)//来电
: onCreateOutgoingConnection(callManagerAccount, request);//去电
}
............
..........
........
//mAdapter.handleCreateConnectionComplete 调用回到 ConnectionServiceWrapper 的 handleCreateConnectionComplete,
// 然后回到 Call 的 handleCreateConnectionSuccess
mAdapter.handleCreateConnectionComplete(// 通知 system 进程(即CallsManager) 电话链接已经创建完成
callId,
request,
new ParcelableConnection(
request.getAccountHandle(),
connection.getState(),
connection.getConnectionCapabilities(),
connection.getConnectionProperties(),
connection.getSupportedAudioRoutes(),
connection.getAddress(),
connection.getAddressPresentation(),
connection.getCallerDisplayName(),
connection.getCallerDisplayNamePresentation(),
connection.getVideoProvider() == null ?
null : connection.getVideoProvider().getInterface(),
connection.getVideoState(),
connection.isRingbackRequested(),
connection.getAudioModeIsVoip(),
connection.getConnectTimeMillis(),
connection.getConnectElapsedTimeMillis(),
connection.getStatusHints(),
connection.getDisconnectCause(),
createIdList(connection.getConferenceables()),
connection.getExtras()));

if (isIncoming && request.shouldShowIncomingCallUi() &&
(connection.getConnectionProperties() & Connection.PROPERTY_SELF_MANAGED) ==
Connection.PROPERTY_SELF_MANAGED) {
connection.onShowIncomingCallUi();
}
if (isUnknown) {
triggerConferenceRecalculate();
}
}

这里的mAdapter就是刚刚addConnectionServiceAdater进来的,handleCreateConnectionComplete()这里传入了一个序列化对象,回调进入telecom中的ConnectionServiceWrapper.java中

private void handleCreateConnectionComplete(
String callId,
ConnectionRequest request,
ParcelableConnection connection) {
.........
if (connection.getState() == Connection.STATE_DISCONNECTED) {
.....
} else {
// Successful connection 连接成功
if (mPendingResponses.containsKey(callId)) {
mPendingResponses.remove(callId)
.handleCreateConnectionSuccess(mCallIdMapper, connection);
}
}
}

这里的mPendingResponses.remove(callId).handleCreateConnectionSuccess()这里是进入了Telecom中的Call对象,

Call.java

@Override
public void handleCreateConnectionSuccess(
CallIdMapper idMapper,
ParcelableConnection connection) {
......
mConferenceableCalls.clear();
for (String id : connection.getConferenceableConnectionIds()) {
mConferenceableCalls.add(idMapper.getCall(id));
}

switch (mCallDirection) {
case CALL_DIRECTION_INCOMING: //来电流程
for (Listener l : mListeners) {
l.onSuccessfulIncomingCall(this);
}
break;
case CALL_DIRECTION_OUTGOING: // 因为时去电的流程,所以会走到这个部分
for (Listener l : mListeners) {
l.onSuccessfulOutgoingCall(this,// 由于 CallsManager 监听了 Call(在addCall的时候), 所以 CallsManager 会得到通知。信息最终提交给 com.android.dialer
getStateFromConnectionState(connection.getState()));
}
break;
case CALL_DIRECTION_UNKNOWN:
for (Listener l : mListeners) {
l.onSuccessfulUnknownCall(this, getStateFromConnectionState(connection
.getState()));
}
break;
}
}

这里的mListeners实现接口在CallManager

CallManager.java

@Override
public void onSuccessfulIncomingCall(Call incomingCall) { //成功来电
......
new IncomingCallFilter(mContext, this, incomingCall, mLock,
mTimeoutsAdapter, filters).performFiltering();
}

这里我们直接看performFiltering()

IncomingCallFilter.java

public void performFiltering() {
......
mHandler.postDelayed(new Runnable("ICF.pFTO", mTelecomLock) {
@Override
public void loggedRun() {
if (mIsPending) {
Log.i(IncomingCallFilter.this, "Call filtering has timed out.");
Log.addEvent(mCall, LogUtils.Events.FILTERING_TIMED_OUT);
mListener.onCallFilteringComplete(mCall, mResult);
mIsPending = false;
}
}
}.prepare(), mTimeoutsAdapter.getCallScreeningTimeoutMillis(mContext.getContentResolver()));
}

这里的mListener还是CallManager.java最后进入了addCall()方法

CallManager.java

public void addCall(Call call, CallFilteringResult result) {
......
for (CallsManagerListener listener : mListeners) {
......
listener.onCallAdded(call);
......
}
}

我们这里只看CallsManagerListener的一个子类就是InCallController.java

开始绑定InCallSerivce 和 InCallAdapter

如果要看代码请进入《 ​​来电入口​​ 》

if (!mContext.bindServiceAsUser(intent, mServiceConnection,   
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE |
Context.BIND_ABOVE_CLIENT,
UserHandle.CURRENT)) {

这里启动的是InCallSerivceImpl而内部实现了IInCallSerivce.aidl,通过IBinder返回。我们重点看一下传入的mServiceConnection对象他继承了SerivceConnection,如果传入这个对象就可以回调里面的serviceConnection方法他内部携带了一个binder。

private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.startSession("ICSBC.oSC");
synchronized (mLock) {
try {
Log.d(this, "onServiceConnected: %s %b %b", name, mIsBound, mIsConnected);
mIsBound = true;
if (mIsConnected) {//是否连接
// Only proceed if we are supposed to be connected.只有当我们被认为是有联系的时候才继续。 成功后调用InCallServer
onConnected(service);
}
} finally {
Log.endSession();
}
}
}



private boolean onConnected(InCallServiceInfo info, IBinder service) {
//进入Framework/base/Telecom //获取IInCallSerivce服务并保存
IInCallService inCallService = IInCallService.Stub.asInterface(service);
mInCallServices.put(info, inCallService);

try {
// 让绑定的服务,可以通过 InCallAdapter 跨进程 访问 system 进程 (因为当前就是在系统进程)
// InCallAdapter 是一个 Binder。
// 需要对Android 通过 Binder实现跨进程调用有一定了解
// 还有对Android 的AIDL由一定了解 调用到了Framework/base/telecom InCallServce
inCallService.setInCallAdapter(
new InCallAdapter( //如果启动InCallUi挂断时会回调进入这个Adapter。调用到了Framework/base/telecom InCallServce
mCallsManager,
mCallIdMapper,
mLock,
info.getComponentName().getPackageName()));
} catch (RemoteException e) {
Log.e(this, e, "Failed to set the in-call adapter.");
Trace.endSection();
return false;
}

//成功连接后,将 world 状态发送到服务。
List<Call> calls = orderCallsWithChildrenFirst(mCallsManager.getCalls());

int numCallsSent = 0;
//将之前保存的Call对象通过inCallService发出去
for (Call call : calls) {
try {

boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
addCall(call);
numCallsSent += 1;
//添加调用 注意这里Call对象的转换,将com.android.serivce.telecom.Call转换为可跨进程传递对象,android.telecom.parcelableCall
inCallService.addCall(ParcelableCallUtils.toParcelableCall(
call,
true /* includeVideoProvider */,
mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(),
includeRttCall));
} catch (RemoteException ignored) {
}
}
try {
//通知Call相关状态发送变化
inCallService.onCallAudioStateChanged(mCallsManager.getAudioState());
inCallService.onCanAddCallChanged(mCallsManager.canAddCall());
} catch (RemoteException ignored) {
}
Log.i(this, "%s calls sent to InCallService.", numCallsSent);
Trace.endSection();
return true;
}

我们需要重点看一下setInCallAdapter喝addCall着两个绑定,

setInCallAdapter提供给framwrork去调用最后设置在Call对象中,这里的Adapter是为消息下发处理的
addCall吧Telecomm Call对象转换成序列化对象 ,这个入口也是拨号调启InCallUi的入口

绑定玩IInCallSerivce和IInCallAdapter接下来就是绑定,IConnectionSerivce和IConnectionSerivceAdapter

绑定IConnectionSerivce的入口在CallManager.java中的placeOutgoingCall()方法他会进入Call的startCreateConnection,再通过创建CreateConnectionProcessor对象进入process方法,这个对象会获取一个ConnectionServiceWapper对象,进入createConneciton进行绑定