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

Commit f1c53340 authored by Malcolm Chen's avatar Malcolm Chen Committed by Xiangyu/Malcolm Chen
Browse files

In PhoneFactory, dynamically allocate 2nd phone when switching to dsds

Test: Manual and unittest
Bug: 142514392
Change-Id: Ia8496a8d297c4512dbe4266b171388ff8d3cbcdd
parent c1931115
Loading
Loading
Loading
Loading
+18 −14
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.os.RegistrantList;
import android.sysprop.TelephonyProperties;
import android.telephony.PhoneCapability;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;

@@ -134,19 +135,6 @@ public class PhoneConfigurationManager {
        return sInstance;
    }

    /**
     * Whether the phoneId has a corresponding active slot / logical modem. If a DSDS capable
     * device is in single SIM mode, phoneId=1 is valid but not active.
     *
     * TODO: b/139642279 combine with SubscriptionManager#isValidPhoneId when phone objects
     * are dynamically allocated instead of always based on getMaxPhoneCount.
     * @hide
     */
    public static boolean isPhoneActive(int phoneId) {
        // Currently it simply depends on getPhoneCount. In future it can be generalized.
        return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount();
    }

    /**
     * Handler class to handle callbacks
     */
@@ -371,11 +359,12 @@ public class PhoneConfigurationManager {
            pm.reboot("Multi-SIM config changed.");
        } else {
            log("onMultiSimConfigChanged: Rebooting is not required.");
            mMi.notifyPhoneFactoryOnMultiSimConfigChanged(mContext, numOfActiveModems);
            broadcastMultiSimConfigChange(numOfActiveModems);
            // Register to RIL service if needed.
            for (int i = 0; i < mPhones.length; i++) {
                Phone phone = mPhones[i];
                phone.mCi.onSlotActiveStatusChange(isPhoneActive(i));
                phone.mCi.onSlotActiveStatusChange(SubscriptionManager.isValidPhoneId(i));
            }
        }
    }
@@ -431,6 +420,9 @@ public class PhoneConfigurationManager {
     */
    @VisibleForTesting
    public static class MockableInterface {
        /**
         * Wrapper function to decide whether reboot is required for modem config change.
         */
        @VisibleForTesting
        public boolean isRebootRequiredForModemConfigChange() {
            boolean rebootRequired = TelephonyProperties.reboot_on_modem_change().orElse(false);
@@ -438,6 +430,9 @@ public class PhoneConfigurationManager {
            return rebootRequired;
        }

        /**
         * Wrapper function to call setMultiSimProperties.
         */
        @VisibleForTesting
        public void setMultiSimProperties(int numOfActiveModems) {
            String multiSimConfig;
@@ -455,6 +450,15 @@ public class PhoneConfigurationManager {
            log("setMultiSimProperties to " + multiSimConfig);
            TelephonyProperties.multi_sim_config(multiSimConfig);
        }

        /**
         * Wrapper function to call PhoneFactory.onMultiSimConfigChanged.
         */
        @VisibleForTesting
        public void notifyPhoneFactoryOnMultiSimConfigChanged(
                Context context, int numOfActiveModems) {
            PhoneFactory.onMultiSimConfigChanged(context, numOfActiveModems);
        }
    }

    private static void log(String s) {
+39 −3
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.internal.telephony;
import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA;
import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA_LTE;

import static java.util.Arrays.copyOf;

import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
@@ -151,7 +153,7 @@ public class PhoneFactory {
                /* In case of multi SIM mode two instances of Phone, RIL are created,
                   where as in single SIM mode only instance. isMultiSimEnabled() function checks
                   whether it is single SIM or multi SIM mode */
                int numPhones = TelephonyManager.getDefault().getSupportedModemCount();
                int numPhones = TelephonyManager.getDefault().getActiveModemCount();

                int[] networkModes = new int[numPhones];
                sPhones = new Phone[numPhones];
@@ -189,7 +191,7 @@ public class PhoneFactory {
                // Set the default phone in base class.
                // FIXME: This is a first best guess at what the defaults will be. It
                // FIXME: needs to be done in a more controlled manner in the future.
                sPhone = sPhones[0];
                if (numPhones > 0) sPhone = sPhones[0];

                // Ensure that we have a default SMS app. Requesting the app with
                // updateIfNeeded set to true is enough to configure a default SMS app.
@@ -209,7 +211,6 @@ public class PhoneFactory {
                Rlog.i(LOG_TAG, "Creating SubInfoRecordUpdater ");
                sSubInfoRecordUpdater = new SubscriptionInfoUpdater(
                        BackgroundThread.get().getLooper(), context, sCommandsInterfaces);
                sc.updatePhonesAvailability(sPhones);

                // Only bring up IMS if the device supports having an IMS stack.
                if (context.getPackageManager().hasSystemFeature(
@@ -260,6 +261,41 @@ public class PhoneFactory {
        }
    }

    /**
     * Upon single SIM to dual SIM switch or vice versa, we dynamically allocate or de-allocate
     * Phone and CommandInterface objects.
     * @param context
     * @param activeModemCount
     */
    public static void onMultiSimConfigChanged(Context context, int activeModemCount) {
        synchronized (sLockProxyPhones) {
            int prevActiveModemCount = sPhones.length;
            if (prevActiveModemCount == activeModemCount) return;

            // TODO: clean up sPhones, sCommandsInterfaces and sTelephonyNetworkFactories objects.
            // Currently we will not clean up the 2nd Phone object, so that it can be re-used if
            // user switches back.
            if (prevActiveModemCount > activeModemCount) return;

            sPhones = copyOf(sPhones, activeModemCount);
            sCommandsInterfaces = copyOf(sCommandsInterfaces, activeModemCount);
            sTelephonyNetworkFactories = copyOf(sTelephonyNetworkFactories, activeModemCount);

            int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
            for (int i = prevActiveModemCount; i < activeModemCount; i++) {
                sCommandsInterfaces[i] = new RIL(context, RILConstants.PREFERRED_NETWORK_MODE,
                        cdmaSubscription, i);
                sPhones[i] = createPhone(context, i);
                if (context.getPackageManager().hasSystemFeature(
                        PackageManager.FEATURE_TELEPHONY_IMS)) {
                    sPhones[i].startMonitoringImsService();
                }
                sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
                        Looper.myLooper(), sPhones[i]);
            }
        }
    }

    private static Phone createPhone(Context context, int phoneId) {
        int phoneType = TelephonyManager.getPhoneType(RILConstants.PREFERRED_NETWORK_MODE);
        Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " phoneId = " + phoneId);
+1 −1
Original line number Diff line number Diff line
@@ -209,7 +209,7 @@ public class ProxyController {
     */
    public boolean setRadioCapability(RadioAccessFamily[] rafs) {
        if (rafs.length != mPhones.length) {
            throw new RuntimeException("Length of input rafs must equal to total phone count");
            return false;
        }
        // Check if there is any ongoing transaction and throw an exception if there
        // is one as this is a programming error.
+5 −2
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SmsManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyHistogram;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager.PrefNetworkMode;
@@ -413,7 +414,7 @@ public class RIL extends BaseCommands implements CommandsInterface {
    /** Returns a {@link IRadio} instance or null if the service is not available. */
    @VisibleForTesting
    public synchronized IRadio getRadioProxy(Message result) {
        if (!PhoneConfigurationManager.isPhoneActive(mPhoneId)) return null;
        if (!SubscriptionManager.isValidPhoneId(mPhoneId)) return null;
        if (!mIsMobileNetworkSupported) {
            if (RILJ_LOGV) riljLog("getRadioProxy: Not calling getService(): wifi-only");
            if (result != null) {
@@ -510,13 +511,15 @@ public class RIL extends BaseCommands implements CommandsInterface {
            // Try to connect to RIL services and set response functions.
            getRadioProxy(null);
            getOemHookProxy(null);
        } else {
            resetProxyAndRequestList();
        }
    }

    /** Returns an {@link IOemHook} instance or null if the service is not available. */
    @VisibleForTesting
    public synchronized IOemHook getOemHookProxy(Message result) {
        if (!PhoneConfigurationManager.isPhoneActive(mPhoneId)) return null;
        if (!SubscriptionManager.isValidPhoneId((mPhoneId))) return null;
        if (!mIsMobileNetworkSupported) {
            if (RILJ_LOGV) riljLog("getOemHookProxy: Not calling getService(): wifi-only");
            if (result != null) {
+6 −11
Original line number Diff line number Diff line
@@ -133,7 +133,6 @@ public class SubscriptionController extends ISub.Stub {

    /** The singleton instance. */
    private static SubscriptionController sInstance = null;
    protected static Phone[] sPhones;
    @UnsupportedAppUsage
    protected Context mContext;
    protected TelephonyManager mTelephonyManager;
@@ -1185,7 +1184,7 @@ public class SubscriptionController extends ISub.Stub {
                }

                // Once the records are loaded, notify DcTracker
                sPhones[slotIndex].updateDataConnectionTracker();
                PhoneFactory.getPhone(slotIndex).updateDataConnectionTracker();

                if (DBG) logdl("[addSubInfoRecord]- info size=" + sSlotIndexToSubIds.size());
            }
@@ -2244,7 +2243,7 @@ public class SubscriptionController extends ISub.Stub {
            }

            ProxyController proxyController = ProxyController.getInstance();
            int len = sPhones.length;
            int len = TelephonyManager.from(mContext).getActiveModemCount();
            logdl("[setDefaultDataSubId] num phones=" + len + ", subId=" + subId);

            if (SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -2252,7 +2251,7 @@ public class SubscriptionController extends ISub.Stub {
                RadioAccessFamily[] rafs = new RadioAccessFamily[len];
                boolean atLeastOneMatch = false;
                for (int phoneId = 0; phoneId < len; phoneId++) {
                    Phone phone = sPhones[phoneId];
                    Phone phone = PhoneFactory.getPhone(phoneId);
                    int raf;
                    int id = phone.getSubId();
                    if (id == subId) {
@@ -2293,11 +2292,11 @@ public class SubscriptionController extends ISub.Stub {
    @UnsupportedAppUsage
    private void updateAllDataConnectionTrackers() {
        // Tell Phone Proxies to update data connection tracker
        int len = sPhones.length;
        if (DBG) logd("[updateAllDataConnectionTrackers] sPhones.length=" + len);
        int len = TelephonyManager.from(mContext).getActiveModemCount();
        if (DBG) logd("[updateAllDataConnectionTrackers] activeModemCount=" + len);
        for (int phoneId = 0; phoneId < len; phoneId++) {
            if (DBG) logd("[updateAllDataConnectionTrackers] phoneId=" + phoneId);
            sPhones[phoneId].updateDataConnectionTracker();
            PhoneFactory.getPhone(phoneId).updateDataConnectionTracker();
        }
    }

@@ -2433,10 +2432,6 @@ public class SubscriptionController extends ISub.Stub {
        }
    }

    public void updatePhonesAvailability(Phone[] phones) {
        sPhones = phones;
    }

    private synchronized ArrayList<Integer> getActiveSubIdArrayList() {
        // Clone the sub id list so it can't change out from under us while iterating
        List<Entry<Integer, ArrayList<Integer>>> simInfoList =
Loading