Android Phone的初始化

本文基于 Android 7.1.1 版本,对 Phone 的创建流程进行简介。

Android 开源项目代码参见 Android Google SourceAndroidXRef,这里使用后者。

GsmCdmaPhone 和 ImsPhone 的创建流程

com.android.phone

Git Repo: platform/packages/services/Telephony/

AndroidManifest

1
2
3
4
5
6
7
8
9
<application android:name="PhoneApp"
android:persistent="true"
android:label="@string/phoneAppLabel"
android:icon="@mipmap/ic_launcher_phone"
android:allowBackup="false"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">

PhoneAPP.onCreate

1
2
3
4
5
6
7
8
9
10
11
public void onCreate() {
if (UserHandle.myUserId() == 0) {
// We are running as the primary user, so should bring up the
// global phone state.
mPhoneGlobals = new PhoneGlobals(this);
mPhoneGlobals.onCreate();

mTelephonyGlobals = new TelephonyGlobals(this);
mTelephonyGlobals.onCreate();
}
}

PhoneGlobals.onCreate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void onCreate() {
if (VDBG) Log.v(LOG_TAG, "onCreate()...");
……
if (mCM == null) {
// Initialize the telephony framework
PhoneFactory.makeDefaultPhones(this);
……
mCM = CallManager.getInstance();
for (Phone phone : PhoneFactory.getPhones()) {
mCM.registerPhone(phone);
}
……
phoneMgr = PhoneInterfaceManager.init(this, PhoneFactory.getDefaultPhone());
……
}

com.android.internal.telephony

Git Repo: platform/frameworks/opt/telephony

PhoneFactory.makeDefaultPhones

  • makeDefaultPhone 代码过多,见以下的分段。
1
2
3
4
5
6
public static void makeDefaultPhones(Context context) {
makeDefaultPhone(context);

public static void makeDefaultPhone(Context context) {
…………
}
1
2
// create the telephony device controller.
TelephonyDevController.create();
1
sPhoneNotifier = new DefaultPhoneNotifier();
1
2
int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
  • 考虑 Multi SIM 的情况,根据 SIM 的数量创建存储对象
1
2
3
4
5
6
7
8
/* 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().getPhoneCount();
int[] networkModes = new int[numPhones];
sPhones = new Phone[numPhones];
sCommandsInterfaces = new RIL[numPhones];
sTelephonyNetworkFactories = new TelephonyNetworkFactory[numPhones];
1
2
3
4
5
6
7
8
9
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, networkModes[i],
cdmaSubscription, i);
}
1
2
3
4
5
6
Rlog.i(LOG_TAG, "Creating SubscriptionController");
SubscriptionController.init(context, sCommandsInterfaces);

// Instantiate UiccController so that all other classes can just
// call getInstance()
sUiccController = UiccController.make(context, sCommandsInterfaces);
  • 根据 Phone 类型的不同,创建不同的 Phone 对象
  • GsmPhoneCdmaPhone 在 Android N 中合并为 GsmCdmaPhone
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (int i = 0; i < numPhones; i++) {
Phone phone = null;
int phoneType = TelephonyManager.getPhoneType(networkModes[i]);
if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
phone = new GsmCdmaPhone(context,
sCommandsInterfaces[i], sPhoneNotifier, i,
PhoneConstants.PHONE_TYPE_GSM,
TelephonyComponentFactory.getInstance());
} else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
phone = new GsmCdmaPhone(context,
sCommandsInterfaces[i], sPhoneNotifier, i,
PhoneConstants.PHONE_TYPE_CDMA_LTE,
TelephonyComponentFactory.getInstance());
}
Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " sub = " + i);

sPhones[i] = phone;
}
  • 设置默认的 PhonePhone[0],未来应该要加入一些控制条件
1
2
3
4
5
// 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];
sCommandsInterface = sCommandsInterfaces[0];
1
2
3
4
Rlog.i(LOG_TAG, "Creating SubInfoRecordUpdater ");
sSubInfoRecordUpdater = new SubscriptionInfoUpdater(context,
sPhones, sCommandsInterfaces);
SubscriptionController.getInstance().updatePhonesAvailability(sPhones);
1
2
3
4
5
6
// 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].startMonitoringImsService();
}
  • 通过 ServiceMnager 获取 TelephonyRegistry 的 Binder 代理, 监听当前的状态并上报
1
2
ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(
ServiceManager.getService("telephony.registry"));
1
2
3
SubscriptionController sc = SubscriptionController.getInstance();

sSubscriptionMonitor = new SubscriptionMonitor(tr, sContext, sc, numPhones);
1
2
3
sPhoneSwitcher = new PhoneSwitcher(MAX_ACTIVE_PHONES, numPhones,
sContext, sc, Looper.myLooper(), tr, sCommandsInterfaces,
sPhones);
1
2
sProxyController = ProxyController.getInstance(context, sPhones,
sUiccController, sCommandsInterfaces, sPhoneSwitcher);
  • 为每个 Phone 创建 TelephonyNetworkFactory 的对象,并通过 NetworkFactoryConnectivityService 进行通信
1
2
3
4
5
sTelephonyNetworkFactories = new TelephonyNetworkFactory[numPhones];
for (int i = 0; i < numPhones; i++) {
sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
sPhoneSwitcher, sc, sSubscriptionMonitor, Looper.myLooper(),
sContext, i, sPhones[i].mDcTracker);

总结

Phone 的作用:

  • 和RIL交互,注册监听事件,并上报消息
  • 为上层提供接口