最开始
public int getGsmLevel() {
int level;
// 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;
if (DBG) log("getGsmLevel=" + level);
log("getGsmLevel=" + level);
return level;
}
然后转到
public int getLevel() {
int level;
if (isGsm) {
level = getLteLevel();
if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
log("matt2" + level);
level = getGsmLevel();
}
} else {
int cdmaLevel = getCdmaLevel();
int evdoLevel = getEvdoLevel();
if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* We don't know evdo, use cdma */
level = cdmaLevel;
} else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* We don't know cdma, use evdo */
level = evdoLevel;
} else {
/* We know both, use the lowest level */
level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
}
}
if (DBG) log("getLevel=" + level);
return level;
}
然后转到
public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
// Bin the strength.
int bin = signalStrength.getLevel();
Log.i("matts-notePhoneSignalStrengthLocked", "Phone Data Connection -> " );
updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
}
然后转到
public void notePhoneSignalStrength(SignalStrength signalStrength) {
enforceCallingPermission();
synchronized (mStats) {
Slog.i("matts-notePhoneSignalStrength", "SENDING BATTERY INFO:");
mStats.notePhoneSignalStrengthLocked(signalStrength);
}
}
然后转到
private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
long ident = Binder.clearCallingIdentity();
try {
mBatteryStats.notePhoneSignalStrength(signalStrength);
} catch (RemoteException e) {
/* The remote entity disappeared, we can safely ignore the exception. */
} finally {
Binder.restoreCallingIdentity(ident);
}
Intent intent = new Intent(TelephonyIntents2.ACTION_SIGNAL_STRENGTH_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Bundle data = new Bundle();
signalStrength.fillInNotifierBundle(data);
intent.putExtras(data);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
然后转到
public void notifySignalStrength(SignalStrength signalStrength) {
if (!checkNotifyPermission("notifySignalStrength()")) {
return;
}
synchronized (mRecords) {
mSignalStrength = signalStrength;
for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
try {
r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
}
if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
try {
int gsmSignalStrength = signalStrength.getGsmSignalStrength();
r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
: gsmSignalStrength));
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
}
}
handleRemoveListLocked();
}
broadcastSignalStrengthChanged(signalStrength);
}
然后转到
public void notifySignalStrength() {
mNotifier.notifySignalStrength(this);
}
然后转到
public void notifySignalStrength(Phone sender) {
try {
if (isPrimaryPhone(sender)) {
mRegistry.notifySignalStrength(sender.getSignalStrength());
} else {
mRegistry2.notifySignalStrength(sender.getSignalStrength());
}
} catch (RemoteException ex) {
// system process is dead
}
}
这个函数所在的class中有个
DefaultPhoneNotifier() {
mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));
}
TelephonyRegistry是ITelephonyRegistry.Stub的子类,作为service运行在system_server进程中,它会通知注册者。上面的DefaultPhoneNotifier运行在com.android.phone进程中,当信号强度值变化时,通过Service进行通知(service被感兴趣的注册者调用了listen,添加了回调函数。
在TelephonyManager.java中提供了API,应用程序可以监听各种事件,实际上它将感兴趣的监听者作为一条记录添加到service一侧的列表(跨进程)中,当有变化时,调用它们提供的回调函数,通知(跨进程)这些注册者。
TelephonyManager.java中的listen函数如下:
public void listen(PhoneStateListener listener, int events) {
if (isDefaultManager() == false) {
if (sRegistry2 == null) {
sRegistry2 = ITelephonyRegistry2.Stub.asInterface(ServiceManager.getService("telephony.registry2"));
}
}
String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
try {
Boolean notifyNow = true;
if (isDefaultManager()) {
sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
} else {
sRegistry2.listen(pkgForDebug, listener.callback, events, notifyNow);
}
} catch (RemoteException ex) {
// system process dead
} catch (NullPointerException ex) {
// system process dead
}
}
下面的代码就是调用的listen函数,收到event之后的回调处理函数是mPhoneStateListener
public NetworkController(Context context) {
mContext = context;
final Resources res = context.getResources();
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
mHasMobileDataFeature = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
mShowPhoneRSSIForData = res.getBoolean(R.bool.config_showPhoneRSSIForData);
mShowAtLeastThreeGees = res.getBoolean(R.bool.config_showMin3G);
mAlwaysShowCdmaRssi = res.getBoolean(
com.android.internal.R.bool.config_alwaysUseCdmaRssi);
// set up the default wifi icon, used when no radios have ever appeared
updateWifiIcons();
updateWimaxIcons();
// telephony
mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
mPhone.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_SERVICE_STATE
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
| PhoneStateListener.LISTEN_CALL_STATE
| PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
| PhoneStateListener.LISTEN_DATA_ACTIVITY);
下面就是回调函数的实现
<span style="font-size:18px;">PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
if (DEBUG) {
Slog.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
}
mSignalStrength = signalStrength;
updateTelephonySignalStrength();
refreshViews();
}</span>
在updateSignalStrength函数中,将根据得到的信息,设置适当的图标id,显示合适的图标。
如果上层app想要获取信号强度信息
case EVENT_POLL_SIGNAL_STRENGTH:
// Just poll signal strength...not part of pollState()
if (mIsScreenOn) {
mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
}
break;
getSignalStrength (Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result, mIs2ndRil);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
send(rr);
}
在ril.java中这边先创建了一个request然后用send函数发送给ril.c
<span style="font-size:18px;"> case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;</span>
查找
<span style="font-size:18px;">private Object
responseSignalStrength(Parcel p) {
// Assume this is gsm, but doesn't matter as ServiceStateTracker
// sets the proper value.
SignalStrength signalStrength = SignalStrength.makeSignalStrengthFromRilParcel(p);
return signalStrength;
}</span>