Android S Preferred network type設定流程
該文件來自根據原始碼的推論,並沒有實際的Log佐證。
1 入口
使用者可選擇的介面最終會使用如下配置開關:
/packages/apps/Settings/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@Override public boolean onPreferenceChange(Preference preference, Object object) { final int newPreferredNetworkMode = Integer.parseInt((String) object); final ListPreference listPreference = (ListPreference) preference; if (mTelephonyManager.setPreferredNetworkTypeBitmask( MobileNetworkUtils.getRafFromNetworkType(newPreferredNetworkMode))) { mBuilder.setPreferenceValueAndSummary(newPreferredNetworkMode); listPreference.setValue(Integer.toString(mBuilder.getSelectedEntryValue())); listPreference.setSummary(mBuilder.getSummary()); return true; } return false; }
2 Framework流程
/frameworks/base/telephony/java/android/telephony/TelephonyManager.java
/** * Set the preferred network type bitmask but if {@link #setAllowedNetworkTypes} has been set, * only the allowed network type will set to the modem. * * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()} * * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling * app has carrier privileges (see {@link #hasCarrierPrivileges}). * <p> * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported} * ({@link TelephonyManager#CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK}) returns true, then * setAllowedNetworkTypesBitmap is used on the radio interface. Otherwise, * setPreferredNetworkTypesBitmap is used instead. * * @param networkTypeBitmask The bitmask of preferred network types. * @return true on success; false on any failure. * @hide * @deprecated Use {@link #setAllowedNetworkTypesForReason} instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @SystemApi public boolean setPreferredNetworkTypeBitmask(@NetworkTypeBitMask long networkTypeBitmask) { try { ITelephony telephony = getITelephony(); if (telephony != null) { return telephony.setAllowedNetworkTypesForReason(getSubId(), TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, networkTypeBitmask); } } catch (RemoteException ex) { Rlog.e(TAG, "setPreferredNetworkTypeBitmask RemoteException", ex); } return false; }
/packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java
/** * Set the allowed network types of the device and * provide the reason triggering the allowed network change. * * @param subId the id of the subscription. * @param reason the reason the allowed network type change is taking place * @param allowedNetworkTypes the allowed network types. * @return true on success; false on any failure. */ @Override public boolean setAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason, @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes) { TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege( mApp, subId, "setAllowedNetworkTypesForReason"); if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) { loge("setAllowedNetworkTypesForReason: Invalid allowed network type reason: " + reason); return false; } if (!SubscriptionManager.isUsableSubscriptionId(subId)) { loge("setAllowedNetworkTypesForReason: Invalid subscriptionId:" + subId); return false; } log("setAllowedNetworkTypesForReason: " + reason + " value: " + TelephonyManager.convertNetworkTypeBitmaskToString(allowedNetworkTypes)); if (allowedNetworkTypes == getPhoneFromSubId(subId).getAllowedNetworkTypes(reason)) { log("setAllowedNetworkTypesForReason: " + reason + "does not change value"); return true; } final long identity = Binder.clearCallingIdentity(); try { Boolean success = (Boolean) sendRequest( CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON, new Pair<Integer, Long>(reason, allowedNetworkTypes), subId); if (DBG) log("setAllowedNetworkTypesForReason: " + (success ? "ok" : "fail")); return success; } finally { Binder.restoreCallingIdentity(identity); } }
case CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON:
request = (MainThreadRequest) msg.obj;
onCompleted = obtainMessage(EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE,
request);
Pair<Integer, Long> reasonWithNetworkTypes =
(Pair<Integer, Long>) request.argument;
getPhoneFromRequest(request).setAllowedNetworkTypes(
reasonWithNetworkTypes.first,
reasonWithNetworkTypes.second,
onCompleted);
break;
/frameworks/opt/telephony/src/java/com/android/internal/telephony/Phone.java
/**
* Requests to set the allowed network types for a specific reason
*
* @param reason reason to configure allowed network type
* @param networkTypes one of the network types
*/
public void setAllowedNetworkTypes(@TelephonyManager.AllowedNetworkTypesReason int reason,
@TelephonyManager.NetworkTypeBitMask long networkTypes, Message response) {
int subId = getSubId();
if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) {
loge("setAllowedNetworkTypes: Invalid allowed network type reason: " + reason);
AsyncResult.forMessage(response, null,
new CommandException(CommandException.Error.INVALID_ARGUMENTS));
response.sendToTarget();
return;
}
if (!SubscriptionManager.isUsableSubscriptionId(subId)
|| !mIsAllowedNetworkTypesLoadedFromDb) {
loge("setAllowedNetworkTypes: no sim or network type is not loaded. SubscriptionId: "
+ subId + ", isNetworkTypeLoaded" + mIsAllowedNetworkTypesLoadedFromDb);
AsyncResult.forMessage(response, null,
new CommandException(CommandException.Error.MISSING_RESOURCE));
response.sendToTarget();
return;
}
String mapAsString = "";
synchronized (mAllowedNetworkTypesForReasons) {
mAllowedNetworkTypesForReasons.put(reason, networkTypes);
mapAsString = mAllowedNetworkTypesForReasons.keySet().stream()
.map(key -> convertAllowedNetworkTypeMapIndexToDbName(key) + "="
+ mAllowedNetworkTypesForReasons.get(key))
.collect(Collectors.joining(","));
}
SubscriptionManager.setSubscriptionProperty(subId,
SubscriptionManager.ALLOWED_NETWORK_TYPES,
mapAsString);
logd("setAllowedNetworkTypes: SubId" + subId + ",setAllowedNetworkTypes " + mapAsString);
updateAllowedNetworkTypes(response);
notifyAllowedNetworkTypesChanged(reason);
}
Phone.java的如下方法不僅會在配置的時候呼叫,在其他情況也會被呼叫:
protected void updateAllowedNetworkTypes(Message response) {
int modemRaf = getRadioAccessFamily();
if (modemRaf == RadioAccessFamily.RAF_UNKNOWN) {
Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: "
+ modemRaf);
if (response != null) {
CommandException ex;
ex = new CommandException(CommandException.Error.GENERIC_FAILURE);
AsyncResult.forMessage(response, null, ex);
response.sendToTarget();
}
return;
}
int filteredRaf = (int) (modemRaf & getEffectiveAllowedNetworkTypes());
logd("setAllowedNetworkTypes: modemRafBitMask = " + modemRaf
+ " ,modemRaf = " + TelephonyManager.convertNetworkTypeBitmaskToString(modemRaf)
+ " ,filteredRafBitMask = " + filteredRaf
+ " ,filteredRaf = " + TelephonyManager.convertNetworkTypeBitmaskToString(
filteredRaf));
mCi.setAllowedNetworkTypesBitmap(filteredRaf, response);
mPreferredNetworkTypeRegistrants.notifyRegistrants();
}
最終會呼叫:
/frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java
@Override
public void setAllowedNetworkTypesBitmap(
@TelephonyManager.NetworkTypeBitMask int networkTypeBitmask, Message result) {
IRadio radioProxy = getRadioProxy(result);
if (radioProxy != null) {
if (mRadioVersion.less(RADIO_HAL_VERSION_1_6)) {
// For older HAL, redirects the call to setPreferredNetworkType.
setPreferredNetworkType(
RadioAccessFamily.getNetworkTypeFromRaf(networkTypeBitmask), result);
return;
}
android.hardware.radio.V1_6.IRadio radioProxy16 =
(android.hardware.radio.V1_6.IRadio) radioProxy;
RILRequest rr = obtainRequest(RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP, result,
mRILDefaultWorkSource);
if (RILJ_LOGD) {
riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
}
mAllowedNetworkTypesBitmask = networkTypeBitmask;
try {
radioProxy16.setAllowedNetworkTypesBitmap(rr.mSerial,
convertToHalRadioAccessFamily(mAllowedNetworkTypesBitmask));
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "setAllowedNetworkTypeBitmask", e);
}
}
}
3 RILD流程
3.1 原始碼
這裡假設RILC最終會呼叫:
/device/google/cuttlefish/guest/hals/ril/reference-libril/ril_service.cpp
Return<void> RadioImpl_1_6::setAllowedNetworkTypesBitmap(
uint32_t serial, hidl_bitfield<RadioAccessFamily> networkTypeBitmap) {
#if VDBG
RLOGD("setAllowedNetworkTypesBitmap: serial %d", serial);
#endif
dispatchInts(serial, mSlotId, RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP, 1, networkTypeBitmap);
return Void();
}
等Modem有返回時,使用如下方法返回給Framework:
/frameworks/opt/telephony/src/java/com/android/internal/telephony/RadioResponse.java
private void responseVoid_1_6(android.hardware.radio.V1_6.RadioResponseInfo responseInfo) {
RILRequest rr = mRil.processResponse_1_6(responseInfo);
if (rr != null) {
Object ret = null;
if (responseInfo.error == RadioError.NONE) {
sendMessageResponse(rr.mResult, ret);
}
mRil.processResponseDone_1_6(rr, responseInfo, ret);
}
}
@Override
public void setAllowedNetworkTypesBitmapResponse(
android.hardware.radio.V1_6.RadioResponseInfo info) {
responseVoid_1_6(info);
}
3.2 流程圖
4 參考文件
Android原始碼
http://aospxref.com/android-12.0.0_r3/
http://aosp.opersys.com/xref/android-12.0.0_r2/
版權宣告:本文為 無痕1024 原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結和本宣告。
本文連結:https://www.cnblogs.com/wuhen1024/p/16057896.html