重置网络后HD不显示的逆推

简介:Android N

第一步

分析初始Log

04-23 20:27:29.713  6464  6464 D TelephonyManager: factoryReset: subId=2     //重置
04-23 20:27:31.546  6464  6464 D ImsManager: updateImsServiceConfig: turnOnIms     //更新Ims

04-23 20:26:29.901  3004  3004 I QImsService: ImsConfigImpl : SetServiceStatus = 0 13 2     //正常情况,打开
04-23 20:26:30.522  3004  3004 I QImsService: ImsConfigImpl : SetServiceStatus = 3 13 2

04-23 20:29:07.947  3004  3004 I QImsService: ImsConfigImpl : SetServiceStatus = 0 13 0     //异常情况,关闭
04-23 20:29:07.994  3004  3004 I QImsService: ImsConfigImpl : SetServiceStatus = 3 13 2

此处为高通平台的Log,然后我们要找打印Log的地方。

第二步

找Log出处

从Log打印可知,是在ImsConfigImpl.java里面调用的。
此处为高通的代码,不方便粘贴,能找到的话,分析起来就方便很多了。

第三步

查看异常原因

我们看到此处SetServiceStatus = 0 13 0 异常,并继续查看源码,找到对应的类型。
第一个 0:CALL_TYPE 类型
第二个 13:网络类型
第三个 0:打开类型(一般0是关闭)

此处为高通代码,想要了解的童鞋,可自行查找。

第四步

查看setFeatureValue情况

04-23 20:27:31.326  6464  6464 D ImsConfig: setFeatureValue: feature = 0, network =13, value =0, listener =null //异常,此处value =0
04-23 20:27:31.447  6464  6464 D ImsConfig: setFeatureValue: feature = 2, network =18, value =0, listener =null
04-23 20:27:31.540  6464  6464 D ImsConfig: setFeatureValue: feature = 1, network =13, value =1, listener =null

04-23 20:31:07.853  6464  6464 D ImsConfig: setFeatureValue: feature = 0, network =13, value =1, listener =null //正常,此处value =1
04-23 20:31:07.935  6464  6464 D ImsConfig: setFeatureValue: feature = 2, network =18, value =0, listener =null
04-23 20:31:07.992  6464  6464 D ImsConfig: setFeatureValue: feature = 1, network =13, value =1, listener =null

可以看到feature没有设置成功。

第五步

查看setFeatureValue的源码

看一下源码,在哪里调用的:

public void setFeatureValue(int feature, int network, int value,
        ImsConfigListener listener) throws ImsException {
    if (DBG) {
        Rlog.d(TAG, "setFeatureValue: feature = " + feature + ", network =" + network +
                ", value =" + value + ", listener =" + listener);
    }
    try {
        miConfig.setFeatureValue(feature, network, value, listener);
    } catch (RemoteException e) {
        throw new ImsException("setFeatureValue()", e,
                ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
    }
}

在这里可以看到setFeatureValue()前后的调用情况。

第六步

调用setFeatureValue的地方

继续下一步调用(这里调用的地方比较多,但是我们只关注VoLte的调用就可以):

    private boolean updateVolteFeatureValue() throws ImsException {
        boolean available = isVolteEnabledByPlatform(mContext);
        boolean enabled = isEnhanced4gLteModeSettingEnabledByUser(mContext);
        boolean isNonTty = isNonTtyOrTtyOnVolteEnabled(mContext);
        boolean isFeatureOn = available && enabled && isNonTty;

        log("updateVolteFeatureValue: available = " + available
                + ", enabled = " + enabled
                + ", nonTTY = " + isNonTty);

        getConfigInterface().setFeatureValue( //在这里调用
                ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
                TelephonyManager.NETWORK_TYPE_LTE,
                isFeatureOn ?
                        ImsConfig.FeatureValueConstants.ON :
                        ImsConfig.FeatureValueConstants.OFF,
                mImsConfigListener);

        return isFeatureOn;
    }

第七步

查看available的值

04-23 20:27:31.322  6464  6464 D ImsManager: updateVolteFeatureValue: available = false, enabled = true, nonTTY = true

available = false,VoLte故不可用。
从第六步知道 boolean available = isVolteEnabledByPlatform(mContext),继续深追。

第八步

查看isVolteEnabledByPlatform()

    public static boolean isVolteEnabledByPlatform(Context context) {
        if (SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
                PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT) == 1) {
            return true;
        }

        return context.getResources().getBoolean(
                com.android.internal.R.bool.config_device_volte_available)
                && getBooleanCarrierConfig(context,
                        CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL)
                && isGbaValid(context);
    }

这里要把
1)context.getResources().getBoolean(com.android.internal.R.bool.config_device_volte_available);
2)getBooleanCarrierConfig(context, CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL);
3)isGbaValid(context).
各个调用的值打印出来看

第九步:

添加Log,逐步分析:

04-17 17:14:24.146  4832  4832 D TelephonyManager: factoryReset: subId=1
04-17 17:16:40.270  4832  4832 D TelephonyManager: factoryReset: subId=1

04-17 17:14:24.555  4832  4832 D ImsManager: isVolteEnabledByPlatform :context = com.android.settings.SubSettings@33ff9f3
04-17 17:14:24.555  4832  4832 D ImsManager: isVolteEnabledByPlatform :config_device_volte_available = true
04-17 17:14:24.559  4832  4832 D ImsManager: isVolteEnabledByPlatform :KEY_CARRIER_VOLTE_AVAILABLE_BOOL = false
04-17 17:14:24.563  4832  4832 D ImsManager: isVolteEnabledByPlatform :isGbaValid = true

可以看到此处的KEY_CARRIER_VOLTE_AVAILABLE_BOOL为false,至此可以定位问题的源头了。

第十步

查看getBooleanCarrierConfig()

private static boolean getBooleanCarrierConfig(Context context, String key) {
        CarrierConfigManager configManager = (CarrierConfigManager) context.getSystemService(
                Context.CARRIER_CONFIG_SERVICE);
        PersistableBundle b = null;
        int[] subId = SubscriptionManager.getSubId(mImsPhoneId);
        SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
        if (configManager != null && subId != null && subscriptionManager != null &&
                subscriptionManager.isActiveSubId(subId[0])) {
            b = configManager.getConfigForSubId(subId[0]);
        }
        if (b != null) {
            return b.getBoolean(key);
        } else {
            // Return static default defined in CarrierConfigManager.
            return CarrierConfigManager.getDefaultConfig().getBoolean(key);
        }
    }

看源码,好像也没什么问题,那么问题到底在哪里呢?

第十一步

打印各个变量,分析其值

打印Log04-20 14:17:39.625  2984  2984 D ImsManager: getBooleanCarrierConfig :mImsPhoneId = 1
04-20 14:17:39.625  2984  2984 D ImsManager: getBooleanCarrierConfig :subId[0] = 1
04-20 14:17:39.626  2984  2984 D ImsManager: getBooleanCarrierConfig :isActiveSubId = true

04-20 14:17:39.715  3045  3045 D ImsManager: getBooleanCarrierConfig :mImsPhoneId = 0
04-20 14:17:39.715  3045  3045 D ImsManager: getBooleanCarrierConfig :subId[0] = 2147483643
04-20 14:17:39.716  3045  3045 D ImsManager: getBooleanCarrierConfig :isActiveSubId = false

可以看到 这里的mImsPhoneId一瞬间从1变到0 是问题的关键所在。

移动卡卡二时,mImsPhoneId 为 0,(此处本该为 1 ),导致subId[0] = 2147483643,进而isActiveSubId返回 false,
最后不能正确返回参数。

private static int mImsPhoneId; (此处的修改 是针对各个开发商,并非正式版)
至于为什么 卡一的时候,没有这个错误,是因为 这个 mImsPhoneId 是静态的,默认为0,所以才不会出问题。
ResetNetwork 里面调用的时候,是新 new 的 ImsManager,而不是之前 赋值过的 Ims,所以才会造成这样的问题。

第十二步

尝试修改

1)调用getDefaultVoicePhoneId,双卡时,通话卡的选择会影响这个值,此方案不通过。
2)调用getDefaultDataPhoneId,测试通过,源码如下:

ImsManager open() ---> mImsPhoneId = imsPhoneId;
ImsPhoneCallTracker getImsService() --- > 
mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
    mServiceId = mImsManager.open(ImsServiceClass.MMTEL,
            createIncomingCallPendingIntent(),
            mImsConnectionStateListener, mPhone.getPhoneId());

此处的mPhone.getPhoneId(),即为getDefaultDataPhoneId()
mPhone即为默认数据卡对应的phone。

但是,mImsPhoneId 可能还受 高通其他代码 的影响,所以不建议这样修改。

第十三步

正式修改

解决方法是:把mImsPhoneId 写入系统属性,然后读取的时候,直接从系统属性值里面读出来。
在给mImsPhoneId 赋值之后,直接调用SystemProperties.set() 将其写到系统属性里面去。

具体代码就不多说了,就是在这里给大家提个解决的思路。

最后,还是要多练习,多看源码,累计经验,才能知道第一步 是经过了多少失败的分析


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值