Ril层简介和短信接收

 RIL层

RIL 首先这个是用来和CP(基带处理器)通信。可以把他看成是硬件层的抽象,这里的硬件当然是各式各样的模块,比如wcdma, gsm, evdo等等。这样ril上层即telephony就无需关心当前是何种模块,比如我要拨出一个电话,我只要下发一个请求号为RIL_REQUEST_DIAL的请求即可,无需关心发送什么AT命令,这是软件思想中隔离变化的体现。

【硬件抽象层,控制mode端,RIL则是将虚拟电话系统的标准功能转换成实际的所使用的Modem的AT指令           telephony 与ril层通过unix domain socket通信

   /framework/base/telephony/java/com/android/internal/telephony/RIL.java】

RILD

是RIL(Radio Interface Layer) Deamon的简称。通过过socket将请求发送给RILD的消息循环,消息循环则将请求转发给底层通信模块(直接调用底层的库)来实现对通信模块功能的调用。反之,当通信模块有类似于来电的消息时,也会通过RILD的回调,将信息包装成消息,发送到RILD的消息循环中去处理,最后通过socket送给telephony

短信接收

 从/framework/base/telephony/java/com/android/internal/telephony/RIL.java看起。

发送短信和接收短信是通过Receiver和Sender架构。这里讲Receiver。

 class RILReceiver implements Runnable{
      ......
              
        public void
        run() {
        .......
            try {
                for (;;) {
                LocalSocket s = null;
                LocalSocketAddress l;

                .......
                ........
                try {
                    s = new LocalSocket();
                    l = new LocalSocketAddress(socketRil,
                            LocalSocketAddress.Namespace.RESERVED);
                    s.connect(l);
       
                    .......
                    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();
                          ..........           
    }

通过socket获取数据后,最后交给了processResponse(p); 

    private void  processResponse (Parcel p) {
        int type;

        type = p.readInt();

        if (type == RESPONSE_UNSOLICITED) {
            processUnsolicited (p);
        } else if (type == RESPONSE_SOLICITED) {
            processSolicited (p);
        }

        releaseWakeLockIfDone();
    }

 这里有2种type.一种是主动上报,比如网络状态,短信,来电等都不需要经过请求,用unsolicited词语专门描述。RESPONSE_SOLICITED是必须先请求然后才响应的类型。当然这里是短信接收肯定会走前者。processUnsolicited该方法会根据当前的请求的类型,如果是短信则是RIL_UNSOL_RESPONSE_NEW_SMS,以下是其调用的代码;

 case RIL_UNSOL_RESPONSE_NEW_SMS: {
                if (RILJ_LOGD) unsljLog(response);

                // FIXME this should move up a layer
                String a[] = new String[2];

                a[1] = (String)ret;

                SmsMessage sms;

                sms = SmsMessage.newFromCMT(a);
                if (mSMSRegistrant != null) {
                    mSMSRegistrant
                        .notifyRegistrant(new AsyncResult(null, sms, null));
                }
            break;
            }

 因为  RIL extends BaseCommands 。其中mSMSRegistrant为BaseCommands 中的对象。 追踪.notifyRegistrant(new AsyncResult(null, sms, null));会发现

void
    internalNotifyRegistrant (Object result, Throwable exception)
    {
        Handler h = getHandler();

        if (h == null) {
            clear();
        } else {
            Message msg = Message.obtain();

            msg.what = what;
            
            msg.obj = new AsyncResult(userObj, result, exception);
            
            h.sendMessage(msg);
        }
    }

 发送了一条mesage对象。而哪里接收这条消息并处理呢? 在BaseCommands 中查看mSMSRegistrant的实例化会发现。

 public void setOnNewSMS(Handler h, int what, Object obj) {。。。}

 其中的handler h 就是接收message并处理的handler.追踪setOnNewSMS会发现最后是在

mCm.setOnNewSMS(this, EVENT_NEW_SMS, null);

framework/base/telephony/java/com/android/internal/telephony/SMSDispatcher.java中实现。  

SMSDispatcher就是继承handler.所以处理函数为

@Override   
    public void handleMessage(Message msg) {
           ....

        switch (msg.what) {

        case EVENT_NEW_SMS:

               ....
            SmsMessage sms;

            ar = (AsyncResult) msg.obj;

           ......

            sms = (SmsMessage) ar.result;

            try {

                int result = dispatchMessag(sms.mWrappedSmsMessage);
             ........
        }

    }

 追踪dispatchMessag实现,会在GsmSMSDispatch和CdmaSMSDispatch中实现。这里只看GsmSMDispatch.经过dispatchNormalMessage,经一系列的判断处理最后普通短信将交给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) {

mWakeLock.acquire(WAKE_LOCK_TIMEOUT);

mContext.sendOrderedBroadcast(intent, permission, mResultReceiver,

this, Activity.RESULT_OK, null, null);

}


 【注:在dispatchPdus方法内,就可以处理防火墙相关事件。让他不发出接收到短信的广播

 然后短信app中PrivilegedSmsReceiver广播接收器接收到广播后会调用onReceiveWithPrivilege方法.此时进入APP层。

packages/apps/Mms/src/com/android/mms/transaction/PrivilegedSmsReceiver

 intent.setClass(context, SmsReceiverService.class);
        intent.putExtra("result", getResultCode());
        beginStartingService(context, intent);

启动SmsReceiverService。跟踪源码可以看到如下代码

 private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

            ......
                if (MESSAGE_SENT_ACTION.equals(intent.getAction())) {
                    handleSmsSent(intent, error);
                } else if (SMS_RECEIVED_ACTION.equals(action)) {
                    handleSmsReceived(intent, error);
                } else if (ACTION_BOOT_COMPLETED.equals(action)) {
                    handleBootCompleted();
                } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
                    handleServiceStateChanged(intent);
                } else if (ACTION_SEND_MESSAGE.endsWith(action)) {
                    handleSendMessage(intent);
                }
            }
            

接收短信会走 handleSmsReceived(intent, error); 函数

private void handleSmsReceived(Intent intent, int error){
        ......        
        Uri messageUri = insertMessage(this, intent, error, format);

        ......
        if (messageUri != null) {
            MessagingNotification.blockingUpdateNewMessageIndicator(this, true, false);
        } else {
            SmsMessage sms = msgs[0];
            SmsMessage msg = SmsMessage.createFromPdu(sms.getPdu());
            CharSequence messageChars = msg.getMessageBody();
            String message = messageChars.toString();
            if (!TextUtils.isEmpty(message)) {
                MessagingNotification.notifyClassZeroMessage(this, msgs[0]
                        .getOriginatingAddress());
            }
            ......
}



    

这里做了2个操作。 insertMessage 插入数据库。插入成功后提示用户blockingUpdateNewMessageIndicator。插入失败也通知用户notifyClassZeroMessage

猜你喜欢

转载自h529820165.iteye.com/blog/1656530
RIL