carrier_config随卡配置

总结:

1.adb shell dumpsys carrier_config //可查看CarrierConfigManager中定义的变量

2.log关键字CarrierIdentifier,可知具体的mcc ,mnc ,spn,iccid,carrierId,specificCarrierId等值

3.配置文件位于packages/apps/CarrierConfig/assets /carrier_config_carrierid_XXX

4.优先级:

carrier_config_carrierid_ XXX > carrier_config_carrierid XXX > carrier_config_carrierid XXX > carrier_config_carrierid .xml > vendor.xml

5.可以在https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/refs/heads/main/assets/sdk29_carrier_id/carrier_list.textpb 查看mccmnc对应carrierID和carriername

  1. 改packages/apps/CarrierConfig/assets下的xml文件,只push CarrierConfig.apk不会生效,需刷system镜像

7.插入每一张运营商卡会在data/user_de/0/com.android.phone/files下生成对应的xml文件,因此push CarrierConfig.apk 需删掉该文件夹下的xml文件

8.carrierID和carriername 定义在packages\providers\TelephonyProvider\assets目录下,对应数据库链接content://carrier_id/all

代码以android10为例

命令:

adb shell dumpsys carrier_config //sim卡相关信息,具体来自类CarrierConfigManager

代码库:

/frameworks/opt/telephony

/frameworks/base/telephony

/packages/services/Telephony

/frameworks/base/core/java/android/service/carrier

/packages/apps/CarrierConfig

一.加载

SubscriptionInfoUpdater.java收到EVENT_SIM_LOADED

–》handleSimLoaded

–》 updateCarrierServices(loadedSlotId, IccCardConstants.INTENT_VALUE_ICC_LOADED);//loadedSlotId为传进的 slotId,通过打印handleSimLoaded可以知道

–》 configManager.updateConfigForPhoneId(slotId, simState); // 为app可调用的api接口

–》loader.updateConfigForPhoneId(phoneId, simState);

–》updateConfigForPhoneId(phoneId);

–》mHandler.sendMessage(mHandler.obtainMessage(EVENT_DO_FETCH_DEFAULT, phoneId, -1));发送EVENT_DO_FETCH_DEFAULT消息

–》final PersistableBundle config = restoreConfigFromXml(mPlatformCarrierConfigPackage, phoneId); //加载配置文件

分析mPlatformCarrierConfigPackage

mPlatformCarrierConfigPackage = mContext.getString(R.string.platform_carrier_config_package); //packages/services/Telephony/res/values/config.xml

定义为

com.android.carrierconfig //carrierconfig

二.第一次插卡

返回到处理EVENT_DO_FETCH_DEFAULT,第一次插卡时会走bindToConfigPackage,此时发送EVENT_CONNECTED_TO_DEFAULT消息

case EVENT_DO_FETCH_DEFAULT:{
final PersistableBundle config =
restoreConfigFromXml(mPlatformCarrierConfigPackage, phoneId);
if (config != null) {

mConfigFromDefaultApp[phoneId] = config;
Message newMsg = obtainMessage(EVENT_FETCH_DEFAULT_DONE, phoneId, -1);
newMsg.getData().putBoolean(“loaded_from_xml”, true);EVENT_CONNECTED_TO_DEFAULT
mHandler.sendMessage(newMsg);
} else {
if (bindToConfigPackage( //第一次插卡时,连接好服务后发送EVENT_CONNECTED_TO_DEFAULT
mPlatformCarrierConfigPackage,
phoneId,
EVENT_CONNECTED_TO_DEFAULT)) {
sendMessageDelayed(
obtainMessage(EVENT_BIND_DEFAULT_TIMEOUT, phoneId, -1),//发送EVENT_BIND_DEFAULT_TIMEOUT
BIND_TIMEOUT_MILLIS);
} else {
// Send broadcast if bind fails.
notifySubscriptionInfoUpdater(phoneId);
// TODO: We must call unbindService even if bindService returns false.
// (And possibly if SecurityException was thrown.)
loge(“binding to default app: "
+ mPlatformCarrierConfigPackage + " fails”);
}
}
break;
}

查看EVENT_CONNECTED_TO_DEFAULT的处理,resultReceiver 回调保存结果,getCarrierConfig获取运营商信息

case EVENT_CONNECTED_TO_DEFAULT:
{

final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId); //获取carrierId
final ResultReceiver resultReceiver =
new ResultReceiver(this) {
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
mContext.unbindService(conn);
// If new service connection has been created, this is stale.
if (mServiceConnection[phoneId] != conn) {
loge(“Received response for stale request.”);
return;
}
removeMessages(EVENT_FETCH_DEFAULT_TIMEOUT);
if (resultCode == RESULT_ERROR || resultData == null) {
// On error, abort config fetching.
loge(“Failed to get carrier config”);
notifySubscriptionInfoUpdater(phoneId);
return;
}
PersistableBundle config =
resultData.getParcelable(KEY_CONFIG_BUNDLE);
saveConfigToXml(
mPlatformCarrierConfigPackage, phoneId, config);
mConfigFromDefaultApp[phoneId] = config;
sendMessage(
obtainMessage(
EVENT_FETCH_DEFAULT_DONE, phoneId, -1));
}
};
// Now fetch the config asynchronously from the ICarrierService.
try {
ICarrierService carrierService =
ICarrierService.Stub.asInterface(conn.service);
carrierService.getCarrierConfig(carrierId, resultReceiver);
logWithLocalLog("fetch config for default app: "
+ mPlatformCarrierConfigPackage
+ " carrierid: " + carrierId.toString());
} catch (RemoteException e) {
loge("Failed to get carrier config from default app: " +
mPlatformCarrierConfigPackage + " err: " + e.toString());
mContext.unbindService(conn);
break; // So we don’t set a timeout.
}
sendMessageDelayed(
obtainMessage(EVENT_FETCH_DEFAULT_TIMEOUT, phoneId, -1),
BIND_TIMEOUT_MILLIS);
break;
}

在CarrierService.java中的getCarrierConfig会调用CarrierService.this.onLoadConfig(id)进行加载,具体由DefaultCarrierConfigService.java实现

public PersistableBundle onLoadConfig(CarrierIdentifier id) {
Log.d(TAG, “Config being fetched”);

for (String file : getApplicationContext().getAssets().list(“”)) { // /packages/apps/CarrierConfig/assets/目录
if (file.startsWith(CARRIER_ID_PREFIX + id.getSpecificCarrierId() + "")) { //carrier_config_carrierid_SpecificCarrierId
parser.setInput(getApplicationContext().getAssets().open(file), “utf-8”);
configBySpecificCarrierId = readConfigFromXml(parser, null);
break;
} else if (file.startsWith(CARRIER_ID_PREFIX + id.getCarrierId() + "")) {carrier_config_carrierid_CarrierId
parser.setInput(getApplicationContext().getAssets().open(file), “utf-8”);
configByCarrierId = readConfigFromXml(parser, null);
} else if (file.startsWith(CARRIER_ID_PREFIX + mccmncCarrierId + “_”)) {
parser.setInput(getApplicationContext().getAssets().open(file), “utf-8”);
configByMccMncFallBackCarrierId = readConfigFromXml(parser, null);
}
}

            // 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 configuration found.
            parser.setInput(getApplicationContext().getAssets().open(
                    MCCMNC_PREFIX + id.getMcc() + id.getMnc() + ".xml"), "utf-8");
            config = readConfigFromXml(parser, id);
        }

    }
    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 = readConfigFromXml(vendorInput, id);
        config.putAll(vendorConfig);
    }
    catch (IOException | XmlPullParserException e) {
        Log.e(TAG, e.toString());
    }

    return config;
}

id来自哪,返回CarrierConfigLoader中的 getCarrierIdentifierForPhoneId ,为一个CarrierIdentifier对象,包含mcc ,mnc ,spn,imsi,gid1,gid2,iccid,carrierId,specificCarrierId

private CarrierIdentifier getCarrierIdentifierForPhoneId(int phoneId) {

String spn = TelephonyManager.from(mContext).getSimOperatorNameForPhone(phoneId); //gsm.sim.operator.alpha, adb shell getprop “gsm.sim.operator.alpha”
String simOperator = TelephonyManager.from(mContext).getSimOperatorNumericForPhone(phoneId);//gsm.sim.operator.numeric
int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
int specificCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
// A valid simOperator should be 5 or 6 digits, depending on the length of the MNC.
if (simOperator != null && simOperator.length() >= 3) {
mcc = simOperator.substring(0, 3);
mnc = simOperator.substring(3);
}
Phone phone = PhoneFactory.getPhone(phoneId);
if (phone != null) {
imsi = phone.getSubscriberId(); //调用RIL.java中的getIMSIForApp 发送消息GET_IMSI到ril
gid1 = phone.getGroupIdLevel1();//
gid2 = phone.getGroupIdLevel2();
iccid = phone.getIccSerialNumber();//卡文件EF_ICCID = 0x2FE2
carrierId = phone.getCarrierId();
specificCarrierId = phone.getSpecificCarrierId();
}
return new CarrierIdentifier(mcc, mnc, spn, imsi, gid1, gid2, iccid, carrierId, specificCarrierId);
}

log中搜索关键字CarrierIdentifier,可知道具体的值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值