【Android Q】Android Q SIM_STATE_CHANGED无法获取slotId或者phoneId

这几天调试适配NFC部分热插NFC SIM激活SWP时。

发现,

总是无法成功,经过调试原来根本原因是SIM_STATE_CHANGED广播的Extra数据已经不再具有slotId, 拿不到。

接下来的流程跑步下去了。

发现QCOM 和MediaTek 基线都是如此。

异常log如下:

08-02 00:04:08.168  2463  2463 D NfcSimStateObserver: onReceive: android.intent.action.SIM_STATE_CHANGED
08-02 00:04:08.168  2463  2463 D NfcSimStateObserver: ACTION_SIM_STATE_CHANGED receiver with iccState = LOADED, simId = -1
08-02 00:04:08.168  2463  2463 D Nfc_SecureElementSelector: onSimStateChanged() - simId = -1 newPresenceState = 2 mUICC1State: Active mUICC2State: ? airplane: false
08-02 00:04:08.168  2463  2463 D Nfc_SecureElementSelector: onSimStateChanged() - simId not supported -1
08-02 00:04:08.507  2463  2463 D NfcSimStateObserver: onReceive: android.intent.action.SIM_STATE_CHANGED
08-02 00:04:08.507  2463  2463 D NfcSimStateObserver: ACTION_SIM_STATE_CHANGED receiver with iccState = LOADED, simId = -1
08-02 00:04:08.507  2463  2463 D Nfc_SecureElementSelector: onSimStateChanged() - simId = -1 newPresenceState = 2 mUICC1State: Active mUICC2State: ? airplane: false
08-02 00:04:08.507  2463  2463 D Nfc_SecureElementSelector: onSimStateChanged() - simId not supported -1

原来正常log如下:

08-09 06:49:57.206  4048  4048 D NfcSimStateObserver: onReceive: android.intent.action.SIM_STATE_CHANGED
08-09 06:49:57.206  4048  4048 D NfcSimStateObserver: ACTION_SIM_STATE_CHANGED receiver with iccState = LOADED, simId = 0
08-09 06:49:57.206  4048  4048 D Nfc_SecureElementSelector: onSimStateChanged() - simId = 0 newPresenceState = 2 mUICC1State: Available mUICC2State: ? airplane: false
08-09 06:49:57.206  4048  4048 D Nfc_SecureElementSelector: getIdofString() - str = SIM1 id = 81
08-09 06:49:57.206  4048  4048 D Nfc_SecureElementSelector: getUserDesiredSeId() - 0x81
08-09 06:49:57.207  4048  4048 D Nfc_SecureElementSelector: RefreshSeStatus(start, false) - nfceeid[0]: 0x81 conInfo[0]: 0x01, nfceeid[1]: 0x82 conInfo[1]: 0x01
08-09 06:49:57.207  4048  4048 D Nfc_SecureElementSelector: RefreshSeStatus() - not in Airplane mode, so using presence information SIM1=0x02, SIM2=0x00
08-09 06:49:57.207  4048  4048 D Nfc_SecureElementSelector: RefreshSeStatus() - mStActiveeSe = 0x00 mStActiveUicc = 0x00
08-09 06:49:57.207  4048  4048 D Nfc_SecureElementSelector: RefreshSeStatus(end) - mUICC1State: Available, mUICC2State: ?, meSEState: Available, mDHSEState: ?
08-09 06:49:57.207  4048  4048 D Nfc_SecureElementSelector: getActiveUiccValue() -  mStActiveUicc= 0
08-09 06:49:58.235  4048  4048 D Nfc_SecureElementSelector: RefreshSeStatus(start, false) - nfceeid[0]: 0x81 conInfo[0]: 0x00, nfceeid[1]: 0x82 conInfo[1]: 0x01
08-09 06:49:58.236  4048  4048 D Nfc_SecureElementSelector: RefreshSeStatus() - not in Airplane mode, so using presence information SIM1=0x02, SIM2=0x00
08-09 06:49:58.236  4048  4048 D Nfc_SecureElementSelector: RefreshSeStatus() - mStActiveeSe = 0x00 mStActiveUicc = 0x81
08-09 06:49:58.236  4048  4048 D Nfc_SecureElementSelector: RefreshSeStatus(end) - mUICC1State: Active, mUICC2State: ?, meSEState: Available, mDHSEState: ?
08-09 06:49:58.237  4048  4048 D NfcService: setRoutingTableDirty()

接下来跟踪发送SIM_STATE_CHANGED广播的出处。

/frameworks/opt/telephony/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java

///frameworks/opt/telephony/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java

    @UnsupportedAppUsage
    private void broadcastSimStateChanged(int slotId, String state, String reason) {
        Intent i = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
        // TODO - we'd like this intent to have a single snapshot of all sim state,
        // but until then this should not use REPLACE_PENDING or we may lose
        // information
        // i.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
        //         | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        i.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
        i.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, state);
        i.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);

        SubscriptionManager.putPhoneIdAndSubIdExtra(i, slotId); //赋值SLOT ID的地方
        logd("Broadcasting intent ACTION_SIM_STATE_CHANGED " + state + " reason " + reason +
                " for phone: " + slotId);
        IntentBroadcaster.getInstance().broadcastStickyIntent(i, slotId);
    }

接着看SubsciptionManager的putPhoneIdAndSubIdExtra()方法。

 

///frameworks/base/telephony/java/android/telephony/SubscriptionManager.java
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
        int[] subIds = SubscriptionManager.getSubId(phoneId);
        if (subIds != null && subIds.length > 0) {
            putPhoneIdAndSubIdExtra(intent, phoneId, subIds[0]);
        } else {
            logd("putPhoneIdAndSubIdExtra: no valid subs");
            intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
        }
    }

    /** @hide */
    @UnsupportedAppUsage
    public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) {
        if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
        intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId);
        intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
    }

经过对比,可以发现方法上多了个注释。

@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)

这个注释的意思是,Android P(API 28)之前(含P)才支持。

 

【解决方案】

直接从phoneid中拿,拿不到直接默认slotid=0.

///packages/apps/NfcSt/src/com/android/nfc/st/NfcSimStateObserver.java
        if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
            String iccState;
            int simId;
            iccState = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
            //[NFC] Begin modify by xxxie for T7753592 on 2019/08/02
            // because of SubscriptionManager send sticky broadcast SIM_STATE_CHANGED
            // UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) definition, so that
            // there are no more 'slot' value in ExtraData
            //simId = intent.getIntExtra(PhoneConstants.SLOT_KEY, -1);
            simId = intent.getIntExtra(PhoneConstants.PHONE_KEY, -1);
            //[NFC] End modify by xxxie for T7753592 on 2019/08/02
            if (iccState == null) {
                iccState = "NULL";
            }
            Log.d(TAG, "ACTION_SIM_STATE_CHANGED receiver with iccState = " + iccState +
                    ", simId = " + simId);
            //[NFC] Begin modify by xxxie for T7753592 on 2019/08/02
            if (-1 == simId) {
                simId = 0;//拿不到默认给卡1
            }
            //[NFC] End modify by xxxie for T7753592 on 2019/08/02
            if (iccState.equals(IccCardConstants.INTENT_VALUE_ICC_LOADED)) {

这样就能暂时解决这个问题,但是倘若支持双NFC SIM的情况,单单热插slot2(SIM2),这将会是一个问题。

 

【Google解决方案】

经过当前最新的MTK baseline alps-trunk-q0.bsp-pre11.1查看,发现SubscriptionInfoUpdater已经更新,更新日期是2019/04/18。

这个提交的人是Jordan Liu(jminjie@google.com)。

发现自己又好像白干活了。。。

SubscriptionInfoUpdater add actual slotid int SIM_STATE_CHANGED extra by Jordan Liu

 

不知道为什么不干脆将SubscriptionManager.java中的接口开放,而是临时自己打个patch。

现在Android Q还尚不稳定,不知后边将如何变化。

静观其变吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值