`

android sms接收流程(ril分析)

 
阅读更多

短信接收是从ril.cpp文件通过socket与RIL.java的socket交流,当ril.cpp收到短信后处理完成后会通过socket发送字节流给上层的RIL.java,而在RIL.java中有Receiver架构(该架构主要是一条线程)在不断监听,

 

Receiver架构代码:

class RILReceiver implements Runnable {

        byte[] buffer;

        RILReceiver() {

            buffer = new byte[RIL_MAX_COMMAND_BYTES];

        }

        public void

        run() {

            int retryCount = 0;

            try {
                for (;;) {

                    LocalSocket s = null;

                    LocalSocketAddress l;

                    try {

                        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

                        }

                        // don't print an error message after the the first time

                        // or after the 8th time

                        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();

                        for (;;) {

                            Parcel p;

                            length = readRilMessage(is, buffer);

                            if (length < 0) {

                                // End-of-stream reached

                                break;

                            }

                            p = Parcel.obtain();

                            p.unmarshall(buffer, 0, length);

                            p.setDataPosition(0);

                            // Log.v(LOG_TAG, "Read packet: " + length +
                            // " bytes");

                            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());

                    }

                    Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL

                    + "' socket");

                    setRadioState(RadioState.RADIO_UNAVAILABLE);

                    try {

                        mSocket.close();

                    } catch (IOException ex) {

                    }

                    mSocket = null;

                    RILRequest.resetSerial();

                    // Clear request list on close

                    synchronized (mRequestsList) {

                        for (int i = 0, sz = mRequestsList.size(); i < sz; i++) {

                            RILRequest rr = mRequestsList.get(i);

                            rr.onError(RADIO_NOT_AVAILABLE, null);

                            rr.release();

                        }

                        mRequestsList.clear();

                    }

                }
            } catch (Throwable tr) {

                Log.e(LOG_TAG, "Uncaught exception", tr);

            }

        }

    }

 

因此从代码可以看出获取到短信消息后经过一系列地分析然后提交给processResponse(p); 方法处理,处理过程中会有两种response,一种是主动上报,比如网络状态,短信,来电等都不需要经过请求,用unsolicited词语专门描述,另一种才是真正意义上的response,也就是命令的响应用solicited描述。那接收短信就是属于unsolicited,跳到processUnsolicited (Parcel p)方法,查看该方法可得出会继续触发以下方法mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null)); 追溯该方法对象的创建,最后发现该方法设置handler的源头是在:SMSDispatcher类里

clip_image004

该类做了一件重要的事:给Command Interface设置handler的处理方法,就是当接收到短信后触发mSMSRegistrant.notifyRegistrant(new AsyncResult(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
    public void handleMessage(Message msg) {

        AsyncResult ar;

        switch (msg.what) {

        case EVENT_NEW_SMS:

            // A new SMS has been received by the device

            if (Config.LOGD) {

                Log.d(TAG, "New SMS Message Received");

            }

            SmsMessage sms;

            ar = (AsyncResult) msg.obj;

            if (ar.exception != null) {

                Log.e(TAG, "Exception processing incoming SMS. Exception:"
                        + ar.exception);

                return;

            }

            sms = (SmsMessage) ar.result;

            try {

                int result = dispatchMessage(sms.mWrappedSmsMessage);

                if (result != Activity.RESULT_OK) {

                    // RESULT_OK means that message was broadcast for app(s) to
                    // handle.

                    // Any other result, we should ack here.

                    boolean handled = (result == Intents.RESULT_SMS_HANDLED);

                    notifyAndAcknowledgeLastIncomingSms(handled, result, null);

                }

            } catch (RuntimeException ex) {

                Log.e(TAG, "Exception dispatching message", ex);

                notifyAndAcknowledgeLastIncomingSms(false,
                        Intents.RESULT_SMS_GENERIC_ERROR, null);

            }

            break;

        }

    }

 

int result = dispatchMessage(sms.mWrappedSmsMessage); 该段会通过子类(GsmSMSDispatcher)的dispatchMessage方法处理。经一系列的判断处理最后普通短信将交给dispatchPdus(pdus);这个方法处理。

 

protected void dispatchPdus(byte[][] pdus) {

Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);

intent.putExtra("pdus", pdus);

dispatch(intent, "android.permission.RECEIVE_SMS");

}

void dispatch(Intent intent, String permission) {

// Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any

// receivers time to take their own wake locks.

mWakeLock.acquire(WAKE_LOCK_TIMEOUT);

mContext.sendOrderedBroadcast(intent, permission, mResultReceiver,

this, Activity.RESULT_OK, null, null);

}

 

最后,我们可以看出这个方法将短信通过顺序广播播放出去(action是SMS_RECEIVED_ACTION),无论广播是否被中断最后都会调用mResultReceiver,这里会将已读或未读的状态告诉给对方。如果短信广播中间没有受到終止,那么接下来的流程是:PrivilegedSmsReceiver类接收到android.provider.Telephony.SMS_RECEIVED的请求然后调用 intent.setClass(context, SmsReceiverService.class); 启动SmsReceiverService服务类来处理短信并保存短信。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics