telephony 总篇

 

http://blog.csdn.net/aaa111/article/details/52876403

电话管理是Android 系统支持的重要的业务之一,提供接听电话,收发短信、电话薄、网络事件监听、读取用户信息等功能。

      从下到上可以分为四层:硬件驱动层、RIL daemon层、Telephony框架实现层、 PHONE应用层,下层为上层提供服务,每层之间采用不同的通讯方式交互。RIL daemon层实现为单独的一个开机启动的进程(rild命令),通过AT命令硬件驱动层交互,TelephonyJava框架实现层包括一个RIL抽象层,RIL抽象层中通过一个本地socket与RIL daemon层(rild)交互,PHONE应用层通过BINDER机制与Telephony框架交互。

 

 

 

 

一、framework telephony层:

android/frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL

RIL层:radio interface layer 多媒体接口层, 主要是与modem进行串口通信,手机网络、通话、短信方面的

功能:接收unsolicited 和solicited 信息

 

主要由phone进程创建

现在主要了解callTracker这个通话方面的内容(ServiceStateTracker、DataConnectionTracker)

modem传来的来电通知

 

            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
                if (RILJ_LOGD) unsljLog(response);

                mCallStateRegistrants
                    .notifyRegistrants(new AsyncResult(null, null, null));

 

RIL的父类,主要是定义各个观察者 RegistrantList

BaseCommands.java

mCallStateRegistrants

GsmCdmaCallTracker.java (Handler类,说明calltracker只是一个信息的集中转发中心而已)

 

    public GsmCdmaCallTracker (GsmCdmaPhone phone) {
        this.mPhone = phone;
        mCi = phone.mCi;
        mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
        mCi.registerForOn(this, EVENT_RADIO_AVAILABLE, null);

 

    @Override
    public void handleMessage(Message msg) {
            case EVENT_CALL_STATE_CHANGE:
                pollCallsWhenSafe();
            break;


CallTracker.java

 

 

    protected void pollCallsWhenSafe() {
        mNeedsPoll = true;

        if (checkNoOperationsPending()) {
            mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
            mCi.getCurrentCalls(mLastRelevantPoll);
        }
    }


由于一开始的RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED只是一个通知,并没有附加其他消息

 

所以这里会下发一个查询当前所有通话的状态表

RIL.java

解析并填充DriverCall

 

    private Object
    responseCallList(Parcel p) {
        ArrayList<DriverCall> response;
        DriverCall dc;
        response.add(dc);
        return response;

GsmCdmaCallTracker.java

 

 

    @Override
    public void handleMessage(Message msg) {
        AsyncResult ar;

        switch (msg.what) {
            case EVENT_POLL_CALLS_RESULT:
                Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");

                if (msg == mLastRelevantPoll) {
                    if (DBG_POLL) log(
                            "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
                    mNeedsPoll = false;
                    mLastRelevantPoll = null;
                    handlePollCalls((AsyncResult)msg.obj);
                }
            break;

 

 

 

首先查看DriverCall类

DriverCall实际反映了Modem端真实的通话连接信息

+CLCC:List current calls 列出当前所有的通话

+CLIP:Calling line identified presented 来电显示

//+CLCC: 1,0,2,0,0,\"+18005551212\",145
        //     index,isMT,state,mode,isMpty(,number,TOA)?

 

//+CLIP: "02151082965",129,"",,"",0

GsmCdmaCallTracker.java

处理轮询得到的所有通话(进行当前modem端与上层端的通话同步--GsmCdmaConnection<-->DriverCall)

 

    @Override
    protected synchronized void handlePollCalls(AsyncResult ar) {
        for (int i = 0, curDC = 0, dcSize = polledCalls.size()
                ; i < mConnections.length; i++) {
            GsmCdmaConnection conn = mConnections[i];
            DriverCall dc = null;

          if (conn == null && dc != null) {
              mConnections[i] = new GsmCdmaConnection(mPhone, dc, this, i);//(1)

            if (newRinging != null) {
            mPhone.notifyNewRingingConnection(newRinging);//(2)
            }

                   updatePhoneState();//(3)

           if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected) {
            mPhone.notifyPreciseCallStateChanged();//(4)
            updateMetrics(mConnections);
           }

(1) :
基本每一个DriverCall都对应一个通话链接GsmCdmaConnection

 

GsmCdmaConnection.java

//DriverCall  ---> GsmCdmaCall

 

    /** This is probably an MT call that we first saw in a CLCC response or a hand over. */
    GsmCdmaCallTracker mOwner;
    GsmCdmaCall mParent;

       public GsmCdmaConnection (GsmCdmaPhone phone, DriverCall dc, GsmCdmaCallTracker ct, int index) {

               mOwner = ct;             
        mParent = parentFromDCState(dc.state);
        mParent.attach(this, dc);

    private GsmCdmaCall
    parentFromDCState (DriverCall.State state) {
        switch (state) {
            case ACTIVE:
            case DIALING:
            case ALERTING:
                return mOwner.mForegroundCall;
            //break;

            case HOLDING:
                return mOwner.mBackgroundCall;
            //break;

            case INCOMING:
            case WAITING:
                return mOwner.mRingingCall;
            //break;

            default:
                throw new RuntimeException("illegal call state: " + state);
        }
    }

 

 

 

 

 

 

GsmCdmaCallTracker.java

 

    
    //***** Constants

    public static final int MAX_CONNECTIONS_GSM = 19;   //7 allowed in GSM + 12 from IMS for SRVCC
    private static final int MAX_CONNECTIONS_PER_CALL_GSM = 5; //only 5 connections allowed per call

    private static final int MAX_CONNECTIONS_CDMA = 8;
    private static final int MAX_CONNECTIONS_PER_CALL_CDMA = 1; //only 1 connection allowed per call

    public GsmCdmaCall mRingingCall = new GsmCdmaCall(this);
    // A call that is ringing or (call) waiting
    public GsmCdmaCall mForegroundCall = new GsmCdmaCall(this);
    public GsmCdmaCall mBackgroundCall = new GsmCdmaCall(this);


GsmCdmaCall.java

 

//mRingingCall / mForegroundCall / mBackgroundCall 每一种类型的call对应多路通话链接, 而且很明显DriverCall ---》GsmCdmaCall

 

    //***** Called from GsmCdmaConnection

    public void attach(Connection conn, DriverCall dc) {
        mConnections.add(conn);

        mState = stateFromDCState (dc.state);
    }

 

 

 

 

 

 

//双模单待无线语音呼叫连续性 Single Radio Voice Call Continuity (SRVCC)


//Hand Over -- 切换,属于移动通信网络中的技术术语。

所谓切换,就是指当移动台在通话过程中从一个基站覆盖区移动到另一个基站覆盖区,或者由于外界干扰而造成通话质量下降时,必须改变原有的话音信道而转接到一条新的空闲话音信道上去,以继续保持通话的过程。切换是移动通信系统中一项非常重要的技术,切换失败会导致掉话,影响网络的运行质量。因此,切换成功率(包括切入和切出)是我们网络考核的一项重要指标,如何提高切换成功率,降低切换掉话率是我们网络优化工作的重点之一

 

(2):

GsmCdmaPhone.java

 

    public void notifyNewRingingConnection(Connection c) {
        super.notifyNewRingingConnectionP(c);
    }

Phone.java

   
    private final RegistrantList mNewRingingConnectionRegistrants
            = new RegistrantList();

    /**
     * Notifies when a new ringing or waiting connection has appeared.<p>
     *
     *  Messages received from this:
     *  Message.obj will be an AsyncResult
     *  AsyncResult.userObj = obj
     *  AsyncResult.result = a Connection. <p>
     *  Please check Connection.isRinging() to make sure the Connection
     *  has not dropped since this message was posted.
     *  If Connection.isRinging() is true, then
     *   Connection.getCall() == Phone.getRingingCall()
     */
    public void registerForNewRingingConnection(
            Handler h, int what, Object obj) {
        checkCorrectThread(h);

        mNewRingingConnectionRegistrants.addUnique(h, what, obj);
    }

    /**
     * Notify registrants of a new ringing Connection.
     * Subclasses of Phone probably want to replace this with a
     * version scoped to their packages
     */
 public void notifyNewRingingConnectionP(Connection cn) {
        if (!mIsVoiceCapable)
            return;
        AsyncResult ar = new AsyncResult(null, cn, null);
        mNewRingingConnectionRegistrants.notifyRegistrants(ar);
    }


android/frameworks/opt/telephony/src/java/com/android/internal/telephony/CallManager.java:580:        phone.registerForNewRingingConnection(handler, EVENT_NEW_RINGING_CONNECTION,

 

 

android/packages/services/Telephony/src/com/android/services/telephony/PstnIncomingCallNotifier.java:111:            mPhone.registerForNewR

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值