三、发送短信流程分析
1.Application层的短信发送流程
Application层中短信发送的流程,其逻辑的实现代码在packages/apps/Mms包路径下,流程如下图。
1.1 Application层短信数据流向跟踪
a.图中省略了短信UI界面的相关操作,将WorkingMessage对象的send方法调用作为短信发送流程的开始。在该方法里做了如下操作:创建Conversation容器保存短信数据;判断彩信or短信;创建新线程,并执行preSendSmsWorker调用。
b.在第3步WorkingMessage.sendSmsWorker中,以短信的dests(发送地址,string), msgText(短信内容,string), threadId(线程ID,long)三个数据为参数构造了SmsMessageSender对象,并且调用该对象的sendMessage方法。
c.第6步和第7步是在SmsMessageSender对象的queueMessage方法中同步调用的。第6步调用Telephony Framework层中的Sms类的静态方法,把即将发送的短信相关信息保存到数据库中。第7步则发起请求发送短信的广播。
d.第7步SmsReceiver接收请求发送短信的广播,启动SmsReceiverService服务(第11步)。
e.第16步,最终该服务中的sendFirstQueueMessage方法(synchronized同步锁保证线程安全)继续响应短信发送请求:首先,读取数据库中等待发送的短信数据,以短信数据(address, msgText, threadId, status,msgUri)构造SmsSingleRecipientSender对象。然后,通过SmsSingleRecipientSender对象的sendMessage方法,继续发起短信发送的请求。
1.2 SmsSingleRecipientSender与framework层的交互
SmsSingleRecipientSender类作为app层传递短信发送请求到framework层的最后一关,它的功能只有一个sendMessage()。有必要分析其内部逻辑实现。SmsSingleRecipientSender对象被调用sendMessage()时, 有如下逻辑处理:
a.调用SmsManager对象divideMessage方法分拆短信内容(若没有超过长度则不拆)。
b.将保存的短信转移至outbox中。
c.创建PendingIntent对象deliveryIntents和sentIntents(个数由分拆的短信数决定),用以回调广播短信发送状态报告和短信发送结果报告。
d.这里出现了分支:判断是否多sim卡。如果是,则调用MSimSmsManager对象的sendMultipartTextMessage方法。如果不是,调用SmsManager对象的sendMultipartTextMessage方法。前者获取的是isms_msim服务,后者获取的是isms服务,其余的逻辑实现是一致的。
至此,发送短信的请求被传递到framework层。
1.3 SmsManager提供给app层调用的对短信操作的接口
由于SmsManager和MSimSmsManager中提供的接口除了获取的服务不同,其他的逻辑实现基本一致,所以只分析SmsManager的接口。isms服务和isms_msim服务下节学习。该类提供了短信拆分、短信发送、将短信复制到SIM卡、从SIM卡删除短信和小区广播等接口,接口中不做处理,直接调用其他类的方法完成。
getDefault():获得默认的SmsManager对象。
divideMessage():短信拆分。不做处理,直接调用SmsMessage.fragmentText()来完成实机的拆分操作。
sendMultipartTextMessage():短信发送。若传入的短信内容是分段的,则调用isms服务的sendMultipartText();若传入的是单短信,则通过sendTextMessage()调用isms服务的 sendText()。
sendDataMessage():发送短信至指定应用端口。不做处理,直接调用isms服务的sendData()。
copyMessageToIcc(): 将短信复制到SIM卡。不做处理,直接调用isms服务的copyMessageToIccEf()。
deleteMessageFromIcc():从SIM卡删除短信。不做处理,直接调用isms服务的updateMessageOnIccEf()。
2.Framework层的短信发送流程
发送短信的请求,从app层通过SmsManager对象的sendMultipartTextMessage方法调用,已经传递到了Telephony Framework层中,Telephony Framework层与RIL层交互,最终完成短信的发送请求,转换成RIL请求,其处理流程详情如下图所示。
本图是继续上节的调用,在SmsManager的sendMultipartTextMessage中出现了分支:若传入的短信内容是分段的,则调用isms服务的sendMultipartText();若传入的是单短信,则通过sendTextMessage()调用isms服务的 sendText()。
2.1 Framework层短信数据流向跟踪
a.第1步中,SmsManager.sendMultipartTextMessage方法有5个入参:
String destinationAddres