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

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跨进程逻辑(来电,去电绑定流程)_第1张图片

 

开始绑定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 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跨进程逻辑(来电,去电绑定流程)_第2张图片

来电从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 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进行绑定

 

你可能感兴趣的:(TelephonyFramework跨进程逻辑(来电,去电绑定流程))