MMS send flow in QCOM
MMS发送流程图

Key Point
1:在点击短信界面的发送button(高通插入双卡后有两个botton)后,会进入ComposeMessageActivity.java的onClick()函数。
这个函数将进行会在调用checkRecipientsCount()函数中继续向下调用其他函数,最终调用到sendMessage()函数。
2:Compose的sendMessage()跳转到WorkingMessage.java的send()函数,在这个函数中会区分短信和彩信的发送,如果是彩信类型或者包含有email地址的收信人,则新建一个线程,进入发送。 该线程: (1)makeSendReq(),将会话的联系人的号码、主题、时间整理为一个请求,然后进入sendMmsWorker()。
(2)sendMmsWorker()中,首先对threadId进行确认,调用到Threads.getOrCreateThreadId(context, recipients),在thread(对应表中的_id)表中查询,查询不到,则递加生产新ID。
(3)Conversation.verifySingleRecipient,如果只有一个联系人,则对联系人的号码查询,如果查询出的号码与传入的号码不一样,则将新号码插入进sendReq中。
(4)
ContentValues values = new ContentValues();
values.put(Mms.MESSAGE_BOX, Mms.MESSAGE_BOX_OUTBOX);
values.put(Mms.THREAD_ID, threadId);
values.put(Mms.MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ);
if (textOnly) {
values.put(Mms.TEXT_ONLY, 1);
}
mmsUri = SqliteWrapper.insert(mActivity, mContentResolver, Mms.Outbox.CONTENT_URI,
values);
向outbox中预先插入一些值,已更新UI界面为sending状态。
(5)
cursor = SqliteWrapper.query(mActivity, mContentResolver,
Mms.Outbox.CONTENT_URI, MMS_OUTBOX_PROJECTION, null, null, null);
if (cursor != null) {
long maxMessageSize = MmsConfig.getMaxSizeScaleForPendingMmsAllowed() *
MmsConfig.getMaxMessageSize();
long totalPendingSize = 0;
while (cursor.moveToNext()) {
totalPendingSize += cursor.getLong(MMS_MESSAGE_SIZE_INDEX);
}
if (totalPendingSize >= maxMessageSize) {
unDiscard(); // it wasn't successfully sent. Allow it to be saved as a draft.
mStatusListener.onMaxPendingMessagesReached();
markMmsMessageWithError(mmsUri);
return;
}
}
查询pending中的彩信总的size,如果大于默认值,则返回错误。
(6)
if (newMessage) {
// Create a new MMS message if one hasn't been made yet.
mmsUri = createDraftMmsMessage(persister, sendReq, slideshow, mmsUri,
mActivity, null);
// Remove the sd card mmsUri will be null
if (mmsUri == null) {
Toast.makeText(mActivity, R.string.cannot_send_attach_reason,
Toast.LENGTH_SHORT).show();
return;
}
} else {
// Otherwise, sync the MMS message in progress to disk.
updateDraftMmsMessage(mmsUri, persister, slideshow, sendReq, null);
}
这里确保data/data/com.android.providers.telephony/app_parts下的PART_XXX附件文件被创建,否则进行重新创建的过程。
updateDraftMmsMessage(mmsUri, persister, slideshow, sendReq, null),这里对part表进行更新,为最新的发送时间,threadid 和number。然后进入MmsMessageSender的sendMessage函数。
3:MmsMessageSender的sendMessage函数,先对date进行更新,然后Move the message into MMS Outbox,最新启动TransactionService服务。
4:TransactionService服务这里用到的obverser模式,对SendTransaction等进行监听:。
5:通过handleMessage进行消息的处理EVENT_NEW_INTENT到onNewIntent(),再到launchTransaction(),最后到
transaction = new SendTransaction(
TransactionService.this, serviceId,
transactionSettings, args.getUri());到processTransaction中。
6:processTransaction()中对Transaction在mPending和mProcessing表中进行判断,然后建立APN链接(这里有个循环的过程) transaction.attach(TransactionService.this),对SendTransaction等被观察者增加观察者,transaction.process()然后进行发送。
7:SendTransaction中启动一个新线程
(1)persister.load(mSendReqURI),其子函数会调用sql.query()操作去查询pdu表中的数据。并封装成pdu格式返回。
(2)values.put(Mms.DATE, date);SqliteWrapper.update(mContext, mContext.getContentResolver(),mSendReqURI, values, null, null);这一步主要的作用是更新当前的时间到pdu表中。
(3)sendPdu()函数这一步是主要的进行彩信发送的函数,最终调用到HttpUtils.httpConnection()。进行http链接。
(4)再次更新数据库,更新发送结果及message_i。
(5)将该信息从outbox移到sent box。信息就会变成sent。
(6)notifyObservers(),这个函数是继承自Observe类。会调用之前注册的update()函数。
8:notifyObservers()会调用到TransactionService中的update,更具返回值,去做重发,或者下一条彩信等动作。
PS下:
(1)这里跟踪高通的附件加载过程,发现temp.jpg等文件没有在sdcard/Android/data/com.android.mms/cache下建立,不知道啥原因
代码在composemessageactivity下的onActivityResult中case REQUEST_CODE_TAKE_PICTURE
File file = new File(TempFileProvider.getScrapPath(this));
Uri uri = Uri.fromFile(file);
// Remove the old captured picture's thumbnail from the cache
MmsApp.getApplication().getThumbnailManager().removeThumbnail(uri);
(2)高通HttpUtils关系http链接的工具类,httpConnection()会有异常关掉socket的,还往socket里写数据的情况,不知道啥原因
本文详细解析了在高通Android 4.4系统中,彩信发送的具体步骤,从ComposeMessageActivity的onClick开始,经过WorkingMessage.java的send()函数,到MmsMessageSender和TransactionService的服务交互,再到SendTransaction的执行,包括HTTP连接的建立和彩信数据的发送。在过程中涉及线程、数据库操作、消息监听和服务交互等关键环节。同时指出在附件加载和HttpUtils中遇到的异常现象。

1万+

被折叠的 条评论
为什么被折叠?



