问题
有的MVNO卡没有配置过 CarrierConfig及相关 overlay,但是实际运行的时候功能被override了 ,此时可能是因为CarrierConfig用了父类(同MCCMNC等情况)的配置,因此在直接查找对应卡cid或mccmnc+mvno属性时候的CarrierConfig是没办法找到影响功能的配置项的。
代码逻辑
fw/opt/telephony
frameworks/opt/telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java
AOSP源码getServiceProviderName接口,从CarrierConfig中读取配置是否覆写运营商名称,两个KEY共同控制
- KEY_CARRIER_NAME_OVERRIDE_BOOL
- KEY_CARRIER_NAME_STRING
//Android S version example
//frameworks/opt/telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java
/**
* Get the service provider name with highest priority among various source.
* @return service provider name.
*/
public String getServiceProviderName() {
// BrandOverride has higher priority than the carrier config
String operatorBrandOverride = getOperatorBrandOverride();
if (!TextUtils.isEmpty(operatorBrandOverride)) {
return operatorBrandOverride;
}
String carrierName = mIccRecords != null ? mIccRecords.getServiceProviderName() : "";
PersistableBundle config = getCarrierConfig();
if (config.getBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL)
|| TextUtils.isEmpty(carrierName)) {
return config.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
}
return carrierName;
}
CarrierConfig APP
packages/apps/CarrierConfig/src/com/android/carrierconfig/
DefaultCarrierConfigService.java 中通过loadConfig接口加载出对应卡的配置
- loadConfig -> readConfigFromXml
加载先后,越后加载的会覆盖前面的
- id.getSpecificCarrierId()
- id.getCarrierId()
- mccmncCarrierId
※然后会有优先级加载配置,所以会
public class DefaultCarrierConfigService extends CarrierService {
private static final String CARRIER_ID_PREFIX = "carrier_config_carrierid_";
private static final String MCCMNC_PREFIX = "carrier_config_mccmnc_";
private static final String NO_SIM_CONFIG_FILE_NAME = "carrier_config_no_sim.xml";//无卡配置的文件名
private XmlPullParserFactory mFactory;
public DefaultCarrierConfigService() {
Log.d(TAG, "Service created");
mFactory = null;
}
PersistableBundle loadConfig(XmlPullParser parser, @Nullable CarrierIdentifier id) {
PersistableBundle config = new PersistableBundle();
// OEM customizable filter for carrier requirements not related to hardware/vendor SKU.
String sku = getApplicationContext().getResources().getString(R.string.sku_filter);
if (id == null) {
try {
// Load no SIM config if carrier id is not set.
parser.setInput(getApplicationContext().getAssets().open(
NO_SIM_CONFIG_FILE_NAME), "utf-8");
config = readConfigFromXml(parser, null, sku);
// Treat vendor_no_sim.xml as if it were appended to the no sim config file.
XmlPullParser vendorInput =
getApplicationContext().getResources().getXml(R.xml.vendor_no_sim);
PersistableBundle vendorConfig = readConfigFromXml(vendorInput, null, sku);
config.putAll(vendorConfig);
}
catch (IOException|XmlPullParserException e) {
Log.e(TAG, "Failed to load config for no SIM", e);
}
return config;
}
try {
if (id.getCarrierId() != TelephonyManager.UNKNOWN_CARRIER_ID) {
PersistableBundle configByCarrierId = new PersistableBundle();
PersistableBundle configBySpecificCarrierId = new PersistableBundle();
PersistableBundle configByMccMncFallBackCarrierId = new PersistableBundle();
TelephonyManager telephonyManager = getApplicationContext()
.getSystemService(TelephonyManager.class);
int mccmncCarrierId = telephonyManager
.getCarrierIdFromMccMnc(id.getMcc() + id.getMnc());
for (String file : getApplicationContext().getAssets().list("")) {
if (file.startsWith(CARRIER_ID_PREFIX + id.getSpecificCarrierId() + "_")) {
parser.setInput(getApplicationContext().getAssets().open(file), "utf-8");
configBySpecificCarrierId = readConfigFromXml(parser, null, sku);
break;
} else if (file.startsWith(CARRIER_ID_PREFIX + id.getCarrierId() + "_")) {
parser.setInput(getApplicationContext().getAssets().open(file), "utf-8");
configByCarrierId = readConfigFromXml(parser, null, sku);
} else if (file.startsWith(CARRIER_ID_PREFIX + mccmncCarrierId + "_")) {
parser.setInput(getApplicationContext().getAssets().open(file), "utf-8");
configByMccMncFallBackCarrierId = readConfigFromXml(parser, null, sku);
}
}
// priority: specific carrier id > carrier id > mccmnc fallback carrier id
if (!configBySpecificCarrierId.isEmpty()) {
config = configBySpecificCarrierId;
} else if (!configByCarrierId.isEmpty()) {
config = configByCarrierId;
} else if (!configByMccMncFallBackCarrierId.isEmpty()) {
config = configByMccMncFallBackCarrierId;
}
}
if (config.isEmpty()) {
// fallback to use mccmnc.xml when there is no carrier id named config found.
parser.setInput(getApplicationContext().getAssets().open(
MCCMNC_PREFIX + id.getMcc() + id.getMnc() + ".xml"), "utf-8");
config = readConfigFromXml(parser, id, sku);
}
}
catch (IOException | XmlPullParserException e) {
Log.d(TAG, e.toString());
// We can return an empty config for unknown networks.
config = new PersistableBundle();
}
// Treat vendor.xml as if it were appended to the carrier config file we read.
XmlPullParser vendorInput = getApplicationContext().getResources().getXml(R.xml.vendor);
try {
PersistableBundle vendorConfig = readConfigFromXm