メール送信--メールの送信プロセス(framework)

6532 ワード

メールの送信フロー(framework)
一、主要書類
/packages/apps/Mms/com/android/mm/transaction/SmsSingleRecipientSender
/framework/base/telephony/java/com/android/internal/telephony/ISms.aidl
/framework/base/telephony/com/android/internal/telephony/IccSmsInterfaceManager
/telephony/java/com/android/internal/telephony/SMSDispatcher.java
/telephony/java/com/android/internal/telephony/ImsSMSDispatcher.java
/telephony/java/com/android/internal/telephony/GsmSMSDispatcher.java
/telephony/java/com/android/internal/telephony/CdmaSMSDispatcher.java
/telephony/java/android/telephony/SmsMessage.java
/base/telephony/java/com/android/internal/telephony/RIL.java
/framework/base/telephone/java/android/telephone/SmsManager
/framework/base/telephone/java/android/telephone/MSimIccSmsInterfaceManager

ファイルの簡単な説明:
SmsSingleRecipientSenderは、アプリケーションMmsがメールを送信する際に呼び出すクラスです
ISms.aidl:MSimIccSmsInterfaceManagerとの通信用
注:ここでは、MSimIccSmsInterfaceManagerというクラスを4.0のソースコードでキャンセルした、高通2.3のソースコードを参照してください.
二、フローチャート
2.1クラス図
 
2.2シーケンス図
1)android2.3のタイミングチャート:
2)android4.0のタイミングチャート
MSimIcccSmsInterfaceManagerというクラスは4.0でキャンセルするため、つまり4.0はISmsを使用する.aidlはIccSmsInterfaceManagerに直接アクセスしていくつかの操作を行い、中間のこのプロセスを省略します.
より明確な対比を与えるために、以下は4.0のタイミングチャートです.
比較からいくつかの微細な違いが見られ、その原理の差は2.3に基づいていくつかの過程を簡略化しただけではない.
説明:GsmSmsDispatcherは1つのブランチにすぎず、もう1つのブランチはCdmaSmsDispatcherであり、ここではGsmを例に挙げる
三、プロセス解析
3.1アプリケーション層呼び出しエントリ
SMSを送信するアプリケーションMmsは、SmsSingleRecipientSenderクラスのsendMessageメソッドを呼び出すことによって、SMS送信のエントリの1つであり、以下はそのコアコードである.
try { 
smsManager.sendMultipartTextMessage(mDest, mServiceCenter, messages, sentIntents, 
deliveryIntents, mSubscription);
 } 
catch (Exception ex) {
 throw new MmsException("SmsMessageSender.sendMessage: caught " + ex 
+ " from SmsManager.sendTextMessage()");
 } if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE))
 { 
log("sendMessage: address=" + mDest + ", threadId=" + mThreadId + ",
 uri=" + mUri + ", msgs.count=" + messageCount); 
}

上記のコードから,SmsManagerクラスのsendMulipartTextMessageメソッドを呼び出すことにより,中間層に入り,他の作業は中間層によって行われることが分かる.
3.2中間層呼び出しの詳細
3.2.1 SmsManagerからSMSDispatcherへ.sendRawPdu();
次の図は、コードの実行プロセスです.
cdmaとgsmはSMSDispatcherのsendRawPdu()メソッドに歩いてメールを送ることができ、何と呼んで根に落ちるか、あるいは時間が経つにつれて必ず合って、時間が経つにつれて必ず分けることができます.その違いは、SmsTrackerオブジェクトを構築する際、そのメンバー変数RadioTechnologyFamilyの値が異なり、cdmaはRadioTechnologyFamilyを使用する点です.RADIO_TECH_3 GPP 2、GSMはRadioTechnologyFamilyを使用する.RADIO_TECH_3GPP.
3.2.2 SMSDispatcher.sendRawPdu()からRILへの流れ
この方法をRilの流れにもっとはっきりさせるために、特画のフローチャートはみんな参考にします
    
その中のmCmはCommandInterfaceで、1つの口実で、RIL.JAvaはこの言い訳を実現するので、呼び出しはRILに呼び出される.JAva中行き、RIL.JAvaは中間層とrildデーモンプロセスの通信の入口であり、これにより対応する操作をrildで完了することができる.これでリレー棒をRIL階に渡しました.
3.2.3 RIL.JAva送信解析
sendImsGsmSms,sendSms,sendCdmaSms,sendImsCdmaSmsの4つのメソッドの基本フローはほぼ同じであり,いずれもRILRequestを構築してからsendメソッドを呼び出して送信する.違いは、RILRequestを取得する際に送信されるリクエストのタイプが異なり、構築されたpdu構造が異なり、2つのImsメソッドがRILRequestに1つの数字を先に書き込む必要があることです.
sendImsGsmSmsを例にとると、以下はそのコアコードです.
    public void
    sendImsGsmSms (String smscPDU, String pdu, Message result) {
        RILRequest rr = RILRequest.obtain(RIL_REQUEST_IMS_SEND_SMS, result);

        rr.mp.writeInt(1); //RadioTechnologyFamily.RADIO_TECH_3GPP;
        constructGsmSendSmsRilRequest(rr, smscPDU, pdu);

        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));

        send(rr);
    }
の実行フローは、次のフローチャートに示されている.
RILの内部呼び出しの流れを見て皆さんはおかしいと思いますが、RILSenderは何ですか?コードを見ると、こいつは内部クラスで、handlerを継承しているので、なぜメッセージを送ることができるのか分かります.ここまでだJAvaはすでに送信操作をデーモンプロセスrildに渡しており、残りの操作はデーモンプロセスと猫側で完了しています.
3.3送信後の処理
上記の各ステップで最終的にメールを送信しましたが、メールが送信されたら終了しますか?明らかにそうではありません.これは始まりではありませんが、終わりまでは遠くありません.ハハハ、あまり早く喜ばないでください.次はメールを送った後にした一連の断後処理です.
断後処理の最も主要な仕事は2つあります.1つは資源を解放することです.その中で最も重要なのはRILRequestという対象です.私たちは恩知らずではいけませんよね.足を使ったら蹴っても聞かないでください.二つ目は、レポートを送信することです.メールの設定でレポートを送信するオプションが開かれていなければ、まだいくつかのことをしています.いわゆる準備ができています.このオプションが開かれていれば、直接レポートを取得することができます.次のポイントは、この2つの面を説明することです.
切断処理を実行するには、送信操作が完了したと判断したに違いありません.どうやって操作が完了したかどうかを判断しますか?上記のRILを覚えています.JAvaはLocalSocketを通じて命令をrildに送ります.私たちの中国は礼尚往来にこだわっています.これにもこの美徳があります.送信が完了するとrildはRILにメッセージを返し、RILが受信すると対応する動作を実行します.
3.3.1 RILからSMSDispatcherまでの実行プロセス
送信プロセスについてRILを覚えていますか?JAvaにはRILSender内部クラスがあります.rildにコマンドを送信するために使用されます.RILReceiver内部クラスは、主にrildの「お礼」を読み取るために使用されます.
ここでメールを送ったときに返されるイベントは何ですか?
前述のメール送信の4つの方法に対応するイベントタイプは、次のとおりです.
1)sendSMS対応RIL_REQUEST_SEND_SMS
2)sendCdmaSms対応RIL_REQUEST_CDMA_SEND_SMS、
3)sendImsGsmSms&sendImsCdmaSms対応RIL_REQUEST_IMS_SEND_SMS
メッセージを作成すると実際にwhatがSEND_に設定されますSMS_COMPLETE、ここまでRILの作業は順調に完了しました.最後のステップを見てください.RILRequestオブジェクトも解放されました.残りの作業はSMSDispatcherが引き続き完了します.SMSDispatcherがこれらの情報をどのように伝えるかを見てください.次の節を見てください.
3.3.2 SMSDispatcher配布情報
SMSDipatcherは伝達された情報を受け取って自分のhandMessageメソッド処理を呼び出す
SEND_SMS_COMPLETEというメッセージ.次の図のコード実行プロセスを見てください.
       
3.3.3レポートの送信
1)
RILがSMSDispatcherに呼び出す説明
GSMの場合、構築方法では、GsmSMSDispatcherをRILがレポート送信時にイベントを受信した受信者として登録し、メッセージタイプをEVENT_に設定するNEW_SMS_STATUS_REPORT、対応するRegistrantクラスはmSmsStatusRegistrantです.
CDMAの場合、メッセージタイプはEVENT_に設定されるNEW_対応するRegistrantクラスがmCdmaSMSRegistrantであるSMS.
RILが最下位から送信されたレポートを受信すると、プロセスは3.3.1実行プロセスと同様に、RESPONSE_のタイプが生成されます.UNSOLICITEDは、processUnsolicited処理に移行し、ここでは重複しない.
2)GSMとCDMAの処理説明
GSMの場合、イベントタイプはRIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORTでは、まずresponseStringを呼び出してParcelからデータを取得し、mSmsStatusRegistrantのnotifyRegistrantメソッドを呼び出してメッセージクラスのwhat属性をEVENT_に設定します.NEW_SMS_STATUS_REPORT,最後にSMSDispatcherに移行して処理を行う.
一方、CDMA、イベントはRIL_UNSOL_RESPONSE_CDMA_NEW_SMS、処理プロセスはGSMとほぼ同じですが、Parcelからデータを取得するのはresponseCdmaSmsメソッドを呼び出してSmsMessageオブジェクトを取得し、mCdmaSMSRegistrantのnotifyRegistrantメソッドを呼び出してメッセージタイプを設定します.whatプロパティはEVENT_です.NEW_SMSは、最後にSMSDispatcherに移行して処理を行う.
3)SMSDispatcher処理
GSMについてはhandleStatusReportメソッド処理を直接呼び出し,転送されたAsyncResultオブジェクトからSmsMessageを取得してSmsTrackerのインデックスを取得し,deliveryPendingListからSmsTrackerを取り出し,deliveryIntentを送信しメッセージ確認を送信する.
CDMAの場合、handleMessageでEVENT_に移動します.NEW_SMSは、dispatchMessageを呼び出してメッセージの配信を行う.
これ以降の操作フローを下図に示します.
     
説明dipatcherMessageメソッドには多くの操作があり,確認メッセージの送信と前述したエラー情報の送信はpendingIntentのsendメソッドによって実現される.ここには一つ一つ細かく挙げていない.
   
四、まとめ
この送信フローは,中間層の送信フローを簡潔に述べたものにすぎず,カラーメッセージの送信フローについては個別の紙面で記述される.アプリケーション層の一連の複雑な操作についても分析されていないが、アプリケーション層がどのように行われているかを理解し、次回の分解を聞く必要がある.