RIL signal strength in AOSP status bar

Recently I had to verify an issue related to RIL signal strength shown in AOSP status bar, so I took a look at how it is transmitted from the native ril to the signal strength icon.

Ril signal

RIL signal strength: where to start from?

We can start from the two opposite sides.

The lower one is quite clear: it is the native ril, with request RIL_REQUEST_SIGNAL_STRENGTH (or the related unsolicited) defined in hardware/ril/include/telephony/ril.h.

The other side belongs to the signal strength icon in the status bar: its behavior is defined in the systemUI framework status bar source code frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java

Class MobileSignalController takes care of listening to the signal strength changes (onSignalStrengthsChanged) and updating the UI (updateTelephony). The value for updating the signal strength icon is is given by the SignalStrength class method getLevel

I was mainly interested in the 3GPP technology that are covered by this piece of code:

if (isGsm) {
  level = getLteLevel();
  if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    level = getTdScdmaLevel();
    if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
      level = getGsmLevel();
    }
  }
}

This is a wise fallback that originates from the evolution of the various native ril signal strength structures.

As written above, the information available at the upper layer depends on how the native ril fills the signal strength structure and usually the one related to GSM (RIL_GW_SignalStrength) is always present: this is why it is the last step of the fallback.

However the native ril can fill the structure with wrong information, that could prevent this fallback to properly work: special care should be taken in setting invalid values when a technology should not be considered.

Last piece is what lies in the middle, converting the information coming from the native RIL in the SignalStrength structure: this can be found in frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java, function convertHalSignalStrength.

It is quite interesting how the range for gsm signal strength (mGsmSignalStrength field in SignalStrength class) is divided: this can be seen in method getGsmLevel:

// ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
// asu = 0 (-113dB or less) is very weak
// signal, its better to show 0 bars to the user in such cases.
// asu = 99 is a special case, where the signal strength is unknown.
int asu = getGsmSignalStrength();
if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD;
else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE;
else level = SIGNAL_STRENGTH_POOR;

Basically it seems to be not too much difficult to have signal bar at full scale!