美文网首页
android 6.0 InCallService

android 6.0 InCallService

作者: wbxjack | 来源:发表于2016-06-24 18:36 被阅读1935次

    总结

    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();
    }
    
    1. 通过inCallService的setInCallAdapter设置了和InCallService双向通信的binder接口。
    2. 这个时候要是还有没出来的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承上启下。

    相关文章

      网友评论

          本文标题:android 6.0 InCallService

          本文链接:https://www.haomeiwen.com/subject/fgwodttx.html