【Telephony】单卡双卡

PhoneFactory.java初始化了手机的默认设置,包括创建TelephonyDevController,设置统计拉取器,注册Phone和RIL接口。根据TelephonyManager.java的getActiveModemCount()方法,确定设备的SIM卡数量,支持单SIM、双SIM或多SIM模式。getMultiSimConfiguration()用于获取设备的多SIM配置,如DSDS(双卡双待)或DSDA(双卡双通)。整个过程涉及对系统属性的读取和多SIM卡状态的判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0. PhoneFactory.java

0.1 makeDefaultPhone()

    public static void makeDefaultPhone(Context context) {
        synchronized (sLockProxyPhones) {
            if (!sMadeDefaults) {
                sContext = context;
                // create the telephony device controller.
                TelephonyDevController.create();

                TelephonyMetrics metrics = TelephonyMetrics.getInstance();
                metrics.setContext(context);

                int retryCount = 0;
                for(;;) {
                    boolean hasException = false;
                    retryCount ++;

                    try {
                        // use UNIX domain socket to
                        // prevent subsequent initialization
                        new LocalServerSocket("com.android.internal.telephony");
                    } catch (java.io.IOException ex) {
                        hasException = true;
                    }

                    if ( !hasException ) {
                        break;
                    } else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
                        throw new RuntimeException("PhoneFactory probably already running");
                    } else {
                        try {
                            Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
                        } catch (InterruptedException er) {
                        }
                    }
                }

                // register statsd pullers.
                sMetricsCollector = new MetricsCollector(context);

                sPhoneNotifier = new DefaultPhoneNotifier(context);

                int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
                Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);

                /* 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 
				在多SIM模式的情况下,会创建两个Phone、RIL实例,其中与单SIM模式相同,只有一个实例。
				isMultiSimEnabled()函数检查是单SIM模式还是多SIM模式
				*/                   
                int numPhones = TelephonyManager.getDefault().getActiveModemCount();

                int[] networkModes = new int[numPhones];
                sPhones = new Phone[numPhones];
                sCommandsInterfaces = new RIL[numPhones];
                sTelephonyNetworkFactories = new TelephonyNetworkFactory[numPhones];

                for (int i = 0; i < numPhones; i++) {
                    // reads the system properties and makes commandsinterface
                    // Get preferred network type.
                    networkModes[i] = RILConstants.PREFERRED_NETWORK_MODE;

                    Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkModes[i]));
                    sCommandsInterfaces[i] = new RIL(context,
                            RadioAccessFamily.getRafFromNetworkType(networkModes[i]),
                            cdmaSubscription, i);
                }

                if (numPhones > 0) {
                    final RadioConfig radioConfig = RadioConfig.make(context,
                            sCommandsInterfaces[0].getHalVersion());
                    sRadioHalCapabilities = RadioInterfaceCapabilityController.init(radioConfig,
                            sCommandsInterfaces[0]);
                } else {
                    // There is no command interface to go off of
                    final RadioConfig radioConfig = RadioConfig.make(context, HalVersion.UNKNOWN);
                    sRadioHalCapabilities = RadioInterfaceCapabilityController.init(
                            radioConfig, null);
                }


                // Instantiate UiccController so that all other classes can just
                // call getInstance()
                sUiccController = UiccController.make(context);

                Rlog.i(LOG_TAG, "Creating SubscriptionController");
                TelephonyComponentFactory.getInstance().inject(SubscriptionController.class.
                        getName()).initSubscriptionController(context);
                TelephonyComponentFactory.getInstance().inject(MultiSimSettingController.class.
                        getName()).initMultiSimSettingController(context,
                        SubscriptionController.getInstance());

                if (context.getPackageManager().hasSystemFeature(
                        PackageManager.FEATURE_TELEPHONY_EUICC)) {
                    sEuiccController = EuiccController.init(context);
                    sEuiccCardController = EuiccCardController.init(context);
                }

                for (int i = 0; i < numPhones; i++) {
                    sPhones[i] = createPhone(context, i);
                }

                // 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.
                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.
                ComponentName componentName =
                        SmsApplication.getDefaultSmsApplication(context, true /* updateIfNeeded */);
                String packageName = "NONE";
                if (componentName != null) {
                    packageName = componentName.getPackageName();
                }
                Rlog.i(LOG_TAG, "defaultSmsApplication: " + packageName);

                // Set up monitor to watch for changes to SMS packages
                SmsApplication.initSmsPackageMonitor(context);

                sMadeDefaults = true;

                Rlog.i(LOG_TAG, "Creating SubInfoRecordUpdater ");
                HandlerThread pfhandlerThread = new HandlerThread("PhoneFactoryHandlerThread");
                pfhandlerThread.start();
                sSubInfoRecordUpdater = TelephonyComponentFactory.getInstance().inject(
                        SubscriptionInfoUpdater.class.getName()).
                        makeSubscriptionInfoUpdater(pfhandlerThread.
                        getLooper(), context, SubscriptionController.getInstance());

                // Only bring up IMS if the device supports having an IMS stack.
                if (context.getPackageManager().hasSystemFeature(
                        PackageManager.FEATURE_TELEPHONY_IMS)) {
                    // Start monitoring after defaults have been made.
                    // Default phone must be ready before ImsPhone is created because ImsService
                    // might need it when it is being opened.
                    for (int i = 0; i < numPhones; i++) {
                        sPhones[i].createImsPhone();
                    }
                } else {
                    Rlog.i(LOG_TAG, "IMS is not supported on this device, skipping ImsResolver.");
                }

                sPhoneConfigurationManager = PhoneConfigurationManager.init(sContext);

                sCellularNetworkValidator = CellularNetworkValidator.make(sContext);

                int maxActivePhones = sPhoneConfigurationManager
                        .getNumberOfModemsWithSimultaneousDataConnections();

                sPhoneSwitcher = TelephonyComponentFactory.getInstance().inject(
                        PhoneSwitcher.class.getName()).
                        makePhoneSwitcher(maxActivePhones, sContext, Looper.myLooper());

                sProxyController = ProxyController.getInstance(context);

                sIntentBroadcaster = IntentBroadcaster.getInstance(context);

                sNotificationChannelController = new NotificationChannelController(context);

                for (int i = 0; i < numPhones; i++) {
                    sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
                            Looper.myLooper(), sPhones[i]);
                }
            }
        }
    }

1.TelephonyManager.java

1.1 getActiveModemCount()

   /**
     * Returns the number of phones available.
     * Returns 0 if none of voice, sms, data is not supported
     * Returns 1 for Single standby mode (Single SIM functionality).
     * Returns 2 for Dual standby mode (Dual SIM functionality).
     * Returns 3 for Tri standby mode (Tri SIM functionality).
     * @deprecated Use {@link #getActiveModemCount} instead.
     */
    @Deprecated
    public int getPhoneCount() {
        return getActiveModemCount();
    }

    /**
     * Returns the number of logical modems currently configured to be activated.
     *
     * Returns 0 if none of voice, sms, data is not supported
     * Returns 1 for Single standby mode (Single SIM functionality).
     * Returns 2 for Dual standby mode (Dual SIM functionality).
     * Returns 3 for Tri standby mode (Tri SIM functionality).
     */
    public int getActiveModemCount() {
        int modemCount = 1;
        switch (getMultiSimConfiguration()) {
            case UNKNOWN:
                modemCount = 1;
                // check for voice and data support, 0 if not supported
                if (!isVoiceCapable() && !isSmsCapable() && !isDataCapable()) {
                    modemCount = 0;
                }
                break;
            case DSDS:
            case DSDA:
                modemCount = 2;
                break;
            case TSTS:
                modemCount = 3;
                break;
        }
        return modemCount;
    }

1.2 getMultiSimConfiguration()

    /**
     * Returns the multi SIM variant
     * Returns DSDS for Dual SIM Dual Standby 双卡双待
     * Returns DSDA for Dual SIM Dual Active  双卡双通
     * Returns TSTS for Triple SIM Triple Standby 三卡三待
     * Returns UNKNOWN for others
     */
    /** {@hide} */
    @UnsupportedAppUsage
    public MultiSimVariants getMultiSimConfiguration() {
        String mSimConfig =
                TelephonyProperties.multi_sim_config().orElse("");
        if (mSimConfig.equals("dsds")) {
            return MultiSimVariants.DSDS;
        } else if (mSimConfig.equals("dsda")) {
            return MultiSimVariants.DSDA;
        } else if (mSimConfig.equals("tsts")) {
            return MultiSimVariants.TSTS;
        } else {
            return MultiSimVariants.UNKNOWN;
        }
    }

String mSimConfig = TelephonyProperties.multi_sim_config().orElse(“”);
在这里插入图片描述

这个语句就是根据用户预设定的persist.radio.multisim.config值,来确定当前是单卡项目还是多卡项目,返回的是手机所支持的卡槽数量。

使用adb 查询
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值