Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a4d1ff9 authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Do not push carrier configs when they are not for an identified carrier

1) Rely on new subId specific indications for loading carrier config
instead of relying on CARRIER_CONFIG_CHANGED, since these indications
are based on CARRIER_CONFIG_CHANGED and should happen after the
ImsService is configured.

2) Ensure we remove the cache when the subId changes to ensure we do not
use invalid cache information in scenarios where the subscription is
removed.

Bug: 167996816
Test: atest FrameworksTelephonyTests
Merged-In: Ic2e2a177bf61abf545514683c3c24dc269119415
Change-Id: Ic2e2a177bf61abf545514683c3c24dc269119415
parent e41bbb69
Loading
Loading
Loading
Loading
+57 −35
Original line number Diff line number Diff line
@@ -188,7 +188,9 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
    private final Map<String, CallQualityMetrics> mCallQualityMetrics = new ConcurrentHashMap<>();
    private final ConcurrentLinkedQueue<CallQualityMetrics> mCallQualityMetricsHistory =
            new ConcurrentLinkedQueue<>();
    private boolean mCarrierConfigLoaded = false;
    // True if there is a carrier config loaded for a specific subscrption (and not the default
    // configuration).
    private boolean mCarrierConfigLoadedForSubscription = false;

    private final MmTelFeatureListener mMmTelFeatureListener = new MmTelFeatureListener();
    private class MmTelFeatureListener extends MmTelFeature.Listener {
@@ -354,18 +356,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        }
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
                int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
                if (subId == mPhone.getSubId()) {
                    updateCarrierConfiguration(subId);
                    log("onReceive : Updating mAllowEmergencyVideoCalls = " +
                            mAllowEmergencyVideoCalls);
                }
            } else if (TelecomManager.ACTION_DEFAULT_DIALER_CHANGED.equals(intent.getAction())) {
            if (TelecomManager.ACTION_DEFAULT_DIALER_CHANGED.equals(intent.getAction())) {
                mDefaultDialerUid.set(getPackageUid(context, intent.getStringExtra(
                        TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME)));
            }
@@ -945,7 +939,6 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        mMetrics = TelephonyMetrics.getInstance();

        IntentFilter intentfilter = new IntentFilter();
        intentfilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        intentfilter.addAction(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
        mPhone.getContext().registerReceiver(mReceiver, intentfilter);
        updateCarrierConfiguration(mPhone.getSubId());
@@ -970,7 +963,20 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
                LOG_TAG, new FeatureConnector.Listener<ImsManager>() {
                    public void connectionReady(ImsManager manager, int subId) throws ImsException {
                        mImsManager = manager;
                        startListeningForCalls();
                        log("connectionReady for subId = " + subId);
                        if (subId != mPhone.getSubId()) {
                            // this means we are behind the ImsService that is actually connected,
                            // skip setting up the ImsService connection so that we do not send the
                            // wrong state information to that subscription.
                            // We will get another connectionReady with the up to date info once
                            // the ImsResolver has caught up.
                            loge("connectionReady: skipping, connection to ImsService for "
                                    + "subId = " + subId + " does not match the ImsPhone's current "
                                    + "subId = " + mPhone.getSubId());
                            return;

                        }
                        startListeningForCalls(subId);
                    }

                    @Override
@@ -1013,7 +1019,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
    }

    @VisibleForTesting
    public void startListeningForCalls() throws ImsException {
    public void startListeningForCalls(int subId) throws ImsException {
        log("startListeningForCalls");
        mOperationLocalLog.log("startListeningForCalls - Connecting to ImsService");
        ImsExternalCallTracker externalCallTracker = mPhone.getExternalCallTracker();
@@ -1047,9 +1053,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            mUtInterface.registerForSuppServiceIndication(this, EVENT_SUPP_SERVICE_INDICATION,
                    null);
        }

        maybeConfigureRtpHeaderExtensions();
        updateImsServiceConfig();
        updateCarrierConfiguration(subId);
        // For compatibility with apps that still use deprecated intent
        sendImsServiceStateIntent(ImsManager.ACTION_IMS_SERVICE_UP);
    }
@@ -1465,13 +1469,33 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
     *              removed.
     */
    private void updateCarrierConfiguration(int subId) {
        // start by assuming the carrier config is not loaded for the provided subscription.
        mCarrierConfigLoadedForSubscription = false;

        CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
        if (carrierConfigManager == null
                || !SubscriptionController.getInstance().isActiveSubId(subId)) {
            loge("cacheCarrierConfiguration: No carrier config service found" + " "
                    + "or not active subId = " + subId);
            mCarrierConfigLoaded = false;
        if (carrierConfigManager == null) {
            loge("updateCarrierConfiguration: No carrier config service found");
            return;
        }
        PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(subId);
        if (carrierConfig == null) {
            loge("updateCarrierConfiguration: carrier config is null, skipping.");
            return;
        }

        // Ensure the local cache is up to date first (including default config for no SIM case) in
        // ImsPhoneCallTracker to ensure we do not carry over settings from the previously inserted
        // SIM for things like emergency calling.
        updateCarrierConfigCache(carrierConfig);
        log("updateCarrierConfiguration : Updating mAllowEmergencyVideoCalls = "
                + mAllowEmergencyVideoCalls);
        // Check for changes due to carrier config.
        maybeConfigureRtpHeaderExtensions();

        if (!SubscriptionController.getInstance().isActiveSubId(subId)) {
            loge("updateCarrierConfiguration: skipping notification to ImsService, non"
                    + "active subId = " + subId);
            return;
        }

@@ -1482,25 +1506,22 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
            // when the device is still locked. A CARRIER_CONFIG_CHANGED indication will be sent
            // once the device moves to ready.
            if (state != null && (!state.iccCardExist() || state.isPinLocked())) {
                loge("cacheCarrierConfiguration: card state is not ready, skipping. State= "
                        + state);
                mCarrierConfigLoaded = false;
                loge("updateCarrierConfiguration: card state is not ready, skipping "
                        + "notification to ImsService. State= " + state);
                return;
            }
        }

        PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(subId);
        if (carrierConfig == null) {
            loge("cacheCarrierConfiguration: Empty carrier config.");
            mCarrierConfigLoaded = false;
        if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
            logi("updateCarrierConfiguration: Empty or default carrier config, skipping "
                    + "notification to ImsService.");
            return;
        }
        mCarrierConfigLoaded = true;

        updateCarrierConfigCache(carrierConfig);
        // Only update the ImsService configurations for the case where a new subscription has been
        // loaded and is active.
        mCarrierConfigLoadedForSubscription = true;
        updateImsServiceConfig();
        // Check for changes due to carrier config.
        maybeConfigureRtpHeaderExtensions();
    }

    /**
@@ -4844,7 +4865,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
        // We do not want to update the ImsConfig for REASON_REGISTERED, since it can happen before
        // the carrier config has loaded and will deregister IMS.
        if (!mShouldUpdateImsConfigOnDisconnect
                && reason != DataEnabledSettings.REASON_REGISTERED && mCarrierConfigLoaded) {
                && reason != DataEnabledSettings.REASON_REGISTERED
                && mCarrierConfigLoadedForSubscription) {
            // This will call into updateVideoCallFeatureValue and eventually all clients will be
            // asynchronously notified that the availability of VT over LTE has changed.
            updateImsServiceConfig();
@@ -4856,7 +4878,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall {
     * trigger the update of the configuration sent to the ImsService.
     */
    private void updateImsServiceConfig() {
        if (mImsManager != null && mCarrierConfigLoaded) {
        if (mImsManager != null && mCarrierConfigLoadedForSubscription) {
            mImsManager.updateImsServiceConfig();
        }
    }
+60 −13
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@@ -121,6 +122,7 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    private ImsCall.Listener mImsCallListener;
    private ImsCall mImsCall;
    private ImsCall mSecondImsCall;
    private BroadcastReceiver mBroadcastReceiver;
    private Bundle mBundle = new Bundle();
    private static final int SUB_0 = 0;
    @Nullable private VtDataUsageProvider mVtDataUsageProvider;
@@ -260,19 +262,6 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
        }).when(mConnectorFactory).create(any(), anyInt(), anyString(), any(), any());

        mCTUT = new ImsPhoneCallTracker(mImsPhone, mConnectorFactory, Runnable::run);
        mCTUT.addReasonCodeRemapping(null, "Wifi signal lost.", ImsReasonInfo.CODE_WIFI_LOST);
        mCTUT.addReasonCodeRemapping(501, "Call answered elsewhere.",
                ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
        mCTUT.addReasonCodeRemapping(510, "Call answered elsewhere.",
                ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, "",
                ImsReasonInfo.CODE_SIP_FORBIDDEN);
        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE,
                "emergency calls over wifi not allowed in this location",
                ImsReasonInfo.CODE_EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE);
        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_SIP_FORBIDDEN,
                "service not allowed in this location",
                ImsReasonInfo.CODE_WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION);
        mCTUT.setDataEnabled(true);

        final ArgumentCaptor<VtDataUsageProvider> vtDataUsageProviderCaptor =
@@ -282,6 +271,11 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
        mVtDataUsageProvider = vtDataUsageProviderCaptor.getValue();
        assertNotNull(mVtDataUsageProvider);
        mVtDataUsageProvider.setProviderCallbackBinder(mVtDataUsageProviderCb);
        final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
                ArgumentCaptor.forClass(BroadcastReceiver.class);
        verify(mContext).registerReceiver(receiverCaptor.capture(), any());
        mBroadcastReceiver = receiverCaptor.getValue();
        assertNotNull(mBroadcastReceiver);

        logd("ImsPhoneCallTracker initiated");
        processAllMessages();
@@ -362,6 +356,27 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
        verify(mImsPhone, times(1)).notifyForVideoCapabilityChanged(eq(true));
    }

    @Test
    @SmallTest
    public void testCarrierConfigLoadSubscription() throws Exception {
        // Start with there being no subId loaded, so SubscriptionController#isActiveSubId is false
        // as part of setup, connectionReady is called, which ends up calling
        // updateCarrierConfiguration. Since the carrier config is not report carrier identified
        // config, we should not see updateImsServiceConfig called yet.
        verify(mImsManager, never()).updateImsServiceConfig();

        // Receive a subscription loaded and IMS connection ready indication.
        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
        bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
        // CarrierConfigLoader has signalled that the carrier config has been applied for a specific
        // subscription. This will trigger unavailable -> ready indications.
        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
        mConnectorListener.connectionReady(mImsManager, SUB_0);
        processAllMessages();
        verify(mImsManager).updateImsServiceConfig();
    }

    @Test
    @SmallTest
    public void testImsMTCall() {
@@ -405,6 +420,10 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testImsCepOnPeer() throws Exception {
        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
        bundle.putBoolean(
                CarrierConfigManager.KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_ON_PEER_BOOL, true);
        mCTUT.updateCarrierConfigCache(bundle);
        testImsMTCallAccept();
        doReturn(false).when(mImsCall).isConferenceHost();
        doReturn(true).when(mImsCall).isMultiparty();
@@ -764,6 +783,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testReasonCodeRemap() {
        loadReasonCodeRemap();

        assertEquals(ImsReasonInfo.CODE_WIFI_LOST, mCTUT.maybeRemapReasonCode(
                new ImsReasonInfo(1, 1, "Wifi signal lost.")));
        assertEquals(ImsReasonInfo.CODE_WIFI_LOST, mCTUT.maybeRemapReasonCode(
@@ -785,6 +806,22 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
        mCTUT.updateCarrierConfigCache(bundle);
    }

    private void loadReasonCodeRemap() {
        mCTUT.addReasonCodeRemapping(null, "Wifi signal lost.", ImsReasonInfo.CODE_WIFI_LOST);
        mCTUT.addReasonCodeRemapping(501, "Call answered elsewhere.",
                ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
        mCTUT.addReasonCodeRemapping(510, "Call answered elsewhere.",
                ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, "",
                ImsReasonInfo.CODE_SIP_FORBIDDEN);
        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE,
                "emergency calls over wifi not allowed in this location",
                ImsReasonInfo.CODE_EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE);
        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_SIP_FORBIDDEN,
                "service not allowed in this location",
                ImsReasonInfo.CODE_WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION);
    }

    private void loadReasonCodeRemapCarrierConfig() {
        PersistableBundle bundle = new PersistableBundle();
        String[] mappings = new String[] {
@@ -1145,6 +1182,10 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testCantMakeCallTooMany() {
        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
        bundle.putBoolean(CarrierConfigManager.KEY_ALLOW_HOLD_VIDEO_CALL_BOOL, true);
        mCTUT.updateCarrierConfigCache(bundle);

        // Place a call.
        placeCallAndMakeActive();

@@ -1182,6 +1223,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testNumericOnlyRemap() {
        loadReasonCodeRemap();

        assertEquals(ImsReasonInfo.CODE_SIP_FORBIDDEN, mCTUT.maybeRemapReasonCode(
                new ImsReasonInfo(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, 0)));
        assertEquals(ImsReasonInfo.CODE_SIP_FORBIDDEN, mCTUT.maybeRemapReasonCode(
@@ -1191,6 +1234,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testRemapEmergencyCallsOverWfc() {
        loadReasonCodeRemap();

        assertEquals(ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE,
                mCTUT.maybeRemapReasonCode(
                        new ImsReasonInfo(ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE, 0)));
@@ -1207,6 +1252,8 @@ public class ImsPhoneCallTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testRemapWfcNotAvailable() {
        loadReasonCodeRemap();

        assertEquals(ImsReasonInfo.CODE_SIP_FORBIDDEN,
                mCTUT.maybeRemapReasonCode(
                        new ImsReasonInfo(ImsReasonInfo.CODE_SIP_FORBIDDEN, 0)));