android Telephony学习 --- 第六篇 android7.0 MO InCallActivity启动流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tingsky9985/article/details/79978154

我们先看下7.0启动InCallActivity时序图:
android Telephony学习 --- 第六篇 android7.0 MO InCallActivity启动流程

还记得上篇讲的*号标记的地方么,对CallIntentProcessor里调用CallsManager的startOutgoingCall方法,我们从这里开始分析:

// Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
Call call = callsManager.startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser);
  • packages/services/Telecomm – CallsManager
if (!mCalls.contains(call) && mPendingMOEmerCall == null) {
   // We check if mCalls already contains the call because we could potentially be reusing
   // a call which was previously added (See {@link #reuseOutgoingCall}).
   addCall(call);
        }

去寻找监听CallsManagerListener的onCallAdded方法:

    private void addCall(Call call) {
        for (CallsManagerListener listener : mListeners) {
            listener.onCallAdded(call);
        }    
    }        
  • packages/services/Telecomm – InCallController
   @Override
    public void onCallAdded(Call call) {
        if (!isBoundToServices()) {
            bindToServices(call);
        }
    }

来看关键代码,绑定InCallService:

            Intent intent = new Intent(InCallService.SERVICE_INTERFACE);
            intent.setComponent(mInCallServiceInfo.getComponentName());
            if (call != null && !call.isIncoming() && !call.isExternalCall()){
                intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS,
                        call.getIntentExtras());
                intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
                        call.getTargetPhoneAccount());
            }

            Log.i(this, "Attempting to bind to InCall %s, with %s", mInCallServiceInfo, intent);
            mIsConnected = true;
            if (!mContext.bindServiceAsUser(intent, mServiceConnection,
                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE |
                        Context.BIND_ABOVE_CLIENT,
                        UserHandle.CURRENT)) {
                Log.w(this, "Failed to connect.");
                mIsConnected = false;
            }

查看mServiceConnection的onServiceConnected方法:

private class InCallServiceBindingConnection extends InCallServiceConnection {

        private final ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                synchronized (mLock) {
                    try {
                        mIsBound = true;
                        if (mIsConnected) {
                            // Only proceed if we are supposed to be connected.
                            onConnected(service);
                        }
                    } 
                }
            }

onConnected方法:

        protected void onConnected(IBinder service) {
            boolean shouldRemainConnected =
                    InCallController.this.onConnected(mInCallServiceInfo, service);
        }

先找到aidl IInCallService对应的接收端,并找到方法addCall:

  private boolean onConnected(InCallServiceInfo info, IBinder service) {
        IInCallService inCallService = IInCallService.Stub.asInterface(service);
        mInCallServices.put(info, inCallService);
        try {
            inCallService.setInCallAdapter(
                    new InCallAdapter(
                            mCallsManager,
                            mCallIdMapper,
                            mLock,
                            info.getComponentName().getPackageName()));
        } 
        
        for (Call call : calls) {
            try {
                // Track the call if we don't already know about it.
                addCall(call);
                numCallsSent += 1;
                inCallService.addCall(ParcelableCallUtils.toParcelableCall(
                        call,
                        true /* includeVideoProvider */,
                        mCallsManager.getPhoneAccountRegistrar(),
                        info.isExternalCallsSupported()));
            } catch (RemoteException ignored) {
            }
        }
  • packages/services/Telecomm – InCallService
    private final class InCallServiceBinder extends IInCallService.Stub {
        @Override
        public void addCall(ParcelableCall call) {
            mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget();
        }
  • frameworks/base/telecomm – Phone
    去找监听的代码,找到onCallAdded方法:
    private void fireCallAdded(Call call) {
        for (Listener listener : mListeners) {
            listener.onCallAdded(this, call);
        }
    }
  • packages/services/Telecomm – InCallService
    绕了一下,又回到了InCallService,并去寻找InCallService的子类:
 private Phone.Listener mPhoneListener = new Phone.Listener() {
        /** ${inheritDoc} */
        @Override
        public void onCallAdded(Phone phone, Call call) {
            InCallService.this.onCallAdded(call);
        }

  • packages/app/Dialer – InCallServiceImpl

InCallServiceImpl extends InCallService

    @Override
    public void onCallAdded(Call call) {
        InCallPresenter.getInstance().onCallAdded(call);
    }
  • packages/app/Dialer – InCallPresenter
    public void onCallAdded(final android.telecom.Call call) {
        if (shouldAttemptBlocking(call)) {
            maybeBlockCall(call);
        } else {
                mCallList.onCallAdded(call);
        }
    }
  • packages/app/Dialer – CallList
    需要找到实现监听implements CallList.Listener,实现方法onCallListChange的地方:
    private void notifyGenericListeners() {
        for (Listener listener : mListeners) {
            listener.onCallListChange(this);
        }
    }
  • packages/app/Dialer – InCallPresenter

startOrFinishUi

    public void onCallListChange(CallList callList) {
        InCallState newState = getPotentialStateFromCallList(callList);
        InCallState oldState = mInCallState;
        newState = startOrFinishUi(newState);

启动InCallActivity:

    public void showInCall(final boolean showDialpad, final boolean newOutgoingCall) {
        Log.i(this, "Showing InCallActivity");
        mContext.startActivity(getInCallIntent(showDialpad, newOutgoingCall));
    }

到这为止,呼出InCallActivity启动的流程基本结束了。

阅读更多

没有更多推荐了,返回首页