Android Telephony Learning---The seventh android7.0 incoming call (MT) process

Let's first look at the general process of 7.0 calls:

 
   

Framework

After the modem receives the incoming call notification message, it reports to the RIL layer in the form of AT commands, and the RIL layer sends the message to RILJ through sokcet, and reports the event ID: RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:

  • frameworks/opt/telephony – RIL
    private void processUnsolicited (Parcel p, int type) {
           case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
                if (RILJ_LOGD) unsljLog(response);
                mCallStateRegistrants
                    .notifyRegistrants(new AsyncResult(null, null, null));
            break;
  • frameworks/opt/telephony – BaseCommands 
The observer method added by mCallStateRegistrants in BaseCommands registers the registerForCallStateChanged method in GsmCdmaCallTracker:
    @Override
    public void registerForCallStateChanged(Handler h, int what, Object obj) {
        Registrant r = new Registrant (h, what, obj);
        mCallStateRegistrants.add(r);
    }
  • frameworks/opt/telephony – GsmCdmaCallTracker
   public GsmCdmaCallTracker (GsmCdmaPhone phone) {
        mCi = phone.mCi;
        mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
Then find the EVENT_CALL_STATE_CHANGE message:
            case EVENT_CALL_STATE_CHANGE:
                pollCallsWhenSafe();
            break;
  • frameworks/opt/telephony – CallTracker
Find the method pollCallsWhenSafe of the parent class of GsmCdmaCallTracker:

    protected void pollCallsWhenSafe() {
        mNeedsPoll = true;
        if (checkNoOperationsPending ()) {
            mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
            mCi.getCurrentCalls(mLastRelevantPoll);
        }
    }
  • frameworks/opt/telephony – RIL
Find CommandsInterface mCi, and its RIL implements CommandsInterface implements the getCurrentCalls method, carrying the message 

EVENT_POLL_CALLS_RESULT:

    @Override
    public void getCurrentCalls (Message result) {
        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);
        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
        send(rr);
    }
  • frameworks/opt/telephony – GsmCdmaCallTracker
Similar to the previous process, then enter the handlePollCalls method:
           
case EVENT_POLL_CALLS_RESULT:
                Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
                if (msg == mLastRelevantPoll) {
                    if (DBG_POLL) log(
                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
                    mNeedsPoll = false;
                    mLastRelevantPoll = null;
                    handlePollCalls((AsyncResult)msg.obj);
                }
Update state, send call state change notifications, etc.:

     if (newRinging != null) {
            mPhone.notifyNewRingingConnection(newRinging);
         }
        updatePhoneState();
        if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected) {
            mPhone.notifyPreciseCallStateChanged();
        }
  • frameworks/opt/telephony – Phone
notifyNewRingingConnectionP方法:

    /**
     * Notify registrants of a new ringing Connection.
     * Subclasses of Phone probably want to replace this with a
     * version scoped to their packages
     */
    public void notifyNewRingingConnectionP(Connection cn) {
        if (!mIsVoiceCapable)
            return;
        AsyncResult ar = new AsyncResult(null, cn, null);
        mNewRingingConnectionRegistrants.notifyRegistrants(ar);
    }

Telephony

  • packages/service/Telephony – PstnIncomingCallNotifier

Find the registration registerForNewRingingConnection,

The message EVENT_NEW_RINGING_CONNECTION calls handleNewRingingConnection:

         mPhone.registerForNewRingingConnection(mHandler, EVENT_NEW_RINGING_CONNECTION, null);

         case EVENT_NEW_RINGING_CONNECTION:
               handleNewRingingConnection((AsyncResult) msg.obj);
               break;
Framework
  • frameworks/base/telecomm – TelecomManager

addNewIncomingCall方法

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 
 

  • packages/services/Telecom – TelecomServiceImpl
Find the place where the corresponding ITelecomService aidl is received, and view the addNewIncomingCall method:
  private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
   @Override
        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);        
  • packages/services/Telecom – CallIntentProcessor
    static void processIncomingCallIntent(CallsManager callsManager, Intent intent) {
        callsManager.processIncomingCallIntent(phoneAccountHandle, clientExtras);
    }
  • packages/services/Telecom – CallsManager
After the call is created, CreateConnection creates the link, and the subsequent process is similar to the outgoing process:

   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);
    }
  • packages/services/Telecom – Call
void startCreateConnection(PhoneAccountRegistrar phoneAccountRegistrar) {
    mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this,
            phoneAccountRegistrar, mContext);
    mCreateConnectionProcessor.process();
}
  • packages/services/Telecom – CreateConnectionProcessor
@VisibleForTesting
public void process() {
    Log.v(this, "process");
    clearTimeout();
    mAttemptRecords = new ArrayList<>();
    if (mCall.getTargetPhoneAccount() != null) {
        mAttemptRecords.add(new CallAttemptRecord(
                mCall.getTargetPhoneAccount (), mCall.getTargetPhoneAccount ()));
    }
    adjustAttemptsForConnectionManager();
    adjustAttemptsForEmergency();
    mAttemptRecordIterator = mAttemptRecords.iterator();
    attemptNextPhoneAccount();
}
  • packages/services/Telecom – ConnectionServiceWrapper   
mServiceInterface.createConnection(

        call.getConnectionManagerPhoneAccount(),
        callId,
        new ConnectionRequest(
                call.getTargetPhoneAccount(),
                call.getHandle(),
                extras,
                call.getVideoState(),
                callId),
        call.shouldAttachToExistingConnection(),
        call.isUnknown());

Frameworks

  • frameworks/base/telecomm -- ConnectionService

When calling out, onCreateOutgoingConnection is called. This article is calling in. You need to check onCreateIncomingConnection .

Connection connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
        : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
        : onCreateOutgoingConnection(callManagerAccount, request);
 
 Telecom 
 

  • packages/services/Telecom – Call
 public void handleCreateConnectionSuccess(
    switch (mCallDirection) {
        case CALL_DIRECTION_INCOMING:
            // Listeners (just CallsManager for now) will be responsible for checking whether
            // the call should be blocked.
            for (Listener l : mListeners) {
                l.onSuccessfulIncomingCall(this);
            }
            break;
  • packages/services/Telecom – CallsManager
@Override
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();
}

  • packages/services/Telecom – IncomingCallFilter

It mainly implements information about intercepting incoming calls, whether it is a blacklist, etc. This article does not focus on the process here:

public void performFiltering() {
    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()));
}
  • packages/services/Telecom – CallsManager
  • @Override
    public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result) {
           addCall(incomingCall);
       }
    private void addCall(Call call) {
        for (CallsManagerListener listener : mListeners) {
            listener.onCallAdded(call);}

  • packages/services/Telecom – InCallController

Similar to the inbound article, with the relevant code:

@Override
public void onCallAdded(Call call) {
    if (!isBoundToServices()) {
        bindToServices(call);
    } else {
        addCall(call);
        inCallService.addCall(parcelableCall);
}
Frameworks
  • frameworks/base/telecomm – InCallService

Implement the aidl method addCall and find the message MSG_ADD_CALL:

private final class InCallServiceBinder extends IInCallService.Stub {
    @Override
    public void setInCallAdapter(IInCallAdapter inCallAdapter) {
        mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget();
    }
    @Override
    public void addCall(ParcelableCall call) {
        mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget();
    }
    case MSG_ADD_CALL:
    mPhone.internalAddCall((ParcelableCall) msg.obj);
    break;


  • frameworks/base/telecomm -- Phone
final 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);
    }
}
  • frameworks/base/telecomm – InCallService
@Override
public void onCallAdded(Phone phone, Call call) {
    InCallService.this.onCallAdded(call);
}

Dialer

  • packages/app/Dialer -- InCallServiceImpl
@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);
    }
}
@Override
public void onIncomingCall(Call call) {
    InCallState newState = startOrFinishUi(InCallState.INCOMING);
    InCallState oldState = mInCallState;
    for (IncomingCallListener listener : mIncomingCallListeners) {
        listener.onIncomingCall(oldState, mInCallState, call);
    }
}
 
 

The above is the general process of 7.0 incoming calls. The next article will explain the incoming call UI display process.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324686302&siteId=291194637