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 endian
dataLength[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并连接到rild
s = 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中发回到请求的发起者。