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 查询