我们先看下7.0来电大体流程:

Framework

modem接收到来电通知消息后,以AT指令的方式上报RIL层,RIL层通过sokcet将消息发送给RILJ, 上报事件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
    mCallStateRegistrants在BaseCommands中添加的观察者方法,在GsmCdmaCallTracker中注册了registerForCallStateChanged方法:
    @Overridepublic 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);

接着找到EVENT_CALL_STATE_CHANGE消息:

            case EVENT_CALL_STATE_CHANGE:pollCallsWhenSafe();break;
  • frameworks/opt/telephony – CallTracker
    找到GsmCdmaCallTracker父类的方法pollCallsWhenSafe:
    protected void pollCallsWhenSafe() {mNeedsPoll = true;if (checkNoOperationsPending()) {mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);mCi.getCurrentCalls(mLastRelevantPoll);}}
  • frameworks/opt/telephony – RIL
    找到CommandsInterface mCi,而其RIL implements CommandsInterface实现了getCurrentCalls方法,,携带消息
    EVENT_POLL_CALLS_RESULT:
    @Overridepublic 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
    和之前流程类似,接着进入handlePollCalls方法:
 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);}

更新状态,发送call state change通知等:

     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
    找到注册registerForNewRingingConnection处,
    消息EVENT_NEW_RINGING_CONNECTION调用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
    找到对应的ITelecomServic aidl接收的地方,查看addNewIncomingCall方法:
  private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {@Overridepublic 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
    创建call之后,CreateConnection创建链接,之后的流程和呼出流程类似:
   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
    呼出时是调用onCreateOutgoingConnection,此篇是呼入,需要查看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
    主要执行关于拦截来电的,是否是黑名单等信息,此篇不关注此处流程:
public void performFiltering() {mHandler.postDelayed(new Runnable("ICF.pFTO") { // performFiltering time-out@Overridepublic 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
   @Overridepublic void onCallFilteringComplete(Call incomingCall, CallFilteringResult result) {addCall(incomingCall);}
    private void addCall(Call call) {for (CallsManagerListener listener : mListeners) {listener.onCallAdded(call);}
  • packages/services/Telecom – InCallController
    和呼入篇类似,附相关代码:
@Override
public void onCallAdded(Call call) {if (!isBoundToServices()) {bindToServices(call);} else {addCall(call);inCallService.addCall(parcelableCall);
}

Frameworks

  • frameworks/base/telecomm – InCallService
    实现aidl方法addCall,找到消息MSG_ADD_CALL:
private final class InCallServiceBinder extends IInCallService.Stub {@Overridepublic void setInCallAdapter(IInCallAdapter inCallAdapter) {mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget();}
    @Overridepublic 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);}
}

android Telephony学习 --- 第七篇 android7.0 来电(MT)流程相关推荐

  1. 【Android Studio学习】第二篇、APP实现画简易的波形图

    目录 第一部分.前言 1.效果展示 2.参考博客 3.实现方式 第二部分.详细步骤 1.添加波形函数的依赖 2.添加一个管理类 3.修改activity_main.xml文件的代码 4.修改MainA ...

  2. android 做分享到朋友圈,android7.0实现分享图片到朋友圈功能

    android7.0实现分享图片到朋友圈功能 发布时间:2020-08-29 00:46:50 来源:脚本之家 阅读:132 作者:十个雨点 本文实例为大家分享了android实现分享图片到朋友圈功能 ...

  3. Android中获取系统语言(适用于Android7.0以上系统)

    2019独角兽企业重金招聘Python工程师标准>>> public static String getSysLang(Context context) {Locale locale ...

  4. Android7.0 Rild工作流程

    点击打开链接 一.基于Rild的通信架构 一般智能手机的硬件架构都是两个处理器:  一个处理器用来运行操作系统,上面运行应用程序,这个处理器称作Application Processor,简称AP:另 ...

  5. android Telephony学习 --- 第九篇 USSD简介

    USSD在国内并不常用,但是海外某些地区还在使用,本人对此理解有限,仅简要介绍下USSD是什么,功能是什么等基本知识,希望可以帮助了解此功能. USSD全称是什么? USSD功能是什么? USSD格式 ...

  6. 【Android Studio学习】第一篇、制作一个拥有登录和注册功能的简易APP

    目录 第一部分.前言 1.目标效果 2.准备知识 第二部分.详细步骤 1.新建Empty工程 ​2.添加资源文件 3.搭建注册界面 4.搭建登录界面 5.编写注册界面和登录界面的代码 6.设置APP初 ...

  7. Android 框架学习1:EventBus 3.0 的特点与如何使用

    前面总结了几篇基础,在这过程中看着别人分享自定义 View.架构或者源码分析,看起来比我写的"高大上"多了,内心也有点小波动. 但是自己的水平自己清楚,基础不扎实画再多源码流程图也 ...

  8. android在哪存储当前用户名和密码,Android实战教程第七篇之如何在内存中存储用户名和密码...

    本文实例为大家分享了Android内存中存储用户名和密码的方法,供大家参考,具体内容如下 首先是配置文件: xmlns:tools="http://schemas.android.com/t ...

  9. Android JNI入门第七篇——C调用Java

    关键代码: java: [java] view plaincopy print? public class CCallJava { public static String getTime() { L ...

最新文章

  1. 胜者树和败者树 - qianye0905 - 博客园
  2. uwsgi 参数解释
  3. Spring-Bean依赖注入(引用数据类型和集合数据类型)
  4. 20145315 《Java程序设计》第五周学习总结
  5. Ios 被拒出现3.1.1
  6. python 数据结构 1
  7. vue读取外部配置文件
  8. lesson 6 threads synchronization
  9. OTSU 获取最佳阈值,及opencv二值化
  10. 城市应急管理系统技术方案
  11. GODOT游戏编程001
  12. 2017年油价调整时间表
  13. 利用python识别身份证号后获取年龄和性别信息
  14. 做业务的程序猿如何提升技能?
  15. 大数据高级开发工程师——Spark学习笔记(4)
  16. Typora:Typora快捷键
  17. linux软件管理及软件仓库
  18. 怎么进DMM日服DMM怎么看DMM小视频
  19. TabIndex是干什么滴
  20. JPA操作数据库中的脏数据更新作用

热门文章

  1. Linux 套接字编程基础
  2. ZBrush 4R7中自定义笔刷
  3. 网络安全面试-网络方面
  4. 富人父母都教给孩子什么样的财富思维?
  5. php pusher,php – Pusher没有接收来自Laravel 5.2广播的事件
  6. 当代中国人的新十大傻
  7. echarts人口密度图全解
  8. STM8S系列基于IAR开发单通道ADC连续采样示例
  9. 浮点型什么时候用Float,什么时候用Double
  10. 小白给小白详解维特比算法(一)