RIL短信接收和发送流程分析最新版android.docx
《RIL短信接收和发送流程分析最新版android.docx》由会员分享,可在线阅读,更多相关《RIL短信接收和发送流程分析最新版android.docx(46页珍藏版)》请在冰豆网上搜索。
RIL短信接收和发送流程分析最新版android
(RIL)短信接收和发送流程分析最新版(android)
参考网站:
为了能更好的了解android接收短信的流程,我进行了更深入的分析,从RIL的通信架构来分析当接收到短信的整个流程。
从frameword里的RIL.java
(观察360的短信拦截和QQ管家的短信拦截,发现先安装的就能先拦截到的短信,然后中断广播,之后谁都不能获取到短信。
从这里可以推出系统大概有一个广播表,同等级的按安装先后顺序排放。
目前的方法是在应用层调用frameworkAPI进行控制的)
文件可以看出发送短信和接收短信是通过Receiver和Sender架构,发送短信主要通过Sender框架,主要如下(图是从网上窃滴~):
上层函数调用CommandInterface将请求消息发送到sender架构,由该架构将请求发送到RILD的架构。
补充发送的子类
classRILSenderextendsHandlerimplementsRunnable{
publicRILSender(Looperlooper){
super(looper);
}
//Onlyallocatedonce
byte[]dataLength=newbyte[4];
//*****Runnableimplementation
publicvoid
run(){
//setupifneeded
}
//*****Handlerimplementation
@Overridepublicvoid
handleMessage(Messagemsg){
RILRequestrr=(RILRequest)(msg.obj);
RILRequestreq=null;
switch(msg.what){
caseEVENT_SEND:
/**
*mRequestMessagePending++alreadyhappenedforevery
*EVENT_SEND,thuswemustmakesure
*mRequestMessagePending--happensonceandonlyonce
*/
booleanalreadySubtracted=false;
try{
LocalSockets;
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){
thrownewRuntimeException(
"Parcellargerthanmaxbytesallowed!
"
+data.length);
}
//parcellengthinbigendian
dataLength[0]=dataLength[1]=0;
dataLength[2]=(byte)((data.length>>8)&0xff);
dataLength[3]=(byte)((data.length)&0xff);
//Log.v(LOG_TAG,"writingpacket:
"+data.length+"bytes");
s.getOutputStream().write(dataLength);
s.getOutputStream().write(data);
}catch(IOExceptionex){
Log.e(LOG_TAG,"IOException",ex);
req=findAndRemoveRequestFromList(rr.mSerial);
//makesurethisrequesthasnotalreadybeenhandled,
//eg,ifRILReceiverclearedthelist.
if(req!
=null||!
alreadySubtracted){
rr.onError(RADIO_NOT_AVAILABLE,null);
rr.release();
}
}catch(RuntimeExceptionexc){
Log.e(LOG_TAG,"Uncaughtexception",exc);
req=findAndRemoveRequestFromList(rr.mSerial);
//makesurethisrequesthasnotalreadybeenhandled,
//eg,ifRILReceiverclearedthelist.
if(req!
=null||!
alreadySubtracted){
rr.onError(GENERIC_FAILURE,null);
rr.release();
}
}finally{
//Note:
Weare"Done"onlyiftherearenooutstanding
//requestsorreplies.Thusthiscodepathwillonlyrelease
//thewakelockonerrors.
releaseWakeLockIfDone();
}
if(!
alreadySubtracted&&mRequestMessagesPending>0){
mRequestMessagesPending--;
}
break;
caseEVENT_WAKE_LOCK_TIMEOUT:
//Haven'theardbackfromthelastrequest.Assumewe're
//notgettingaresponseandreleasethewakelock.
synchronized(mWakeLock){
if(mWakeLock.isHeld()){
//ThetimerofWAKE_LOCK_TIMEOUTisresetwitheach
//newsendrequest.SowhenWAKE_LOCK_TIMEOUToccurs
//allrequestsinmRequestListalreadywaitedat
//leastDEFAULT_WAKE_LOCK_TIMEOUTbutnoresponse.
//ResetmRequestMessagesWaitingtoenable
//releaseWakeLockIfDone().
//
//Note:
KeepmRequestListsothatdelayedresponse
//canstillbehandledwhenresponsefinallycomes.
if(mRequestMessagesWaiting!
=0){
Log.d(LOG_TAG,"NOTE:
mReqWaitingisNOT0but"
+mRequestMessagesWaiting+"atTIMEOUT,reset!
"
+"Therestillmsgwaitngforresponse");
mRequestMessagesWaiting=0;
if(RILJ_LOGD){
synchronized(mRequestsList){
intcount=mRequestsList.size();
Log.d(LOG_TAG,"WAKE_LOCK_TIMEOUT"+
"mRequestList="+count);
for(inti=0;irr=mRequestsList.get(i);
Log.d(LOG_TAG,i+":
["+rr.mSerial+"]"
+requestToString(rr.mRequest));
}
}
}
}
//mRequestMessagesPendingshowshowmany
//requestsarewaitingtobesent(andbefore
//tobeaddedinrequestlist)sincestarthe
//WAKE_LOCK_TIMEOUTtimer.SinceWAKE_LOCK_TIMEOUT
//istheexpectedtimetogetresponse,allrequests
//shouldalreadysentout(i.e.
//mRequestMessagesPendingis0)whileTIMEOUToccurs.
if(mRequestMessagesPending!
=0){
Log.e(LOG_TAG,"ERROR:
mReqPendingisNOT0but"
+mRequestMessagesPending+"atTIMEOUT,reset!
");
mRequestMessagesPending=0;
}
mWakeLock.release();
}
}
break;
}
}
}
目前主要分析接收短信走过的那些渠道,因此发送短信只是略微的说明一下。
接收短信流程如下(从发送消息到接收消息的处理流程)(图是从网上剽滴~):
从上图右边那块(结合代码)可以看出短信接收是从ril.cpp文件通过socket与RIL.java的socket交流,当ril.cpp收到短信后处理完成后会通过socket发送字节流给上层的RIL.java,而在RIL.java中有Receiver架构(该架构主要是一条线程)在不断监听,
Receiver架构代码:
classRILReceiverimplementsRunnable{
byte[]buffer;
RILReceiver(){
buffer=newbyte[RIL_MAX_COMMAND_BYTES];
}
publicvoid
run(){
intretryCount=0;
StringrilSocket="rild";
try{for(;;){
LocalSockets=null;
LocalSocketAddressl;
booleanmultiRild=SystemProperties.getBoolean("ro.multi.rild",false);
//Use'rild'socketincaseof
//-Non-dsds(mInstanceIdwillbenull)
//-FirstinstanceifDSDSandMultirildenabled
//-DSDSandMultirildisnotenabled.
//Use'rild1'socketforsecondinstanceinDSDSandMultirildenabled
if(mInstanceId==null||mInstanceId==0||multiRild==false){
rilSocket=SOCKET_NAME_RIL;
}else{
rilSocket=SOCKET_NAME_RIL1;
}
try{
s=newLocalSocket();
l=newLocalSocketAddress(rilSocket,
LocalSocketAddress.Namespace.RESERVED);
s.connect(l);
}catch(IOExceptionex){
try{
if(s!
=null){
s.close();
}
}catch(IOExceptionex2){
//ignorefailuretocloseafterfailuretoconnect
}
//don'tprintanerrormessageafterthethefirsttime
//orafterthe8thtime
if(retryCount==8){
Log.e(LOG_TAG,
"Couldn'tfind'"+rilSocket
+"'socketafter"+retryCount
+"times,continuingtoretrysilently");
}elseif(retryCount>0&&retryCount<8){
Log.i(LOG_TAG,
"Couldn'tfind'"+rilSocket
+"'socket;retryingaftertimeout");
}
try{
Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
}catch(InterruptedExceptioner){
}
retryCount++;
continue;
}
retryCount=0;
mSocket=s;
Log.i(LOG_TAG,"Connectedto'"+rilSocket+"'socket");
intlength=0;
try{
InputStreamis=mSocket.getInputStream();
for(;;){
Parcelp;
length=readRilMessage(is,buffer);
if(length<0){
//End-of-streamreached
break;
}
p=Parcel.obtain();
p.unmarshall(buffer,0,length);
p.setDataPosition(0);
//Log.v(LOG_TAG,"Readpacket:
"+length+"bytes");
processResponse(p);
p.recycle();
}
}catch(java.io.IOExceptionex){
Log.i(LOG_TAG,"'"+rilSocket+"'socketclosed",
ex);
}catch(Throwabletr){
Log.e(LOG_TAG,"Uncaughtexceptionreadlength="+length+
"Exception:
"+tr.toString());
}
Log.i(LOG_TAG,"Disconnectedfrom'"+rilSocket
+"'socket");
setRadioState(RadioState.RADIO_UNAVAILABLE);
try{
mSocket.close();
}catch(IOExceptionex){
}
mSocket=null;
RILRequest.resetSerial();
//Clearrequestlistonclose
clearRequestsList(RADIO_NOT_AVAILABLE,false);
}}catch(Throwabletr){
Log.e(LOG_TAG,"Uncaughtexception",tr);
}
/*We'redisconnectedsowedon'tknowtherilversion*/
notifyRegistrantsRilConnectionChanged(-1);
}
}
因此从代码可以看出获取到短信消息后经过一系列地分析然后提交给processResponse(p);方法处理,处理过程中会有两种response,一种是主动上报,比如网络状态,短信,来电等都不需要经过请求,用unsolicited词语专门描述,另一种才是真正意义上的response,也就是命令的响应用solicited描述。
那接收短信就是属于unsolicited,跳到processUnsolicited(Parcelp)方法,查看该方法可得出会继续触发以下方法mSMSRegistrant.notifyRegistrant(newAsyncResult(null,sms,null)); 追溯该方法对象的创建,最后发现该方法设置handler的源头是在:
SMSDispatcher类里
该类做了一件重要的事:
给CommandInterface设置handler的处理方法,就是当接收到短信后触发mSMSRegistrant.notifyRegistrant(newAsyncResult(null,sms,null));方法,然后回调调用之前传入的handler,接着在handler里面处理短信消息。
mCm.setOnNewSMS(this,EVENT_NEW_SMS,null);
mCm.setOnSmsStatus(this,EVENT_NEW_SMS_STATUS_REPORT,null);
mCm.setOnIccSmsFull(this,EVENT_ICC_FULL,null);
mCm.registerForOn(this,EVENT_RADIO_ON,null);
handler处理接收到的短信消息:
@Override
publicvoidhandleMessage(Messagemsg){
AsyncResultar;
switch(msg.what){
caseEVENT_NEW_SMS:
//AnewSMShasbeenreceivedbythedevice
if(Config.LOGD){
Log.d(TAG,"NewSMSMessageReceived");
}
SmsMessagesms;
ar=(AsyncResult)msg.obj;
if(ar.exception!
=null){
Log.e(TAG,"ExceptionprocessingincomingSMS.Exception:
"
+ar.exception);
return;
}
sms=(SmsMessage)ar.result;
try{
intresult=dispatchMessage(sms.mWrappedSmsMessage);
if(result!
=Activity.RESULT_OK){
//RESULT_OKmeansthatmessagewasbroadcastforapp(s)to
//handle.
//Anyotherresult,weshouldackhere.
booleanhandled=(result==Intents.RESULT_SMS_HANDLED);
notifyAndAcknowledgeLastIncomingSms(handled,result,null);
}
}catch(RuntimeExceptionex){
Log.e(TAG,"Exceptiondispatchingmessage",ex);
notifyAndAcknowledgeLastIncomingSms(false,
Intents.RESULT_SMS_GENERIC_ERROR,null);
}
break;
}
}
intresult=dispatchMessage(sms.mWrappedSmsMessage);该段会通过子类(GsmSMSDispatcher)的dispatchMessage方法处理。
经一系列的判断处理最后普通短信将交给dispatchPdus(pdus);这个方法处理。
protectedvoid