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

Commit 7570a9a5 authored by Brad Ebinger's avatar Brad Ebinger
Browse files

Adds MSIM config support to PhoneConfigurationManager

Some devices use the multi_sim_config property for DSDA.
For these devices, consider voice subs = 2 and statically
notify both slots as MSIM capable for the new APIs.

Bug: b/319904227
Test: atest FrameworksTelephonyTests:PhoneConfigurationManagerTest
Change-Id: I06f923cf1ced3f57d06b96dbf614aef1ea828eb1
parent 656495d7
Loading
Loading
Loading
Loading
+77 −21
Original line number Diff line number Diff line
@@ -47,7 +47,9 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
@@ -76,8 +78,10 @@ public class PhoneConfigurationManager {
    private static PhoneConfigurationManager sInstance = null;
    private final Context mContext;
    private PhoneCapability mStaticCapability;
    private final Set<Integer> mSlotsSupportingSimultaneousCellularCalls = new HashSet<>(2);
    private final Set<Integer> mSubIdsSupportingSimultaneousCellularCalls = new HashSet<>(2);
    private final Set<Integer> mSlotsSupportingSimultaneousCellularCalls = new HashSet<>(3);
    private final Set<Integer> mSubIdsSupportingSimultaneousCellularCalls = new HashSet<>(3);
    private final HashSet<Consumer<Set<Integer>>> mSimultaneousCellularCallingListeners =
            new HashSet<>(1);
    private final RadioConfig mRadioConfig;
    private final Handler mHandler;
    // mPhones is obtained from PhoneFactory and can have phones corresponding to inactive modems as
@@ -185,12 +189,16 @@ public class PhoneConfigurationManager {
    /**
     * If virtual DSDA is enabled for this UE, then increase maxActiveVoiceSubscriptions to 2.
     */
    private PhoneCapability maybeUpdateMaxActiveVoiceSubscriptions(
    private PhoneCapability maybeOverrideMaxActiveVoiceSubscriptions(
            final PhoneCapability staticCapability) {
        if (staticCapability.getLogicalModemList().size() > 1 && mVirtualDsdaEnabled) {
        boolean isVDsdaEnabled = staticCapability.getLogicalModemList().size() > 1
                && mVirtualDsdaEnabled;
        boolean isBkwdCompatDsdaEnabled = mFeatureFlags.simultaneousCallingIndications()
                && mMi.getMultiSimProperty().orElse(SSSS).equals(DSDA);
        if (isVDsdaEnabled || isBkwdCompatDsdaEnabled) {
            // Since we already initialized maxActiveVoiceSubscriptions to the count the
            // modem is capable of, vDSDA is only able to increase that count via this method. We do
            // not allow vDSDA to decrease maxActiveVoiceSubscriptions:
            // modem is capable of, we are only able to increase that count via this method. We do
            // not allow a decrease of maxActiveVoiceSubscriptions:
            int updatedMaxActiveVoiceSubscriptions =
                    Math.max(staticCapability.getMaxActiveVoiceSubscriptions(), 2);
            return new PhoneCapability.Builder(staticCapability)
@@ -202,14 +210,31 @@ public class PhoneConfigurationManager {
    }

    private void maybeEnableCellularDSDASupport() {
        if (mRadioConfig != null && mRadioConfig.getRadioConfigProxy(null)
                .getVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_2_2) &&
                getPhoneCount() > 1 &&
                mStaticCapability.getMaxActiveVoiceSubscriptions() > 1) {
        boolean bkwdsCompatDsda = mFeatureFlags.simultaneousCallingIndications()
                && getPhoneCount() > 1
                && mMi.getMultiSimProperty().orElse(SSSS).equals(DSDA);
        boolean halSupportSimulCalling = mRadioConfig != null
                && mRadioConfig.getRadioConfigProxy(null).getVersion().greaterOrEqual(
                        RIL.RADIO_HAL_VERSION_2_2)
                && getPhoneCount() > 1 && mStaticCapability.getMaxActiveVoiceSubscriptions() > 1;
        // Register for simultaneous calling support changes in the modem if the HAL supports it
        if (halSupportSimulCalling) {
            updateSimultaneousCallingSupport();
            mRadioConfig.registerForSimultaneousCallingSupportStatusChanged(mHandler,
                    EVENT_SIMULTANEOUS_CALLING_SUPPORT_CHANGED, null);
            if (mFeatureFlags.simultaneousCallingIndications()) {
        } else if (bkwdsCompatDsda) {
            // For older devices that only declare that they support DSDA via modem config,
            // set DSDA as capable now statically.
            log("DSDA modem config detected - setting DSDA enabled");
            for (Phone p : mPhones) {
                mSlotsSupportingSimultaneousCellularCalls.add(p.getPhoneId());
            }
            updateSimultaneousSubIdsFromPhoneIdMappingAndNotify();
            notifySimultaneousCellularCallingSlotsChanged();
        }
        // Register for subId updates to notify listeners when simultaneous calling is configured
        if (mFeatureFlags.simultaneousCallingIndications()
                && (bkwdsCompatDsda || halSupportSimulCalling)) {
            mContext.getSystemService(TelephonyRegistryManager.class)
                    .addOnSubscriptionsChangedListener(
                            new SubscriptionManager.OnSubscriptionsChangedListener() {
@@ -220,7 +245,6 @@ public class PhoneConfigurationManager {
                            }, mHandler::post);
        }
    }
    }

    /**
     * Static method to get instance.
@@ -331,6 +355,7 @@ public class PhoneConfigurationManager {
                    }
                    if (mFeatureFlags.simultaneousCallingIndications()) {
                        updateSimultaneousSubIdsFromPhoneIdMappingAndNotify();
                        notifySimultaneousCellularCallingSlotsChanged();
                    }
                    break;
                default:
@@ -469,7 +494,7 @@ public class PhoneConfigurationManager {
                    mHandler, EVENT_GET_PHONE_CAPABILITY_DONE);
            mRadioConfig.getPhoneCapability(callback);
        }
        mStaticCapability = maybeUpdateMaxActiveVoiceSubscriptions(mStaticCapability);
        mStaticCapability = maybeOverrideMaxActiveVoiceSubscriptions(mStaticCapability);
        log("getStaticPhoneCapability: mStaticCapability " + mStaticCapability);
        return mStaticCapability;
    }
@@ -485,8 +510,31 @@ public class PhoneConfigurationManager {
        return mStaticCapability.getMaxActiveDataSubscriptions();
    }

    /**
     * Register to listen to changes in the Phone slots that support simultaneous calling.
     * @param consumer A consumer that will be used to consume the new slots supporting simultaneous
     *                 cellular calling when it changes.
     */
    public void registerForSimultaneousCellularCallingSlotsChanged(
            Consumer<Set<Integer>> consumer) {
        mSimultaneousCellularCallingListeners.add(consumer);
    }

    private void notifySimultaneousCellularCallingSlotsChanged() {
        log("notifying listeners of changes to simultaneous cellular calling - new state:"
                + mSlotsSupportingSimultaneousCellularCalls);
        for (Consumer<Set<Integer>> consumer : mSimultaneousCellularCallingListeners) {
            try {
                consumer.accept(new HashSet<>(mSlotsSupportingSimultaneousCellularCalls));
            } catch (Exception e) {
                log("Unexpected Exception encountered when notifying listener: " + e);
            }
        }
    }

    private void notifyCapabilityChanged() {
        mNotifier.notifyPhoneCapabilityChanged(mStaticCapability);
        mNotifier.notifyPhoneCapabilityChanged(maybeOverrideMaxActiveVoiceSubscriptions(
                mStaticCapability));
    }

    /**
@@ -572,6 +620,7 @@ public class PhoneConfigurationManager {
                mSlotsSupportingSimultaneousCellularCalls.clear();
                if (mFeatureFlags.simultaneousCallingIndications()) {
                    updateSimultaneousSubIdsFromPhoneIdMappingAndNotify();
                    notifySimultaneousCellularCallingSlotsChanged();
                }
            }

@@ -750,6 +799,13 @@ public class PhoneConfigurationManager {
                Context context, int numOfActiveModems) {
            PhoneFactory.onMultiSimConfigChanged(context, numOfActiveModems);
        }

        /**
         * Wrapper function to query the sysprop for multi_sim_config
         */
        public Optional<String> getMultiSimProperty() {
            return TelephonyProperties.multi_sim_config();
        }
    }

    private static void log(String s) {
+62 −0
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -220,6 +222,61 @@ public class PhoneConfigurationManagerTest extends TelephonyTest {
        assertTrue(mPcm.getSlotsSupportingSimultaneousCellularCalls().isEmpty());
    }

    /**
     * If the device uses the older "dsda" multi_sim_config setting, ensure that DSDA is set
     * statically for that device and subId updates work.
     */
    @Test
    @SmallTest
    public void testBkwdsCompatSimultaneousCallingDsda() throws Exception {
        doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
        doReturn(RIL.RADIO_HAL_VERSION_2_1).when(mMockRadioConfigProxy).getVersion();
        doReturn(Optional.of("dsda")).when(mMi).getMultiSimProperty();
        final int phone0SubId = 2;
        final int phone1SubId = 3;
        mPhones = new Phone[]{mPhone, mPhone1};
        doReturn(0).when(mPhone).getPhoneId();
        doReturn(1).when(mPhone1).getPhoneId();
        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
        init(2);
        doReturn(phone0SubId).when(mPhone).getSubId();
        doReturn(phone1SubId).when(mPhone1).getSubId();
        Set<Integer>[] cachedSimultaneousCallingSlots = new Set[]{Collections.emptySet()};
        mPcm.registerForSimultaneousCellularCallingSlotsChanged(newSlots ->
                cachedSimultaneousCallingSlots[0] = newSlots);

        mPcm.getStaticPhoneCapability();
        setAndVerifyStaticCapability(STATIC_DSDA_CAPABILITY);
        ArgumentCaptor<SubscriptionManager.OnSubscriptionsChangedListener> cBCaptor =
                ArgumentCaptor.forClass(SubscriptionManager.OnSubscriptionsChangedListener.class);
        verify(mMockRegistryManager).addOnSubscriptionsChangedListener(cBCaptor.capture(), any());
        processAllMessages();

        int[] enabledLogicalSlots = {0, 1};
        HashSet<Integer> expectedSlots = new HashSet<>(2);
        for (int i : enabledLogicalSlots) {
            expectedSlots.add(i);
        }
        HashSet<Integer> expectedSubIds = new HashSet<>(2);
        expectedSubIds.add(phone0SubId);
        expectedSubIds.add(phone1SubId);
        assertEquals(expectedSlots, mPcm.getSlotsSupportingSimultaneousCellularCalls());
        verify(mMockRegistryManager).notifySimultaneousCellularCallingSubscriptionsChanged(
                eq(expectedSubIds));
        assertEquals(expectedSlots, cachedSimultaneousCallingSlots[0]);

        // Change sub ID mapping
        final int phone1SubIdV2 = 4;
        expectedSubIds.clear();
        expectedSubIds.add(phone0SubId);
        expectedSubIds.add(phone1SubIdV2);
        doReturn(phone1SubIdV2).when(mPhone1).getSubId();
        cBCaptor.getValue().onSubscriptionsChanged();
        processAllMessages();
        verify(mMockRegistryManager, times(2))
                .notifySimultaneousCellularCallingSubscriptionsChanged(eq(expectedSubIds));
    }

    @Test
    @SmallTest
    public void testUpdateSimultaneousCallingSupportNotifications() throws Exception {
@@ -233,6 +290,9 @@ public class PhoneConfigurationManagerTest extends TelephonyTest {
        init(2);
        doReturn(phone0SubId).when(mPhone).getSubId();
        doReturn(phone1SubId).when(mPhone1).getSubId();
        Set<Integer>[] cachedSimultaneousCallingSlots = new Set[]{Collections.emptySet()};
        mPcm.registerForSimultaneousCellularCallingSlotsChanged(newSlots ->
                cachedSimultaneousCallingSlots[0] = newSlots);

        // Simultaneous calling enabled
        mPcm.updateSimultaneousCallingSupport();
@@ -254,6 +314,7 @@ public class PhoneConfigurationManagerTest extends TelephonyTest {
        assertEquals(expectedSlots, mPcm.getSlotsSupportingSimultaneousCellularCalls());
        verify(mMockRegistryManager).notifySimultaneousCellularCallingSubscriptionsChanged(
                eq(expectedSubIds));
        assertEquals(expectedSlots, cachedSimultaneousCallingSlots[0]);

        // Simultaneous Calling Disabled
        mPcm.updateSimultaneousCallingSupport();
@@ -268,6 +329,7 @@ public class PhoneConfigurationManagerTest extends TelephonyTest {
        assertEquals(Collections.emptySet(), mPcm.getSlotsSupportingSimultaneousCellularCalls());
        verify(mMockRegistryManager, times(2))
                .notifySimultaneousCellularCallingSubscriptionsChanged(eq(Collections.emptySet()));
        assertEquals(Collections.emptySet(), cachedSimultaneousCallingSlots[0]);
    }

    @Test