androoid framework学习之 - Telephony 来电流程
来源:互联网 发布:微信软件开发 编辑:程序博客网 时间:2024/04/30 00:11
androoid framework学习之 - Telephony 来电流程
今天顺了一下来电的整个流程,从RIL开始捋一捋:
1.在RIL.java中:当moderm有新信息通过Socket发送过来时,RIL Receive会接收到,然后跑processResponse。
class RILReceiver implements Runnable { byte[] buffer; RILReceiver() { buffer = new byte[RIL_MAX_COMMAND_BYTES]; } @Override public void run() { int retryCount = 0; String rilSocket = "rild";//循环处理rild传递来的事件 try {for (;;) { LocalSocket s = null; LocalSocketAddress l; if (mInstanceId == null || mInstanceId == 0 ) { rilSocket = SOCKET_NAME_RIL[0]; } else { rilSocket = SOCKET_NAME_RIL[mInstanceId]; } try {//创建于rild通信的socket 建立连接 s = new LocalSocket(); l = new LocalSocketAddress(rilSocket, LocalSocketAddress.Namespace.RESERVED); s.connect(l); } catch (IOException ex){ try { if (s != null) { s.close(); } } catch (IOException ex2) { //ignore failure to close after failure to connect } // don't print an error message after the the first time // or after the 8th time if (retryCount == 8) { Rlog.e (RILJ_LOG_TAG, "Couldn't find '" + rilSocket + "' socket after " + retryCount + " times, continuing to retry silently"); } else if (retryCount >= 0 && retryCount < 8) { Rlog.i (RILJ_LOG_TAG, "Couldn't find '" + rilSocket + "' socket; retrying after timeout"); } try { Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); } catch (InterruptedException er) { } retryCount++; continue; } retryCount = 0; mSocket = s; Rlog.i(RILJ_LOG_TAG, "(" + mInstanceId + ") Connected to '" + rilSocket + "' socket"); int length = 0; try { //读取socket数据 InputStream is = mSocket.getInputStream(); for (;;) {//解析数据 Parcel p; length = readRilMessage(is, buffer); if (length < 0) { // End-of-stream reached break; } p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0); //Rlog.v(RILJ_LOG_TAG, "Read packet: " + length + " bytes"); //处理rild传递来的消息 processResponse(p); p.recycle(); } } catch (java.io.IOException ex) { Rlog.i(RILJ_LOG_TAG, "'" + rilSocket + "' socket closed", ex); } catch (Throwable tr) { Rlog.e(RILJ_LOG_TAG, "Uncaught exception read length=" + length + "Exception:" + tr.toString()); } Rlog.i(RILJ_LOG_TAG, "(" + mInstanceId + ") Disconnected from '" + rilSocket + "' socket");//无法读取数据,将CP状态设置为不可用 setRadioState (RadioState.RADIO_UNAVAILABLE); try { mSocket.close(); } catch (IOException ex) { } mSocket = null; RILRequest.resetSerial(); // Clear request list on close clearRequestList(RADIO_NOT_AVAILABLE, false); }} catch (Throwable tr) { Rlog.e(RILJ_LOG_TAG,"Uncaught exception", tr); } /* We're disconnected so we don't know the ril version */ notifyRegistrantsRilConnectionChanged(-1); } }
private void processResponse (Parcel p) { int type; type = p.readInt();//新事件Or send事件response if (type == RESPONSE_UNSOLICITED) { processUnsolicited (p);//新事件 } else if (type == RESPONSE_SOLICITED) { RILRequest rr = processSolicited (p);//command的返回 if (rr != null) { rr.release(); decrementWakeLock(); } } }
那这里是如果是新来电的话,就是新事件,会执行processUnsolicited:
private void processUnsolicited (Parcel p) { int response; Object ret; response = p.readInt(); try {switch(response) { //来电 ................... case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break; case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break; case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break; case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break;...................................... switch(response) { case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: /* has bonus radio state int */ RadioState newState = getRadioStateFromInt(p.readInt()); if (RILJ_LOGD) unsljLogMore(response, newState.toString()); switchToRadioState(newState); break; case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: if (RILJ_LOGD) unsljLog(response); mImsNetworkStateChangedRegistrants .notifyRegistrants(new AsyncResult(null, null, null)); break; case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: if (RILJ_LOGD) unsljLog(response); mCallStateRegistrants .notifyRegistrants(new AsyncResult(null, null, null)); break;.............................}
public void notifyRegistrant(AsyncResult ar) { internalNotifyRegistrant (ar.result, ar.exception); }
/*package*/ void internalNotifyRegistrant (Object result, Throwable exception) { Handler h = getHandler(); if (h == null) { clear(); } else { Message msg = Message.obtain(); msg.what = what; msg.obj = new AsyncResult(userObj, result, exception); h.sendMessage(msg); } }
那这里sengMessage发到哪里呢?
在CallstateNotifier里面有如下注册:
// Events generated internally: public CallStateMonitor(CallManager callManager) { this.callManager = callManager; registeredHandlers = new ArrayList<Handler>(); registerForNotifications(); } /** * Register for call state notifications with the CallManager. */ private void registerForNotifications() { // // TODO: The lines commented out here can be removed as their associated functionality in // other files is removed. // callManager.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null); //callManager.registerForPreciseCallStateChanged(this, PHONE_STATE_CHANGED, null); //callManager.registerForDisconnect(this, PHONE_DISCONNECT, null); //callManager.registerForUnknownConnection(this, PHONE_UNKNOWN_CONNECTION_APPEARED, null); callManager.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null); //callManager.registerForCallWaiting(this, PHONE_CDMA_CALL_WAITING, null); callManager.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null);
那在上面send的内容是CallStateMonitor.PHONE_NEW_RINGING_CONNECTION,搜索这个,
在CallNotifier.java里面:
@Override public void handleMessage(Message msg) { switch (msg.what) { case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION://这个就是从callStateNotifer来的 log("RINGING... (new)"); isForbidden = false; // Add to check the firewall when firewall provider is built. final ContentResolver cr = mApplication.getContentResolver(); if (cr.acquireProvider(FIREWALL_PROVIDER_URI) != null) { AsyncResult r = (AsyncResult) msg.obj; Connection c = (Connection) r.result; if (c != null && c.isRinging() && c.getCall() != null) { Phone phone = c.getCall().getPhone(); String number = c.getAddress(); int subscription = phone.getSubId(); Bundle extras = new Bundle(); extras.putInt(PhoneConstants.SUBSCRIPTION_KEY, subscription); extras.putString(EXTRA_NUMBER, number); extras = cr.call(FIREWALL_PROVIDER_URI, IS_FORBIDDEN, null, extras); if (extras != null) { isForbidden= extras.getBoolean(IS_FORBIDDEN); if (isForbidden) { PhoneUtils.hangupRingingCall(c.getCall()); return; } } } } onNewRingingConnection((AsyncResult) msg.obj); break; case CallStateMonitor.PHONE_STATE_CHANGED: onPhoneStateChanged((AsyncResult) msg.obj); break; case CallStateMonitor.PHONE_DISCONNECT: if (DBG) log("DISCONNECT"); onDisconnect((AsyncResult) msg.obj); break;
这边就分析到这里了。
0 0
- androoid framework学习之 - Telephony 来电流程
- androoid framework学习之 - Telephony 流程
- androoid framework学习之Service组件
- androoid framework学习之BroadCast组件
- androoid framework学习之activity组件
- androoid framework学习之 - ContextMenu上下文菜单
- androoid framework学习之 - 选项菜单OptionsMenu
- androoid framework学习之 - 开启数据开关
- androoid framework学习之 - RILd相关介绍
- androoid framework学习之Settings的主界面的代码流程分析
- androoid framework学习之 - RILd启动过程和如何接收framwork层的消息流程
- androoid framework学习之 - RILd启动过程和如何接收framwork层的消息流程(二)
- androoid framework学习之ContentProvider组件(很不错)
- androoid framework学习之 - SubMenu创建选项菜单
- androoid framework学习之 - InCallUI中CallButton界面更新介绍(audioButton等)
- telephony framework通话状态维护流程
- Android4.4 Telephony流程分析——来电(MT)流程
- androoid makefile 学习
- 讯投贵金属相关逻辑整理
- 给我们好评---跳转到应用市场
- java之maven
- 仿京东收货地址
- 欢迎使用CSDN-markdown编辑器
- androoid framework学习之 - Telephony 来电流程
- linux 进程间通信之mmap
- Centos6.5 安装启动Nginx
- Javascript设置定时请求
- 关闭Listview的setFilterText() 出现的弹出对话框
- 关于安卓工程导出带res资源文件的jar的总结
- Jvisualvm是JDK自带的一款性能分析工具
- 配置eclipse通过JDBC连接SQl Server 2008R2数据库
- SQL——创建、管理表(DDL语句)