你的位置:首页 > 操作系统

[操作系统]Android7.0 Phone应用源码分析(二) phone来电流程分析


1.1TelephonyFramework

当有来电通知时,首先接收到消息的是Modem层,然后Medoem再上传给RIL层,RIL进程通过sokcet将消息发送给RILJ(framework层的RIL),同样进入RILJ的processResponse方法,根据前面介绍去电流程的分析得知,来电属于UnSolicited消息,事件ID是

RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,看看RILJ里的处理

com.android.internal.telephony.RIL
processUnsolicited (Parcel p, int type) {    ………………………………  switch(response) {    case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); 
    break;    ………………………………  }    ……………………………… switch(response) {    case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:     if (RILJ_LOGD) unsljLog(response);       mCallStateRegistrants .notifyRegistrants(new AsyncResult(null, null, null));     break;     ………………………………  }     ………………………………}

mCallStateRegistrants是RegistrantList实例,这里用到了观察者模式,mCallStateRegistrants将call状态的变化通知给了所有感兴趣的注册者,BaseCommands提供了相关注册接口

com.android.internal.telephony. registerForCallStateChanged @Override  public void registerForCallStateChanged(Handler h, int what, Object obj) {    Registrant r = new Registrant (h, what, obj);    mCallStateRegistrants.add(r);  }}

最后找到GsmCdmaCallTracker在创建的时候注册了该事件

com.android.internal.telephony. GsmCdmaCallTrackerpublic GsmCdmaCallTracker (GsmCdmaPhone phone) {    this.mPhone = phone;    mCi = phone.mCi;    mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);    mCi.registerForOn(this, EVENT_RADIO_AVAILABLE, null);    mCi.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);    ...... ......}

收到EVENT_CALL_STATE_CHANGE消息后进入pollCallsWhenSafe方法

protected void pollCallsWhenSafe() {    mNeedsPoll = true;    if (checkNoOperationsPending()) {      mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);      mCi.getCurrentCalls(mLastRelevantPoll);    }}}

这里的处理流程跟之前拨号类似,同样是通过RILJ获取当前call状态,收到回应后进入handlePollCalls方法

protected synchronized void handlePollCalls(AsyncResult ar) {   ………………………………   if (newRinging != null) {     // 新来电通知    mPhone.notifyNewRingingConnection(newRinging);   }    ………………………………  updatePhoneState();        // 更新phone状态    ……………………………… if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected)      {   mPhone.notifyPreciseCallStateChanged(); // 发出call状态变化通知  }}

新来电进入phone的notifyNewRingingConnection的方法

com.android.internal.telephony.Phone public void notifyNewRingingConnectionP(Connection cn) {  if (!mIsVoiceCapable)     return;  AsyncResult ar = new AsyncResult(null, cn, null);  mNewRingingConnectionRegistrants.notifyRegistrants(ar);}}

又是一个观察者模式,最后找到是注册了该事件的监听对象PstnIncomingCallNotifier

1.2TelephonyService

com.android.services.telephony. PstnIncomingCallNotifierprivate void registerForNotifications() { if (mPhone != null) {     Log.i(this, "Registering: %s", mPhone);     mPhone.registerForNewRingingConnection(mHandler, EVENT_NEW_RINGING_CONNECTION, null);     mPhone.registerForCallWaiting(mHandler, EVENT_CDMA_CALL_WAITING, null);     mPhone.registerForUnknownConnection(mHandler, EVENT_UNKNOWN_CONNECTION, null);    }}

Handler处理消息进入handleNewRingingConnection方法

private void handleNewRingingConnection(AsyncResult asyncResult) {    Log.d(this, "handleNewRingingConnection");    Connection connection = (Connection) asyncResult.result;    if (connection != null) {      Call call = connection.getCall();      // Final verification of the ringing state before sending the intent to Telecom.      if (call != null && call.getState().isRinging()) {        sendIncomingCallIntent(connection);      }    } }

获取到call对象以后,最后进入sendIncomingCallIntent

private void sendIncomingCallIntent(Connection connection) {      ………………………………    PhoneAccountHandle handle = findCorrectPhoneAccountHandle();    if (handle == null) {      try {        connection.hangup();      } catch (CallStateException e) {        // connection already disconnected. Do nothing      }    } else {      TelecomManager.from(mPhone.getContext()).addNewIncomingCall(handle, extras);    } }

通过aidl接口调用telecomservice的的addNewIncomingCall方法

1.3 TelecomService

TelecomServiceImpl的成员变量mBinderImpl是具体实现类

com.android.server.telecom.TelecomServiceImplprivate final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub(){public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {  ………………………………  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);}  ………………………………}

这里调用到的是CallIntentProcessor 的processIncomingCallIntent方法

com.android.server.telecom. CallIntentProcessorstatic void processIncomingCallIntent(CallsManager callsManager, Intent intent) {    ………………………………    Log.d(CallIntentProcessor.class,        "Processing incoming call from connection service [%s]",        phoneAccountHandle.getComponentName());    callsManager.processIncomingCallIntent(phoneAccountHandle, clientExtras);}

进入callsmanager的processIncomingCallIntent方法

void processIncomingCallIntent(PhoneAccountHandle phoneAccountHandle, Bundle extras) {    ………………………………    Call call = new Call(        getNextCallId(),        mContext,        this,        mLock,        mConnectionServiceRepository,        mContactsAsyncHelper,        mCallerInfoAsyncQueryFactory,        handle,        null /* gatewayInfo */,        null /* connectionManagerPhoneAccount */,        phoneAccountHandle,        Call.CALL_DIRECTION_INCOMING /* callDirection */,        false /* forceAttachToExistingConnection */,        false /* isConference */    );    ………………………………    call.addListener(this);    call.startCreateConnection(mPhoneAccountRegistrar);  }

走到这一步,跟之前拨号的流程一样,创建了一个call对象,然后调用

startCreateConnection创建连接,根据之前拨号的流程分析最后会进入 ConnectionService的createConnection方法

1.4 TelecommFramework

再把实现代码贴一遍:

private void createConnection(final PhoneAccountHandle callManagerAccount, final String callId, 
       final ConnectionRequest request,  boolean isIncoming, boolean isUnknown) {       ………………………………    Connection connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)     : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)     : onCreateOutgoingConnection(callManagerAccount, request); 
       ………………………………    mAdapter.handleCreateConnectionComplete(        callId,        request,        new ParcelableConnection(            request.getAccountHandle(),            connection.getState(),            connection.getConnectionCapabilities(),            connection.getConnectionProperties(),            connection.getAddress(),            connection.getAddressPresentation(),            connection.getCallerDisplayName(),            connection.getCallerDisplayNamePresentation(),            connection.getVideoProvider() == null ?                null : connection.getVideoProvider().getInterface(),            connection.getVideoState(),            connection.isRingbackRequested(),            connection.getAudioModeIsVoip(),            connection.getConnectTimeMillis(),            connection.getStatusHints(),            connection.getDisconnectCause(),            createIdList(connection.getConferenceables()),            connection.getExtras(),            connection.getUserData()));//MOTO Calling Code - IKPIM-1774 (ftr 33860)    if (isUnknown) {      triggerConferenceRecalculate();    }}

这里由于是来电,所以调用onCreateIncomingConnection方法,该方法同样返回null,所以具体是由其子类实现的,也就是TelephonyConnectionService

public Connection onCreateIncomingConnection(      PhoneAccountHandle connectionManagerPhoneAccount,      ConnectionRequest request) {          Connection connection =  createConnectionFor(phone, originalConnection, false /* isOutgoing */,            request.getAccountHandle(), request.getTelecomCallId(),            request.getAddress());    if (connection == null) {      return Connection.createCanceledConnection();    } else {      return connection;    } }

最后根据GMS或是CDMA返回对应Connection对象,最后进入ConnectionServiceAdapter处理

android.telecom. ConnectionServiceAdapter void handleCreateConnectionComplete(      String id,      ConnectionRequest request,      ParcelableConnection connection) {    for (IConnectionServiceAdapter adapter : mAdapters) {      try {        adapter.handleCreateConnectionComplete(id, request, connection);      } catch (RemoteException e) {      }    }}

这里的adapter实际上就是ConnectionServiceWrapper的内部类Adapter,需要注意的是之前拨号的时候创建完connection并呼出之后,后续也会走到这个流程里

public void handleCreateConnectionComplete(String callId, ConnectionRequest request,        ParcelableConnection connection) {      Log.startSession("CSW.hCCC");      long token = Binder.clearCallingIdentity();      try {        synchronized (mLock) {          logIncoming("handleCreateConnectionComplete %s", callId);          ConnectionServiceWrapper.this            handleCreateConnectionComplete(callId, request, connection);        }      } finally {        Binder.restoreCallingIdentity(token);        Log.endSession();      }}

最后进入handleCreateConnectionComplete方法

private void handleCreateConnectionComplete(      String callId,      ConnectionRequest request,      ParcelableConnection connection) {    // TODO: Note we are not using parameter "request", which is a side effect of our tacit    // assumption that we have at most one outgoing connection attempt per ConnectionService.    // This may not continue to be the case.    if (connection.getState() == Connection.STATE_DISCONNECTED) {      // A connection that begins in the DISCONNECTED state is an indication of      // failure to connect; we handle all failures uniformly      removeCall(callId, connection.getDisconnectCause());    } else {      // Successful connection      if (mPendingResponses.containsKey(callId)) {        mPendingResponses.remove(callId).handleCreateConnectionSuccess(mCallIdMapper, connection);      }    }}

这里的mPendingResponses是map容器

private final Map<String, CreateConnectionResponse> mPendingResponses = new HashMap<>();

ConnectionServiceWrapper在调用createConnection的时候会往该容器里添加对象,也就是CreateConnectionProcessor对象

public void handleCreateConnectionSuccess(      CallIdMapper idMapper,      ParcelableConnection connection) {    if (mCallResponse == null) {      // Nobody is listening for this connection attempt any longer; ask the responsible      // ConnectionService to tear down any resources associated with the call      mService.abort(mCall);    } else {      // Success -- share the good news and remember that we are no longer interested      // in hearing about any more attempts      mCallResponse.handleCreateConnectionSuccess(idMapper, connection);      mCallResponse = null;      // If there's a timeout running then don't clear it. The timeout can be triggered      // after the call has successfully been created but before it has become active.    }}

这个mCallResponse是CreateConnectionProcessor创建的时候引入的,也就是call对象

com.android.server.telecom.Call  public void handleCreateConnectionSuccess(      CallIdMapper idMapper,      ParcelableConnection connection) {       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,              getStateFromConnectionState(connection.getState()));        }        break;      case CALL_DIRECTION_UNKNOWN:        for (Listener l : mListeners) {           l.onSuccessfulUnknownCall(this, getStateFromConnectionState(connection .getState()));        }        break;    }  }

这里根据是来电还是去电类型,执行相应回调,监听者会收到通知,来电事件则触发onSuccessfulIncomingCall的回调

1.5 TelecommService

前面提到CallsManager在执行processIncomingCallIntent方法时候会创建call,之后就会给call添加监听,所以最后会回调到CallsManager类

public void onSuccessfulIncomingCall(Call incomingCall) {    Log.d(this, "onSuccessfulIncomingCall");    List<IncomingCallFilter.CallFilter> filters = new ArrayList<>();    filters.add(new DirectToVoicemailCallFilter(mCallerInfoLookupHelper));    filters.add(new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter()));    filters.add(new CallScreeningServiceFilter(mContext, this, mPhoneAccountRegistrar,        mDefaultDialerManagerAdapter,        new ParcelableCallUtils.Converter(), mLock));    new IncomingCallFilter(mContext, this, incomingCall, mLock,        mTimeoutsAdapter, filters).performFiltering();}

这里用到了一个迭代器模式,一个来电操作触发这三个对象的处理:

DirectToVoicemailCallFilter,AsyncBlockCheckFilter,CallScreeningServiceFilter

生成一个IncomingCallFilter对象,调用performFiltering方法

com.android.server.telecom.callfiltering. IncomingCallFilter public void performFiltering() {    Log.event(mCall, Log.Events.FILTERING_INITIATED);    for (CallFilter filter : mFilters) {      filter.startFilterLookup(mCall, this);    }    mHandler.postDelayed(new Runnable("ICF.pFTO") { // performFiltering time-out      @Override      public void loggedRun() {        // synchronized to prevent a race on mResult and to enter into Telecom.        synchronized (mTelecomLock) {          if (mIsPending) {            Log.i(IncomingCallFilter.this, "Call filtering has timed out.");            Log.event(mCall, Log.Events.FILTERING_TIMED_OUT);            mListener.onCallFilteringComplete(mCall, mResult);            mIsPending = false;          }        }      }  }.prepare(), mTimeoutsAdapter.getCallScreeningTimeoutMillis(mContext.getContentResolver()));}

他们依次执行startFilterLookup异步查询方法,通过回调方法并将结果CallFilteringResult传回onCallFilteringComplete将CallFilteringResult对象传递回来

public class CallFilteringResult {  public boolean shouldAllowCall;     // 是否允许通话  public boolean shouldReject;      // 是否拒接  public boolean shouldAddToCallLog;   // 是否添加至通话记  public boolean shouldShowNotification; // 是否显示通知栏消息  ………………………………  ………………………………}public void onCallFilteringComplete(Call call, CallFilteringResult result) {    synchronized (mTelecomLock) { // synchronizing to prevent race on mResult      mNumPendingFilters--;      mResult = result.combine(mResult);      if (mNumPendingFilters == 0) {        mHandler.post(new Runnable("ICF.oCFC") {          @Override          public void loggedRun() {            // synchronized to enter into Telecom.            synchronized (mTelecomLock) {              if (mIsPending) {                mListener.onCallFilteringComplete(mCall, mResult);                mIsPending = false;              }            }          }        }.prepare());      }    }  }

先看看DirectToVoicemailCallFilter对象,它处理的是voicemail相关信息,

实际上是由CallerInfoLookupHelper完成查询的,内部调用CallerInfoAsyncQueryFactory的startQuery方法,而CallerInfoAsyncQueryFactory是个接口类,在CallsManager创建的时候由外部传参进来,最后找到是TelecomService的initializeTelecomSystem里创建的

com.android.server.telecom.components. TelecomServicestatic void initializeTelecomSystem(Context context) {  new CallerInfoAsyncQueryFactory() {      @Override      public CallerInfoAsyncQuery startQuery(         int token, Context context, String number,         CallerInfoAsyncQuery.OnQueryCompleteListener listener,         Object cookie) {           Log.i(TelecomSystem.getInstance(),           "CallerInfoAsyncQuery.startQuery number=%s cookie=%s",           Log.pii(number), cookie);           return CallerInfoAsyncQuery.startQuery(           token, context, number, listener, cookie);      } }

进入CallerInfoAsyncQuery的startQuery方法

com.android.internal.telephony.CallerInfoAsyncQuerypublic static CallerInfoAsyncQuery startQuery(int token, Context context, String number,      OnQueryCompleteListener listener, Object cookie, int subId) { final Uri contactRef = PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI.buildUpon()     .appendPath(number)     .appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS,     String.valueOf(PhoneNumberUtils.isUriNumber(number)))     .build();}

查询的uri是PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI

返回cursor结果集后转化成CallerInfo,其中shouldSendToVoicemail变量查询的

是PhoneLookup.SEND_TO_VOICEMAIL字段

public static CallerInfo getCallerInfo(Context context, Uri contactRef, Cursor cursor) {    ...... ......    ...... ......    columnIndex = cursor.getColumnIndex(PhoneLookup.SEND_TO_VOICEMAIL);        info.shouldSendToVoicemail = (columnIndex != -1) &&            ((cursor.getInt(columnIndex)) == 1);        info.contactExists = true;    ...... ......}

最后回到DirectToVoicemailCallFilter的查询回调,shouldSendToVoicemail为true时表示允许通话,否则是拒接

if (info.shouldSendToVoicemail) {  result = new CallFilteringResult(            false, // shouldAllowCall            true, // shouldReject            true, // shouldAddToCallLog            true // shouldShowNotification             );  } else {      result = new CallFilteringResult(             true, // shouldAllowCall              false, // shouldReject             true, // shouldAddToCallLog             true // shouldShowNotification             );   }}

再看看AsyncBlockCheckFilter,它处理的是黑名单事件

判断一个电话号码是否在黑名单里调用到了BlockChecker的isBlocked方法

com.android.internal.telephony. BlockCheckerpublic static boolean isBlocked(Context context, String phoneNumber) {    boolean isBlocked = false;    long startTimeNano = System.nanoTime();    try {      if (BlockedNumberContract.SystemContract.shouldSystemBlockNumber(          context, phoneNumber)) {        Rlog.d(TAG, phoneNumber + " is blocked.");        isBlocked = true;      }    } catch (Exception e) {      Rlog.e(TAG, "Exception checking for blocked number: " + e);    }    int durationMillis = (int) ((System.nanoTime() - startTimeNano) / 1000000);    if (durationMillis > 500 || VDBG) {      Rlog.d(TAG, "Blocked number lookup took: " + durationMillis + " ms.");    }    return isBlocked;  }

BlockedNumberContract.SystemContract是framework里的一个黑名单协议类

public static final String AUTHORITY = "com.android.blockednumber";public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number";public static boolean shouldSystemBlockNumber(Context context, String phoneNumber) {      final Bundle res = context.getContentResolver().call(         AUTHORITY_URI, METHOD_SHOULD_SYSTEM_BLOCK_NUMBER, phoneNumber, null);      return res != null && res.getBoolean(RES_NUMBER_IS_BLOCKED, false);}

黑名单是BlockedNumberProvider数据库, 调用call方法

com.android.providers.blockednumber. BlockedNumberProvider@Overridepublic Bundle call(@NonNull String method, @Nullable String arg, @Nullable Bundle extras) {    final Bundle res = new Bundle();    switch (method) {        case SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER:          enforceSystemReadPermissionAndPrimaryUser();          res.putBoolean(          BlockedNumberContract.RES_NUMBER_IS_BLOCKED, shouldSystemBlockNumber(arg));        break;        ............        ............    }      }private boolean shouldSystemBlockNumber(String phoneNumber) {  if (getBlockSuppressionStatus().isSuppressed) {     return false;  }  if (isEmergencyNumber(phoneNumber)) {    return false;  }    return isBlocked(phoneNumber);}

最后调用isBlocked方法查询blocked表中是否存在该number

查询得到结果后返回

CallFilteringResult result;    if (isBlocked) {      result = new CallFilteringResult(          false, // shouldAllowCall          true, //shouldReject          false, //shouldAddToCallLog          false // shouldShowNotification      );    } else {      result = new CallFilteringResult(          true, // shouldAllowCall          false, // shouldReject          true, // shouldAddToCallLog          true // shouldShowNotification      );    }

如果号码在黑名单里则拦截

最后是CallScreeningServiceFilter不知道是处理什么,内部绑定一个抽象服务

CallScreeningService但是却找不到哪个子类继承了它,这里先忽略它

回到前面IncomingCallFilter的onCallFilteringCompletev方法,结果集会做个逻辑运算

mResult = result.combine(mResult);看看它的实现

com.android.server.telecom.callfilteringCallFilteringResultpublic CallFilteringResult combine(CallFilteringResult other) {    if (other == null) {      return this;    }    return new CallFilteringResult(        shouldAllowCall && other.shouldAllowCall,        shouldReject || other.shouldReject,        shouldAddToCallLog && other.shouldAddToCallLog,        shouldShowNotification && other.shouldShowNotification);  }

只有三个过滤结果都是允许通话才允许通话,添加至通话记录以及是否显示到通知栏同理

当然这里的查询操作也有超时限制,时间是5秒,超过5秒后忽略还未查询到的过滤器则被忽略mTimeoutsAdapter.getCallScreeningTimeoutMillis(mContext.getContentResolver()));

最后过滤结果被回调到CallsManager的onCallFilteringComplete

public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result) {  ………………………………  if (incomingCall.getState() != CallState.DISCONNECTED &&   incomingCall.getState() != CallState.DISCONNECTING) {      setCallState(incomingCall, CallState.RINGING,       result.shouldAllowCall ? "successful incoming call" : "blocking call");  } else {    Log.i(this, "onCallFilteringCompleted: call already disconnected.");  }    if (result.shouldAllowCall) {      if (hasMaximumRingingCalls()) {        rejectCallAndLog(incomingCall);      } else if (hasMaximumDialingCalls()) {        rejectCallAndLog(incomingCall);      } else {        addCall(incomingCall);      }    } else {      if (result.shouldReject) {        incomingCall.reject(false, null);      }      if (result.shouldAddToCallLog) {           mCallLogManager.logCall(incomingCall, Calls.MISSED_TYPE,            result.shouldShowNotification);      } else if (result.shouldShowNotification) {        mMissedCallNotifier.showMissedCallNotification(incomingCall);      }    }  }

调用setCallState设置通话状态为CallState.RINGING,接着判断是否拒接,是否写入通话记录等, 正常情况下调用addCall方法

private void addCall(Call call) {    ………………………………    updateCallsManagerState();    // onCallAdded for calls which immediately take the foreground (like the first call).    for (CallsManagerListener listener : mListeners) {      if (Log.SYSTRACE_DEBUG) {        Trace.beginSection(listener.getClass().toString() + " addCall");      }      listener.onCallAdded(call);      if (Log.SYSTRACE_DEBUG) {        Trace.endSection();      }    }    Trace.endSection();  }

遍历回调监听者的onCallAdded方法,InCallController是其中一个观察者,看看它的实现

com.android.server.telecom. InCallController@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 = ParcelableCallUtils.toParcelableCall(call,         true,mCallsManager.getPhoneAccountRegistrar());        try {          inCallService.addCall(parcelableCall);        } catch (RemoteException ignored) {        }      }    }  }

这里的inCallService是个aidl接口,抽象服务InCallService的嵌套类InCallServiceBinder 实现了该接口

1.6 TelecommFramework

android.telecom. InCallServiceprivate final class InCallServiceBinder extends IInCallService.Stub {  @Override    public void addCall(ParcelableCall call) {      mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget();    }  ...... ......  ...... ......}

handle对象处理消息MSG_ADD_CALL

private final Handler mHandler = new Handler(Looper.getMainLooper()) {    @Override    public void handleMessage(Message msg) {        case MSG_ADD_CALL:          mPhone.internalAddCall((ParcelableCall) msg.obj);          break;   }}candroid.telecom.Phonefinal void internalAddCall(ParcelableCall parcelableCall) {    Call call = new Call(this, parcelableCall.getId(), mInCallAdapter,        parcelableCall.getState());    mCallByTelecomCallId.put(parcelableCall.getId(), call);    mCalls.add(call);    checkCallTree(parcelableCall);    call.internalUpdate(parcelableCall, mCallByTelecomCallId);    fireCallAdded(call); } private void fireCallAdded(Call call) {    for (Listener listener : mListeners) {      listener.onCallAdded(this, call);    } }

mPhone对象内部新建了一个call对象,获取并转化ParcelableCall的相关信息,并将call对象加入列表,最后回调Phone的监听者的onCallAdded方法,这里就是InCallService的

mPhoneListener成员变量

private Phone.Listener mPhoneListener = new Phone.Listener() {    /** ${inheritDoc} */     ...... ......    /** ${inheritDoc} */    @Override    public void onCallAdded(Phone phone, Call call) {      InCallService.this.onCallAdded(call);    }    ...... ......  };

这里InCallService的onCallAdded方法是一个抽象方法,具体实现在它的子类

1.7 Dialer

InCallServiceImpl继承了InCallService,该服务在Dialer工程的manifest文件里有声明

<service android:name="com.android.incallui.InCallServiceImpl"   android:permission="android.permission.BIND_INCALL_SERVICE"   android:directBootAware="true" >   <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI"      android:value="true" />   <meta-data android:name="android.telecom.IN_CALL_SERVICE_RINGING"      android:value="false"/>   <intent-filter>      <action android:name="android.telecom.InCallService"/>   </intent-filter></service>

看看InCallServiceImpl的onCallAdded方法

com.android.incallui. InCallServiceImpl @Override  public void onCallAdded(Call call) {    InCallPresenter.getInstance().onCallAdded(call);  }

InCallPresenter是incallui用于处理通话逻辑的核心类,内部就是各种业务逻辑操作,看看onCallAdded方法

com.android.incallui. InCallPresenterpublic void onCallAdded(final android.telecom.Call call) {    if (shouldAttemptBlocking(call)) {      maybeBlockCall(call);    } else {      mCallList.onCallAdded(call);    }    // Since a call has been added we are no longer waiting for Telecom to send us a call.    setBoundAndWaitingForOutgoingCall(false, null);    call.registerCallback(mCallCallback);}

mCallList维护了call列表

com.android.incallui.CallListpublic void onCallAdded(final android.telecom.Call telecomCall) {    Trace.beginSection("onCallAdded");    final Call call = new Call(telecomCall);    Log.d(this, "onCallAdded: callState=" + call.getState());    if (call.getState() == Call.State.INCOMING ||        call.getState() == Call.State.CALL_WAITING) {      onIncoming(call, call.getCannedSmsResponses());    } else {      onUpdate(call);    }    call.logCallInitiationType();    Trace.endSection();}

来电则调用onIncoming方法,其它call状态则调用onUpdate方法,具体过程这里就不详述了,最终incallui拉起来电界面显示,至此,一个来电的整体流程都分析完了,大致流程如下:

RIL→TelephonyFramework →TeleponyService→ TeleComService→

TeleComFramework→ TeleComService→TeleComFramework-->Dialer