Android P 移动网络系统架构--ServiceStateTracker

不问归期 提交于 2020-02-26 11:20:27

获取手机信号

 

网络信号强度的单位是dBm(毫瓦分贝),一般用负数表示。

2G,3G,4G获得信号强度的方式都是重写PhoneStateListener的onSignalStrengthsChanged() 方法,当信号强度发生改变的时候就会触发这个事件,我们可以在这个事件里获取信号强度

APP通过注册监听PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
TelephonyManager mr = Context.getSystemService(Context.TELEPHONY_SERVICE);
mr.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
 
private class MyPhoneStateListener extends PhoneStateListener {
private int asu = 0,lastSignal = 0;     
@Override     
public void onSignalStrengthsChanged(SignalStrength signalStrength) {         
super.onSignalStrengthsChanged(signalStrength);         
}
}
获取得到SignalStrength 对象,该对象包含了所有信号相关信息
/**
* Contains phone signal strength related information.
*/
public class SignalStrength implements Parcelable {
...
 
/** Parameters reported by the Radio */
    private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
    private int mGsmBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
    private int mCdmaDbm;   // This value is the RSSI value
    private int mCdmaEcio;  // This value is the Ec/Io
    private int mEvdoDbm;   // This value is the EVDO RSSI value
    private int mEvdoEcio;  // This value is the EVDO Ec/Io
    private int mEvdoSnr;   // Valid values are 0-8.  8 is the highest signal to noise ratio
    private int mLteSignalStrength;
    private int mLteRsrp;
    private int mLteRsrq;
    private int mLteRssnr;
    private int mLteCqi;
    private int mTdScdmaRscp; // Valid values are -24...-120dBm or INVALID if unknown
    private int mWcdmaSignalStrength;
    private int mWcdmaRscpAsu;  // the WCDMA RSCP in ASU as reported from the HAL
    private int mWcdmaRscp;     // the WCDMA RSCP in dBm
...
}
 
分析:
由TelephonyManager.java中listen()方法可知,实际调用的是
registry.listenForSubscriber()
@ TelephonyManager.java
public void listen (PhoneStateListener listener, int events) {
         ...
        ITelephonyRegistry registry = getTelephonyRegistry();
           
        if (registry != null ) {
                registry.listenForSubscriber(listener.mSubId, getOpPackageName(),
                        listener.callback, events, notifyNow);
       }
else {
                Rlog.w(TAG,
"telephony registry not ready." );
            }

    }
ITelephonyRegistry的实现类为
TelephonyRegistry.java
@TelephonyRegistry.java
    @Override

    public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback,
            int events, boolean notifyNow) {
        listen(pkgForDebug, callback, events, notifyNow, subId);
    }

    private void listen(String callingPackage, IPhoneStateListener callback, int events,
            boolean notifyNow, int subId) {
        ...
            int phoneId = SubscriptionManager.getPhoneId(subId);
            synchronized (mRecords) {
                // register
                IBinder b = callback.asBinder();
                Record r = add(b);

                if (r == null) {
                    return;
                }

                r.context = mContext;
                r.callback = callback;//这里将callback加到Record中
                r.callingPackage = callingPackage;
                r.callerUid = Binder.getCallingUid();
                r.callerPid = Binder.getCallingPid();      
          ...   
     }

看一下Record是什么?
@TelephonyRegistry.java   
    private Record add(IBinder binder) {

        Record r;
        synchronized (mRecords) {
            final int N = mRecords.size();
            for (int i = 0; i < N; i++) {
                r = mRecords.get(i);
                if (binder == r.binder) {
                    // Already existed.
                    return r;
                }
            }
             r = new Record();
            r.binder = binder;
            r.deathRecipient = new TelephonyRegistryDeathRecipient(binder);

            try {
                binder.linkToDeath(r.deathRecipient, 0);
            } catch (RemoteException e) {
                if (VDBG) log("LinkToDeath remote exception sending to r=" + r + " e=" + e);
                // Binder already died. Return null.
                return null;
            }

             mRecords.add(r);
            if (DBG) log("add new record");
        }
        return r;
    }
由代码可知,每次注册一个监听事件,都new一个对应的Record,生成的Record又保存在一个ArrayList中,名为mRecords。
Record为TelephonyRegistry的内部类,这里保存一个PhoneStateListener对象   
private static class Record {

        Context context;

        String callingPackage;

        IBinder binder;

        TelephonyRegistryDeathRecipient deathRecipient;


        IPhoneStateListener callback;
               ...
        }

标记一下这里,因为之前这些分析于我们这篇帖子的主题ServiceStateTracker好像一点关系没有,所有我们下面分析一下ServiceStateTracker。
 
ServiceStateTracker的初始化在上面已经介绍过了,这里不再赘述,其中ServiceStateTracker的构造方法中有一个重要的调用

@ ServiceStateTracker.java
       public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci) {      
            ...         
         updatePhoneType();      
            ...    }   
 
      public void updatePhoneType() {      
     ...        
       mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));      
     ...    }

mCi是CommandsInterface的实例,CommandsInterface是一个接口类,这里的实现在RIL中。
@RIL.java
public class RIL extends BaseCommands implements CommandsInterface {      
     ...   
    @Override

    public void getSignalStrength(Message result) {
        IRadio radioProxy = getRadioProxy(result);
        if (radioProxy != null) {
            RILRequest rr = obtainRequest(RIL_REQUEST_SIGNAL_STRENGTH, result,
                    mRILDefaultWorkSource);

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

            try {
                radioProxy.getSignalStrength(rr.mSerial);
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR(rr, "getSignalStrength", e);
            }
        }
    }}


该方法是向modern获取信号,并向上返回结果,发送EVENT_GET_SIGNAL_STRENGTH消息。看一下解析
@ServiceStateTracker.java
    @Override
    public void handleMessage(Message msg) {      
       ...         
       case EVENT_GET_SIGNAL_STRENGTH:

                // This callback is called when signal strength is polled
                // all by itself

                if (!(mCi.getRadioState().isOn())) {
                    // Polling will continue when radio turns back on
                    return;
                }
                ar = (AsyncResult) msg.obj;
                onSignalStrengthResult(ar);

                queueNextSignalStrengthPoll();//重要! 延时一段时间再次向RIL发送请求获取信号值,循环获取。androidP默认时间变更为20s

                break;      
        ...    }

这里主要是onSignalStrengthResult(ar)方法。处理消息内容,发送给APP层。   
     protected boolean onSignalStrengthResult(AsyncResult ar) {      
     ...      
           if ((ar.exception == null) && (ar.result != null)) {

            mSignalStrength = (SignalStrength) ar.result;//接受消息返回的SignalStrength
            mSignalStrength.validateInput();//验证信号值是否合规
            if (dataRat == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN
                    && voiceRat == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
                mSignalStrength.fixType();
            } else {
                mSignalStrength.setGsm(isGsm);
            }
            mSignalStrength.setLteRsrpBoost(mSS.getLteEarfcnRsrpBoost());

            PersistableBundle config = getCarrierConfig();
            mSignalStrength.setUseOnlyRsrpForLteLevel(config.getBoolean(
                    CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL));
            mSignalStrength.setLteRsrpThresholds(config.getIntArray(
                    CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY));
            mSignalStrength.setWcdmaDefaultSignalMeasurement(config.getString(
                    CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING));
            mSignalStrength.setWcdmaRscpThresholds(config.getIntArray(
                    CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY));
        } else {
            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
            mSignalStrength = new SignalStrength(isGsm);
        }


        boolean ssChanged = notifySignalStrength();//发送phone通知SignalStrength状态改变

        
return ssChanged;
    }   
private SignalStrength mLastSignalStrength = null;

    protected boolean notifySignalStrength() {
        boolean notified = false;
        if (!mSignalStrength.equals(mLastSignalStrength)) {
            try {
                mPhone.notifySignalStrength();
                notified = true;
                mLastSignalStrength = mSignalStrength;
            } catch (NullPointerException ex) {
                loge("updateSignalStrength() Phone already destroyed: " + ex
                        + "SignalStrength not notified");
            }
        }
        return notified;

    }
@ Phone.java   
    public void notifySignalStrength() {

        mNotifier.notifySignalStrength(this);
    }


mNotifier为PhoneNotifier的实例,PhoneNotifier是一个接口类,这里具体实现类为DefaultPhoneNotifier.java

PS:mNotifier = new DefaultPhoneNotifier在PhoneFactory.makeDefaultPhone()中
@DefaultPhoneNotifier.java

    @Override
    public void notifySignalStrength(Phone sender) {
        int phoneId = sender.getPhoneId();
        int subId = sender.getSubId();
        if (DBG) {
            // too chatty to log constantly
            Rlog.d(LOG_TAG, "notifySignalStrength: mRegistry=" + mRegistry
                    + " ss=" + sender.getSignalStrength() + " sender=" + sender);
        }
        try {
            if (mRegistry != null) {
                mRegistry.notifySignalStrengthForPhoneId(phoneId, subId,
                        sender.getSignalStrength());
            }
        } catch (RemoteException ex) {
            // system process is dead
        }
    }

mRegistry为ITelephonyRegistry的实例,感觉是不是哪里见过?看一下上面 mark一下的位置。


@ TelephonyRegistry.java
 
public void notifySignalStrengthForPhoneId ( int phoneId, int subId,
                SignalStrength signalStrength) {
   
...      
    synchronized (mRecords) {
            
        if (validatePhoneId(phoneId)) {
               
            if (VDBG) log( "notifySignalStrengthForPhoneId: valid phoneId=" + phoneId);
           mSignalStrength[phoneId] = signalStrength;
               
           for (Record r : mRecords) {
                    
               if (VDBG) {
                        log( "notifySignalStrengthForPhoneId: r=" + r + " subId=" + subId
                                + " phoneId=" + phoneId + " ss=" + signalStrength);

                    }
                    
            if (r.matchPhoneStateListenerEvent(
                                PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) &&
                            idMatch(r.subId, subId, phoneId)) {
                        
             try {
                          
                  r.callback.onSignalStrengthsChanged( new SignalStrength(signalStrength));
                }
catch (RemoteException ex) {
                            mRemoveList.add(r.binder);
                }

     }         
...}
首先遍历mRecords集合,匹配PhoneStateListener.LISTEN_SIGNAL_STRENGTHS常量,调用r.callback.onSignalStrengthsChanged方法。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!