Framework層Ril控制流程分析
RIL Native層分析:http://www.cnblogs.com/bastard/archive/2012/11/05/2754891.html
一 RIL整體框架
看一下整個RIL部分框架圖:
實際上Framework部分比較復雜的,包含了很多類;但其核心的兩個類是GSMPhone/,RIL.Java.
還包括圍繞這兩個類構成的狀態管理,命令交互的類。
二 PhoneApp 啟動過程
在AndroidManifest.xml文件中:
<application android:name="PhoneApp"
android:persistent="true"
……
在開機啟動時到ActivityManagerService的systemReady時,會將帶有這個屬性的App啟動。
調用應用的Application——PhoneApp:
public class PhoneApp extends Application { @Override public void onCreate() { //初始化framework層telephony相關
PhoneFactory.makeDefaultPhones(this); Phone phone = PhoneFactory.getDefaultPhone(); CallManager mCM = CallManager.getInstance(); mCM.registerPhone(phone); } }
PhoneFactory初始化Framework層相關對象:
public static void makeDefaultPhone(Context context) { sPhoneNotifier = new DefaultPhoneNotifier(); //創建CommandsInterface實例RIL
sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); // Instantiate UiccController so that all other classes can just call getInstance()
UiccController.make(context, sCommandsInterface); //根據類型創建Phone實例
int phoneType = getPhoneType(networkMode); //創建Phone實例GSMPhone 以及代理對象ProxyPhone
sProxyPhone = new PhoneProxy(new GSMPhone(context, sCommandsInterface, sPhoneNotifier)); }
這個sCommandsInterface很關鍵 是連接GSMPhone與RIL。
整個Framewrok Telephony中很關鍵的就是Phone和CommandInterface兩個接口:
核心就是圍繞這兩個接口派生的類;還有各種對Phone進行了包裝的類。
Phone:Internal interface used to control the phone;
CommandInterface:提供跟native層Ril交互的接口發送命令和接受命令,注冊狀態傳遞回調接口,向上層傳遞狀態變化。
下面是這幾個核心類的結構圖:
三 命令控制流程
命令從Phone開始,在傳遞到RIL,在通過Socket傳遞給Rild。下面看一下framework中RIL類工作流程。
與Native端交互過程:
RIL提供了call和connection過程命令接口,狀態變化回調,unsolicited事件通知。
類結構圖:
其中關鍵的兩個線程:sender和receiver ,運行單獨的線程中處理向下和向上的請求。
RIL構造函數:
public RIL(Context context, ……) { //創建sender運行線程
mSenderThread = new HandlerThread("RILSender"); mSenderThread.start(); //send消息處理循環
Looper looper = mSenderThread.getLooper(); mSender = new RILSender(looper); //建立receiver運行的線程
mReceiver = new RILReceiver(); mReceiverThread = new Thread(mReceiver, "RILReceiver"); mReceiverThread.start(); }
1 send事件流程
dial撥號流程:
public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) { //獲取一個RILRequest對象 請求對象類型
RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); //將數據打包成parcel
rr.mp.writeString(address); rr.mp.writeInt(clirMode); rr.mp.writeInt(0); // UUS information is absent
…… //將數據發送到send線程中處理 內部公共接口send
send(rr); } private void send(RILRequest rr) { //Handler異步處理消息
msg = mSender.obtainMessage(EVENT_SEND, rr); msg.sendToTarget(); }
Send消息處理過程:
class RILSender extends Handler implements Runnable { public RILSender(Looper looper) { super(looper); } // Only allocated once
byte[] dataLength = new byte[4]; public void run() { //setup if needed
} handleMessage(Message msg) { RILRequest rr = (RILRequest)(msg.obj); RILRequest req = null; switch (msg.what) { case EVENT_SEND: //與rild通信socket
LocalSocket s; s = mSocket; //加入請求隊列
synchronized (mRequestsList) { mRequestsList.add(rr); mRequestMessagesWaiting++; } byte[] data; data = rr.mp.marshall(); //將將數據通過socket傳入到rild進程中
s.getOutputStream().write(dataLength); s.getOutputStream().write(data); break; } } }
在send線程中將數據通過socket傳遞給rild進程處理。
2 receive事件流程
Receiver接收rild發送來的事件以及send事件的response事件:
class RILReceiver implements Runnable { byte[] buffer; RILReceiver() { buffer = new byte[RIL_MAX_COMMAND_BYTES]; } public void run() { String rilSocket = "rild"; //循環處理rild傳遞來的事件
for (;;) { //創建於rild通信的socket 建立連接
s = new LocalSocket(); l = new LocalSocketAddress(rilSocket, LocalSocketAddress.Namespace.RESERVED); s.connect(l); mSocket = s; //讀取socket數據
InputStream is = mSocket.getInputStream(); for (;;) { //解析數據
Parcel p; length = readRilMessage(is, buffer); p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0); //處理rild傳遞來的消息
processResponse(p); } setRadioState (RadioState.RADIO_UNAVAILABLE); mSocket.close(); // Clear request list on close
clearRequestsList(RADIO_NOT_AVAILABLE, false); } } } private void processResponse (Parcel p) { type = p.readInt(); //新事件Or send事件response
if (type == RESPONSE_UNSOLICITED) { processUnsolicited (p); } else if (type == RESPONSE_SOLICITED) { processSolicited (p); } }
網絡端事件處理流程:
private void processUnsolicited (Parcel p) { Object ret; int response = p.readInt(); switch(response) { //來電
case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break; …… } switch(response) { case RIL_UNSOL_CALL_RING: //通知注冊來電事件的register
if (mRingRegistrant != null) { mRingRegistrant.notifyRegistrant( new AsyncResult (null, ret, null)); } break; …… } }
3 receiver事件通知register機制
對事件狀態的注冊是在RIL的父類BaseCommands完成的。
BaseCommands類注冊事件的實現:
public abstract class BaseCommands implements CommandsInterface { //注冊到列表中
protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList(); protected RegistrantList mCallStateRegistrants = new RegistrantList(); protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList(); …… //注冊某一事件發生
protected Registrant mRingRegistrant; protected Registrant mSmsStatusRegistrant; protected Registrant mRestrictedStateRegistrant; …… //注冊接口
public void registerForRadioStateChanged(Handler h, int what, Object obj) { Registrant r = new Registrant (h, what, obj); synchronized (mStateMonitor) { mRadioStateChangedRegistrants.add(r); r.notifyRegistrant(); } } //注冊回調
public void setOnCallRing(Handler h, int what, Object obj) { mRingRegistrant = new Registrant (h, what, obj); } }
這里有RegistrantList與Registrant類,注冊事件以Registrant對象存儲;
下面是Registrant類得主要成員:
public class Registrant{ WeakReference refH; int what; Object userObj; public Registrant(Handler h, int what, Object obj){ refH = new WeakReference(h); this.what = what; userObj = obj; } public void notifyRegistrant(){ internalNotifyRegistrant (null, null); } void internalNotifyRegistrant (Object result, Throwable exception){ //通過Handler傳遞消息
Handler h = getHandler(); Message msg = Message.obtain(); msg.what = what; msg.obj = new AsyncResult(userObj, result, exception); h.sendMessage(msg); } }
這里說直接使用Handler,來實現了一個Observer模式,但是Handler是處理線程的框架類,實現異步的處理消息,具有更強的功能。
所以看到Telephony中很多類都是從Handler繼承下來的,就是為了監聽事件發生,狀態變化等消息。