Android Telephony分析(三) ---- RILJ详解
前言
本文主要講解RILJ工作原理,以便更好地分析代碼,分析業務的流程。?
這里說的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\Android\internal\telephony) ,?
RILC指的是Ril.cpp (hardware\ril\libril)
1. RILJ的創建
RILJ的繼承關系如下:?
可以看到RILJ繼承自BaseCommands并且實現了CommandsInterface接口,RILJ中有兩個子線程RILSender和RILReceiver。?
再看看RILJ的構造函數:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
在RILJ初始化的時候,啟動了RILSender線程用于發送數據,啟動了RILReceiver線程用于接收數據。?
在《Android Telephony分析(一) — Phone詳解 》的第二小節中曾經說到,在創建Phone實例之前會先創建RILJ,一個Phone實例對應一個RILJ實例。?
在CallTracker.java、Phone.java、ServiceStateTracker.java我們常常看到的
- 1
- 1
mCi對象都是RILJ實例。
本文來自http://blog.csdn.net/linyongan?,轉載請務必注明出處。
2. RILJ的工作原理
RILJ、RILC、Modem的工作流程:
RILJRILJRILCRILCModemModem發送Request發送RequestModem處理solicited/unSolicited Responsesolicited/unSolicited Response RILJ里有RILSender線程用于向RILC發送數據和RILReceiver用于接收來自RILC的數據,但是這些數據的發送和接收是一個異步的過程。?
結合同步,才能更好地理解異步:
同步:發送方發出數據后,等接收方發回響應以后才發下一個數據包。?
異步:發送方發出數據后,不等接收方發回響應,接著發送下個數據包。
理解這個概念之后,我們再去分析代碼,我們就以打電話為例吧。
2.1 RILSender發送Request
前面的撥號流程省略,我們直接從GsmCdmaCallTracker.java的dial()方法開始分析:
public synchronized Connection dial(String dialString, int clirMode, UUSInfo uusInfo,Bundle intentExtras)throws CallStateException {...//先通過obtainCompleteMessage方法得到一個MessagemCi.dial(mPendingMO.getAddress(), clirMode, uusInfo, obtainCompleteMessage());...}private MessageobtainCompleteMessage() {//該消息類型是EVENT_OPERATION_COMPLETEreturn obtainCompleteMessage(EVENT_OPERATION_COMPLETE);}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
在調用RILJ的方法發起撥號請求之前,先創建一個Message對象,這個Message對象主要用于,當RILJ發起撥號請求,modem返回消息之后,RILJ再通過Message.sendToTarget,這樣回調就可以通知GsmCdmaCallTracker,后文2.2.1小節會詳細講。?
接著在RILJ中:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
就這樣,整個主動向RILC發出請求的流程就將完了。
2.2 RILReceiver接收Response
在RILReceiver線程中
class RILReceiver implements Runnable {@Overridepublic voidrun() {...... processResponse(p);......}}private voidprocessResponse (Parcel p) {int type;type = p.readInt();//對上報的消息分類處理if (type == RESPONSE_UNSOLICITED || type == RESPONSE_UNSOLICITED_ACK_EXP) {//對modem主動上報消息的處理processUnsolicited (p, type);} else if (type == RESPONSE_SOLICITED || type == RESPONSE_SOLICITED_ACK_EXP) { //對之前RILJ發出的Request的回應消息的處理RILRequest rr = processSolicited (p, type);if (rr != null) {if (type == RESPONSE_SOLICITED) {decrementWakeLock(rr);}rr.release();}}}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
RILC上報給RILJ的消息可以分成兩類:?
1. Solicited Response—>對之前RILJ發出的Request進行回應的消息。(一個Request對應一個Response)?
2. UnSolicited Response—>modem主動上報的消息。(單方向,由RILC發給RILJ)
2.2.1 處理Solicited Response
繼續上面撥號的例子,在RILJ發起撥號請求后,modem處理完之后,返回消息給RILC,最后通知到RILJ。
private RILRequestprocessSolicited (Parcel p, int type) {RILRequest rr; //把RILRequest對象從mRequestList列表中取出來rr = findAndRemoveRequestFromList(serial); //省略對數據的處理.....//輸出標志性log,"< "代表RILC向RILJ反饋信息。if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)+ " " + retToString(rr.mRequest, ret));if (rr.mResult != null) { AsyncResult.forMessage(rr.mResult, ret, null); //是否還記得上面2.1小節中說到rr.mResult存儲的是什么對象嗎?//這就是在調用RILJ的dial方法前創建的Message對象!//Message.sendToTarget,這樣通過回調,流程就回到調用RILJ的dial方法的地方了。rr.mResult.sendToTarget(); } return rr; }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
2.2.2 處理Solicited Response
這里以撥打電話后,modem上報call的狀態變化消息RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED為例
private voidprocessUnsolicited (Parcel p, int type) {int response; Object ret; //讀取當前上報消息的號碼 response = p.readInt(); //根據號碼找到相應的邏輯處理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);//【重點】通過RegistrantList機制,繼續上報消息mCallStateRegistrants.notifyRegistrants(new AsyncResult(null, null, null));break;}} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
關于RegistrantList機制,請看上一篇文章《Android Telephony分析(二) —- RegistrantList詳解》?
接著會通知到注冊監聽Call狀態變化的人:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
最終會在GsmCdmaCallTracker的handleMessage方法中對EVENT_CALL_STATE_CHANGE進行處理。?
modem主動上報消息的流程也講解完了。
3 .學以致用
學習完本篇博客的知識,怎么去分析調用RILJ的方法主動發起Request的流程和modem主動上報消息的流程呢??
這里還是以第二小節撥號的代碼為例,其他業務流程都可以舉一反三。?
1.主動發起Request這類代碼流程,核心是誰創建Message,之后還是誰對該Message進行處理。
2.modem主動上報消息這類代碼流程,核心是誰注冊監聽了這個消息,那么還是誰對該消息進行處理。
GsmCdmaCallTrackerGsmCdmaCallTrackerRILJRILJModemModemregisterForCallStateChanged()Call狀態變化processUnsolicited()mCallStateRegistrants.notifyRegistrants()handleMessage()最后可以通過log中的“>”和“<”判斷消息的方向。
D/RILJ ( 2795): [5655]> DIAL D/RILJ ( 2795): [5655]< DIAL- 1
- 2
- 1
- 2
“>”:是RILJ發請求給modem。?
“<”:是modem上報消息給RILJ。
原文地址:http://blog.csdn.net/linyongan/article/details/52066306
總結
以上是生活随笔為你收集整理的Android Telephony分析(三) ---- RILJ详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Telephony分析(
- 下一篇: Android Telephony分析(