zoukankan      html  css  js  c++  java
  • Android Telephony —— 手机信号实时变化源码分析过程记录

    源码版本:4.4

    跳过InCallActivity等UI实现。先看service以及底层。

    1, 在frameworks/opt下面会发现如下文件列表:

    ./telephony/src/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
    ./telephony/src/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
    ./telephony/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
    ./telephony/src/java/com/android/internal/telephony/gsm/GsmLteServiceStateTracker.java
    ./telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java

    2, 可以直接进入./telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java 分析,很容易发现类似于如下的代码:

    619     /**
    620      * send signal-strength-changed notification if changed Called both for
    621      * solicited and unsolicited signal strength updates
    622      *
    623      * @return true if the signal strength changed and a notification was sent.
    624      */
    625     protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
    626         SignalStrength oldSignalStrength = mSignalStrength;
    627 
    628         // This signal is used for both voice and data radio signal so parse
    629         // all fields
    630 
    631         if ((ar.exception == null) && (ar.result != null)) {
    632             mSignalStrength = (SignalStrength) ar.result;
    633             mSignalStrength.validateInput();
    634             mSignalStrength.setGsm(isGsm);
    635         } else {
    636             log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
    637             mSignalStrength = new SignalStrength(isGsm);
    638         }
    639 
    640         return notifySignalStrength();
    641     }

      这里主要是结构体的初始化以及上下文环境的简单判断。我们继续追踪notifySignalStrength()

    229     private SignalStrength mLastSignalStrength = null;
    230     protected boolean notifySignalStrength() {
    231         boolean notified = false;
    232         synchronized(mCellInfo) {
    233             if (!mSignalStrength.equals(mLastSignalStrength)) {
    234                 try {
    235                     mPhoneBase.notifySignalStrength();
    236                     notified = true;
    237                 } catch (NullPointerException ex) {
    238                     loge("updateSignalStrength() Phone already destroyed: " + ex
    239                             + "SignalStrength not notified");
    240                 }
    241             }
    242         }
    243         return notified;
    244     }

    这里有mSignalStrength 和 mLastSignalStrength 两个和信号强度相关的量。算是找到切入点了,信号强度更新的中间点就是这里了。

    3,我们先向下分析看有什么可以学习的。 onSignalStrengthResult 是被  frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java中handleMessage在Message Type是    EVENT_GET_SIGNAL_STRENGTH的时候调用的:

     424             case EVENT_GET_SIGNAL_STRENGTH:
     425                 // This callback is called when signal strength is polled
     426                 // all by itself
     427 
     428                 if (!(mCi.getRadioState().isOn())) {
     429                     // Polling will continue when radio turns back on
     430                     return;
     431                 }
     432                 ar = (AsyncResult) msg.obj;
     433                 onSignalStrengthResult(ar, true);
     434                 queueNextSignalStrengthPoll();
     435 
     436                 break;

    4, 到这里就需要对RIL有一定的了解才好继续追下去。RIL的event传到上层之后主要通过一个叫做Registrant的机制分发的。

      我们跳到frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java中去。

      这里有主动去得到signalstrength的方法:

    1127     getSignalStrength (Message result) {
    1128         RILRequest rr
    1129                 = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result, mIs2ndRil);
    1130 
    1131         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
    1132 
    1133         send(rr);
    1134     }

      继续往下看,接受到底层发来的数据后通过Registrant Notification:

    2811             case RIL_UNSOL_SIGNAL_STRENGTH:
    2812                 // Note this is set to "verbose" because it happens
    2813                 // frequently
    2814                 if (RILJ_LOGV) unsljLogvRet(response, ret);
    2815 
    2816                 if (mSignalStrengthRegistrant != null) {
    2817                     mSignalStrengthRegistrant.notifyRegistrant(
    2818                                         new AsyncResult (null, ret, null));
    2819                 }
    2820             break;

    5, 继续追下去,我们看到有主动通过RIL_REQUEST_SIGNAL_STRENGTH去request signal strength的。

      所以直接在hardware/ril下搜关键字:RIL_REQUEST_SIGNAL_STRENGTH得到结果如下:

    ./include/telephony/ril.h:1388: * RIL_REQUEST_SIGNAL_STRENGTH
    ./include/telephony/ril.h:1402:#define RIL_REQUEST_SIGNAL_STRENGTH 19
    ./libril/ril.cpp:3758:        case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
    ./libril/ril_commands.h:36:    {RIL_REQUEST_SIGNAL_STRENGTH, dispatchVoid, responseRilSignalStrength},
    ./reference-ril/reference-ril.c:2093:        case RIL_REQUEST_SIGNAL_STRENGTH:
    ./reference-ril/ril.h:1388: * RIL_REQUEST_SIGNAL_STRENGTH
    ./reference-ril/ril.h:1402:#define RIL_REQUEST_SIGNAL_STRENGTH 19

      很明显是hardware/ril/reference-ril/reference-ril.c里面如下函数被调用去查询信号强度了,调用AT command等一看便知:

     839 static void requestSignalStrength(void *data, size_t datalen, RIL_Token t)
     840 {
     841     ATResponse *p_response = NULL;
     842     int err;
     843     char *line;
     844     int count =0;
     845     int numofElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
     846     int response[numofElements];
     847 
     848     err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response);
     849 
     850     if (err < 0 || p_response->success == 0) {
     851         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
     852         goto error;
     853     }
     854 
     855     line = p_response->p_intermediates->line;
     856 
     857     err = at_tok_start(&line);
     858     if (err < 0) goto error;
     859 
     860     for (count =0; count < numofElements; count ++) {
     861         err = at_tok_nextint(&line, &(response[count]));
     862         if (err < 0) goto error;
     863     }
     864 
     865     RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
     866 
     867     at_response_free(p_response);
     868     return;

    从上层追到下层基本告一段落,Telephony的其他功能的实现结构都一样,也可以同样通过上述思路去追踪。

    涉及到的源码路径基本有:

    frameworks/av

    frameworks/base

    frameworks/opt

    packages/apps

    hardware/ril

  • 相关阅读:
    Android自定义drawable(Shape)详解
    如何设置对话框的宽度和高度
    Android资料之-EditText中的inputType
    android4.0 禁止横竖屏切换使用 android:configChanges="orientation|keyboardHidden"无效的解决方法
    android ScrollView 充满屏幕
    治疗神经衰弱最有效的方法和药物是什么
    交换机和路由器的区别
    小众编程语言同样值得你关注
    RotateAnimation详解
    你可能没听过的 Java 8 中的 10 个特性
  • 原文地址:https://www.cnblogs.com/icxy/p/3953179.html
Copyright © 2011-2022 走看看