androoid framework学习之 - Telephony 来电流程

来源:互联网 发布:微信软件开发 编辑:程序博客网 时间:2024/04/30 00:11
androoid framework学习之 - Telephony 来电流程

今天顺了一下来电的整个流程,从RIL开始捋一捋:

1.在RIL.java中:当moderm有新信息通过Socket发送过来时,RIL Receive会接收到,然后跑processResponse。 
   class RILReceiver implements Runnable {        byte[] buffer;        RILReceiver() {            buffer = new byte[RIL_MAX_COMMAND_BYTES];        }        @Override        public void        run() {            int retryCount = 0;            String rilSocket = "rild";//循环处理rild传递来的事件            try {for (;;) {                LocalSocket s = null;                LocalSocketAddress l;                if (mInstanceId == null || mInstanceId == 0 ) {                    rilSocket = SOCKET_NAME_RIL[0];                } else {                    rilSocket = SOCKET_NAME_RIL[mInstanceId];                }                try {//创建于rild通信的socket 建立连接                    s = new LocalSocket();                    l = new LocalSocketAddress(rilSocket,                            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) {                        Rlog.e (RILJ_LOG_TAG,                            "Couldn't find '" + rilSocket                            + "' socket after " + retryCount                            + " times, continuing to retry silently");                    } else if (retryCount >= 0 && retryCount < 8) {                        Rlog.i (RILJ_LOG_TAG,                            "Couldn't find '" + rilSocket                            + "' socket; retrying after timeout");                    }                    try {                        Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);                    } catch (InterruptedException er) {                    }                    retryCount++;                    continue;                }                retryCount = 0;                mSocket = s;                Rlog.i(RILJ_LOG_TAG, "(" + mInstanceId + ") Connected to '"                        + rilSocket + "' socket");                int length = 0;                try { //读取socket数据                    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);                        //Rlog.v(RILJ_LOG_TAG, "Read packet: " + length + " bytes");                        //处理rild传递来的消息                        processResponse(p);                        p.recycle();                    }                } catch (java.io.IOException ex) {                    Rlog.i(RILJ_LOG_TAG, "'" + rilSocket + "' socket closed",                          ex);                } catch (Throwable tr) {                    Rlog.e(RILJ_LOG_TAG, "Uncaught exception read length=" + length +                        "Exception:" + tr.toString());                }                Rlog.i(RILJ_LOG_TAG, "(" + mInstanceId + ") Disconnected from '" + rilSocket                      + "' socket");//无法读取数据,将CP状态设置为不可用                setRadioState (RadioState.RADIO_UNAVAILABLE);                try {                    mSocket.close();                } catch (IOException ex) {                }                mSocket = null;                RILRequest.resetSerial();                // Clear request list on close                clearRequestList(RADIO_NOT_AVAILABLE, false);            }} catch (Throwable tr) {                Rlog.e(RILJ_LOG_TAG,"Uncaught exception", tr);            }            /* We're disconnected so we don't know the ril version */            notifyRegistrantsRilConnectionChanged(-1);        }    }
    private void    processResponse (Parcel p) {        int type;        type = p.readInt();//新事件Or send事件response        if (type == RESPONSE_UNSOLICITED) {            processUnsolicited (p);//新事件        } else if (type == RESPONSE_SOLICITED) {            RILRequest rr = processSolicited (p);//command的返回            if (rr != null) {                rr.release();                decrementWakeLock();            }        }    }

那这里是如果是新来电的话,就是新事件,会执行processUnsolicited:
    private void    processUnsolicited (Parcel p) {        int response;        Object ret;        response = p.readInt();        try {switch(response) { //来电             ...................                         case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret =  responseVoid(p); break;            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret =  responseVoid(p); break;            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret =  responseVoid(p); break;            case RIL_UNSOL_RESPONSE_NEW_SMS: ret =  responseString(p); break;......................................        switch(response) {            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:                /* has bonus radio state int */                RadioState newState = getRadioStateFromInt(p.readInt());                if (RILJ_LOGD) unsljLogMore(response, newState.toString());                switchToRadioState(newState);            break;            case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:                if (RILJ_LOGD) unsljLog(response);                mImsNetworkStateChangedRegistrants                    .notifyRegistrants(new AsyncResult(null, null, null));            break;            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:                if (RILJ_LOGD) unsljLog(response);                mCallStateRegistrants                    .notifyRegistrants(new AsyncResult(null, null, null));            break;.............................}

    public void    notifyRegistrant(AsyncResult ar)    {        internalNotifyRegistrant (ar.result, ar.exception);    }

    /*package*/ 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);        }    }

那这里sengMessage发到哪里呢?
在CallstateNotifier里面有如下注册:
    // Events generated internally:    public CallStateMonitor(CallManager callManager) {        this.callManager = callManager;        registeredHandlers = new ArrayList<Handler>();        registerForNotifications();    }    /**     * Register for call state notifications with the CallManager.     */    private void registerForNotifications() {        //        // TODO: The lines commented out here can be removed as their associated functionality in        // other files is removed.        //        callManager.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null);        //callManager.registerForPreciseCallStateChanged(this, PHONE_STATE_CHANGED, null);        //callManager.registerForDisconnect(this, PHONE_DISCONNECT, null);        //callManager.registerForUnknownConnection(this, PHONE_UNKNOWN_CONNECTION_APPEARED, null);        callManager.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null);        //callManager.registerForCallWaiting(this, PHONE_CDMA_CALL_WAITING, null);        callManager.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null);

那在上面send的内容是CallStateMonitor.PHONE_NEW_RINGING_CONNECTION,搜索这个,
在CallNotifier.java里面:
    @Override    public void handleMessage(Message msg) {        switch (msg.what) {            case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION://这个就是从callStateNotifer来的                log("RINGING... (new)");                isForbidden = false;                // Add to check the firewall when firewall provider is built.                final ContentResolver cr = mApplication.getContentResolver();                if (cr.acquireProvider(FIREWALL_PROVIDER_URI) != null) {                    AsyncResult r = (AsyncResult) msg.obj;                    Connection c = (Connection) r.result;                    if (c != null && c.isRinging() && c.getCall() != null) {                        Phone phone = c.getCall().getPhone();                        String number = c.getAddress();                        int subscription = phone.getSubId();                        Bundle extras = new Bundle();                        extras.putInt(PhoneConstants.SUBSCRIPTION_KEY, subscription);                        extras.putString(EXTRA_NUMBER, number);                        extras = cr.call(FIREWALL_PROVIDER_URI, IS_FORBIDDEN, null, extras);                        if (extras != null) {                            isForbidden= extras.getBoolean(IS_FORBIDDEN);                            if (isForbidden) {                                PhoneUtils.hangupRingingCall(c.getCall());                                return;                            }                        }                    }                }                onNewRingingConnection((AsyncResult) msg.obj);                break;            case CallStateMonitor.PHONE_STATE_CHANGED:                onPhoneStateChanged((AsyncResult) msg.obj);                break;            case CallStateMonitor.PHONE_DISCONNECT:                if (DBG) log("DISCONNECT");                onDisconnect((AsyncResult) msg.obj);                break;


这边就分析到这里了。
0 0
原创粉丝点击