Android Phone模块 三

来源:互联网 发布:wind软件使用 编辑:程序博客网 时间:2024/05/21 02:50

RIL


public RIL(Context context, int preferredNetworkType, int cdmaSubscription,int phoneId) {super(context);mCdmaSubscription = cdmaSubscription;mPreferredNetworkType = preferredNetworkType;mPhoneType = RILConstants.NO_PHONE;mPhoneId = phoneId;if (mPhoneId != PhoneFactory.DEFAULT_PHONE_ID) {SOCKET_NAME_RIL = SOCKET_NAME_RIL + phoneId;}PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);mWakeLock.setReferenceCounted(false);mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,DEFAULT_WAKE_LOCK_TIMEOUT);mRequestMessagesPending = 0;mRequestMessagesWaiting = 0;//创建ril发送线程mSenderThread = new HandlerThread("RILSender");mSenderThread.start();Looper looper = mSenderThread.getLooper();mSender = new RILSender(looper);ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {riljLog("Not starting RILReceiver: wifi-only");} else {riljLog("Starting RILReceiver");//创建接收线程mReceiver = new RILReceiver();mReceiverThread = new Thread(mReceiver, "RILReceiver");mReceiverThread.start();IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_SCREEN_ON);filter.addAction(Intent.ACTION_SCREEN_OFF);context.registerReceiver(mIntentReceiver, filter);}}
RIL线程模型:

RILSender

当上层需要向rild服务发送请求时,通过RIL的send函数来完成。
public void handleMessage(Message msg) {RILRequest rr = (RILRequest) (msg.obj);RILRequest req = null;switch (msg.what) {case EVENT_SEND:boolean alreadySubtracted = false;try {LocalSocket s;s = mSocket;if (s == null) {rr.onError(RADIO_NOT_AVAILABLE, null);rr.release();if (mRequestMessagesPending > 0)mRequestMessagesPending--;alreadySubtracted = true;return;}synchronized (mRequestsList) {mRequestsList.add(rr);mRequestMessagesWaiting++;}if (mRequestMessagesPending > 0)mRequestMessagesPending--;alreadySubtracted = true;byte[] data;data = rr.mp.marshall();rr.mp.recycle();rr.mp = null;if (data.length > RIL_MAX_COMMAND_BYTES) {throw new RuntimeException("Parcel larger than max bytes allowed! "+ data.length);}// parcel length in big endiandataLength[0] = dataLength[1] = 0;dataLength[2] = (byte) ((data.length >> 8) & 0xff);dataLength[3] = (byte) ((data.length) & 0xff);s.getOutputStream().write(dataLength);s.getOutputStream().write(data);} catch (IOException ex) {Log.e(LOG_TAG, "IOException", ex);req = findAndRemoveRequestFromList(rr.mSerial);if (req != null || !alreadySubtracted) {rr.onError(RADIO_NOT_AVAILABLE, null);rr.release();}} catch (RuntimeException exc) {Log.e(LOG_TAG, "Uncaught exception ", exc);req = findAndRemoveRequestFromList(rr.mSerial);if (req != null || !alreadySubtracted) {rr.onError(GENERIC_FAILURE, null);rr.release();}} finally {releaseWakeLockIfDone();}if (!alreadySubtracted && mRequestMessagesPending > 0) {mRequestMessagesPending--;}break;case EVENT_WAKE_LOCK_TIMEOUT:synchronized (mWakeLock) {if (mWakeLock.isHeld()) {if (mRequestMessagesWaiting != 0) {mRequestMessagesWaiting = 0;}if (mRequestMessagesPending != 0) {mRequestMessagesPending = 0;}mWakeLock.release();}}break;}}

写入rild套接字的数据为:


发送步骤:

1.        生成RILRequest,此时将生成m_Serial(请求的Token)并将请求号,数据,及其Result Message 对象填入到RILRequest中

2.        使用send将RILRequest打包到EVENT_SEND消息中发送到到RIL Sender Handler

3.        RilSender 接收到EVENT_SEND消息,将RILRequest通过套接口发送到RILD,同时将RILRequest保存在mRequest中以便应答消息的返回。

RILReceiver


public void run() {int retryCount = 0;try {for (;;) {LocalSocket s = null;LocalSocketAddress l;try {//创建socket并连接到rilds = new LocalSocket();l = new LocalSocketAddress(SOCKET_NAME_RIL,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}if (retryCount == 8) {Log.e(LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL+ "' socket after " + retryCount+ " times, continuing to retry silently");} else if (retryCount > 0 && retryCount < 8) {Log.i(LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL+ "' socket; retrying after timeout");}try {Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);} catch (InterruptedException er) {}retryCount++;continue;}retryCount = 0;mSocket = s;Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");int length = 0;try {InputStream is = mSocket.getInputStream();//循环从socket中读取消息for (;;) {Parcel p;length = readRilMessage(is, buffer);if (length < 0) {break;}p = Parcel.obtain();p.unmarshall(buffer, 0, length);p.setDataPosition(0);processResponse(p);p.recycle();}} catch (java.io.IOException ex) {Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",ex);} catch (Throwable tr) {Log.e(LOG_TAG, "Uncaught exception read length=" + length+ "Exception:" + tr.toString());}//socket连接断开,请求所有请求并重新连接Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL+ "' socket");setRadioState(RadioState.RADIO_UNAVAILABLE);try {mSocket.close();} catch (IOException ex) {}mSocket = null;RILRequest.resetSerial();clearRequestsList(RADIO_NOT_AVAILABLE, false);}} catch (Throwable tr) {Log.e(LOG_TAG, "Uncaught exception", tr);}notifyRegistrantsRilConnectionChanged(-1);}

接收步骤

1.        分析接收到的Parcel,根据类型不同进行处理。

2.        根据数据中的Token(mSerail),反查mRequest,找到对应的请求信息。

3.        将是接收到的数据转换成结果数据。

4.        将结果放在RequestMessage中发回到请求的发起者。