总结
InCallService是UI和telecom的桥梁。通过InCallService来完成各种call的更新与操作。
启动
CallsManager在生成新的Call实例后,会通过回调InCallController的onCallAdded函数,这个时候如果InCallService没有被启动,InCallController会去启动InCallService,如果已经绑定了,那么直接调用incallService的addCall函数。
即,所有CallsManager的回调,最后都调到InCallService的相关函数来处理。
@Override
public void onCallAdded(Call call) {
if (!isBoundToServices()) {
bindToServices(call);
} else {
adjustServiceBindingsForEmergency();
Log.i(this, "onCallAdded: %s", call);
// Track the call if we don't already know about it.
addCall(call);
for (Map.Entry<ComponentName, IInCallService> entry : mInCallServices.entrySet()) {
ComponentName componentName = entry.getKey();
IInCallService inCallService = entry.getValue();
ParcelableCall parcelableCall = toParcelableCall(call,
true /* includeVideoProvider */);
try {
inCallService.addCall(parcelableCall);
} catch (RemoteException ignored) {
}
}
}
}
下面直接看一下,启动完成后,在onConnected函数中,做了什么
private void onConnected(ComponentName componentName, IBinder service) {
Trace.beginSection("onConnected: " + componentName);
Log.i(this, "onConnected to %s", componentName);
IInCallService inCallService = IInCallService.Stub.asInterface(service);
mInCallServices.put(componentName, inCallService);
try {
inCallService.setInCallAdapter(
new InCallAdapter(
mCallsManager,
mCallIdMapper,
mLock));
} catch (RemoteException e) {
Log.e(this, e, "Failed to set the in-call adapter.");
Trace.endSection();
onInCallServiceFailure(componentName, "setInCallAdapter");
return;
}
// Upon successful connection, send the state of the world to the service.
Collection<Call> calls = mCallsManager.getCalls();
if (!calls.isEmpty()) {
Log.i(this, "Adding %s calls to InCallService after onConnected: %s", calls.size(),
componentName);
for (Call call : calls) {
try {
// Track the call if we don't already know about it.
addCall(call);
inCallService.addCall(toParcelableCall(call, true /* includeVideoProvider */));
} catch (RemoteException ignored) {
}
}
onCallAudioStateChanged(
null,
mCallsManager.getAudioState());
onCanAddCallChanged(mCallsManager.canAddCall());
} else {
unbindFromServices();
}
Trace.endSection();
}
- 通过inCallService的setInCallAdapter设置了和InCallService双向通信的binder接口。
- 这个时候要是还有没出来的call,调用incallService.addCall
双向操作
可以看到InCallAdapter也是个IInCallAdapter的服务端实现(frameworks/base/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl)
class InCallAdapter extends IInCallAdapter.Stub {
private final CallsManager mCallsManager;
private final CallIdMapper mCallIdMapper;
private final TelecomSystem.SyncRoot mLock;
....
InCallServiceImpl(packages/apps/InCallUI/src/com/android/incallui/InCallServiceImpl.java)继承了InCallService,所以最后最后启动了InCallServiceImpl。
当用户操作的时候,通过InCallAdapter对象来通知telecom(最终是调用CallsManager相关函数),当底层状态变化(也是通过CallsManager调用InCallController的回调,最后调到InCallService),用InCallService来让上层更新相关状态。
所以,分层来看InCallService连接上下,操作的角度CallsManager承上启下。
网友评论