初识com.android.phone

前置文章

  1. 《Android系统之System Server大纲》
  2. 《Android无线电信息管理开篇准备工作》

前言

在 《Android无线电信息管理开篇准备工作》 一文中,表明了 PhoneInterfaceManager 和 SubscriptionController 运行在 phone 进程(com.android.phone)中,因此,此文章,先引领读者简单认识一下 phone 以及 PhoneInterfaceManager 和 SubscriptionController 的创建过程。

一般情况下,phone 的源码在 AOSP 的路径是:

packages/services/Telephony/

一般情况下,phone 所依赖的 framework 源码路径是:

frameworks/opt/telephony/frameworks/base/telephony/

一般情况下,phone 的产物是:

TeleService.apk

一般情况下,放置在手机的路径是:

/system/priv-app/TeleService/

Phone概要

Phone 是一个 App 的形式运行在 Android 系统,所以 phone 具有生命。当然 phone 是一个特殊的 app,它没有 launcher 入口,更多的是作为一个“service”的身份在工作。但是 phone 不是完全没有 UI 的代码,但是它的 UI 一般是通过系统其它 APP 启动。如在拨号器中启动通话设置,如下图:

初识com.android.phone_第1张图片

Phone 是 Android 手机里面一个非常核心的 APP,因此,在 AndroidManifest.xml 中,必须有如下配置:

android:persistent="true"

让 phone 持久化运行在 Android 系统中。

Phone的作用

Phone 是 Android 手机里面一个非常核心的 APP,没有了 phone,就无法进行一切的无线电业务,例如通话,短信等等。

Phone对外业务

首先,必须了解 phone 在无线电业务中所处的位置,如下图:

初识com.android.phone_第2张图片

由上图可知,Phone 在上层是业务中枢,对上层业务,Phone 需要与其它无线电业务模块进行通信,如通话模块,短信模块,数据上网模块;往下,Phone 需要与 RILC 进行通信,在这里,Phone 端有 RILJ 模块,RILJ 和 RILC 通过 socket 进行通信;Modem 就是和有线上网的猫是实现一样的功能,Modem 是手机与基站进行通信的设备。关于 RIL 和 Modem,会因为芯片厂商的不同,往往有很大的区别,笔者不在本文在阐述这些模块,读者如果感兴趣,可以查阅相关资料。

因此,我们可以想象得到,以一个通话业务为例,其流程必定是:

初识com.android.phone_第3张图片

Phone业务

  1. CDMA 业务(支持CDMA的手机)
  2. GSM 业务(支持GSM的手机)
  3. IMS业务(支持IMS的手机)
  4. EUICC业务(支持EUICC的手机。embedded SIM,嵌入式SIM卡)
  5. MBMS业务(MBMS:Multimedia Broadcast Multicast Service,多媒体广播多播业务)
  6. CAT业务(STK等在线业务)
  7. 数据连接业务
  8. SIP业务(Session Initiation Protocol,VoLTE,ViLTE)

Phone的启动

在上文中,提到 phone 是一个持久化的应用,因此,在手机开机启动的过程中,在 ActivityManagerService 等系统服务启动完毕后,会启动 persistent 的 app。Phone 在此时就被启动起来。

在 APP 的启动过程中,会先实例化 Applicaiton 对象,代表整个 App 最高的对象。这些对于 APP 开发者而言,是多么的熟悉,因为在 Manifest.xml 中,你必须指定应用的 Application。Phone 的 application 标签信息如下:

.....<application android:name="PhoneApp"    android:persistent="true"    android:label="@string/phoneAppLabel"    .....    android:defaultToDeviceProtectedStorage="true"    android:directBootAware="true">.....

这里,先啰嗦一下 defaultToDeviceProtectedStorage 和 directBootAware 属性,这两个属性和 Android 的文件级加密有关,读者可以阅读《Android加密之文件级加密》一文了解它们。

从 phone 的 manifest.xml 文件中的 application 标签可以知道,Phone 对 Application 对象就行了继承,命名为 PhoneApp。

public class PhoneApp extends Application {    PhoneGlobals mPhoneGlobals;    @Override    public void onCreate() {        .....        mPhoneGlobals = new PhoneGlobals(this);        mPhoneGlobals.onCreate();        mTelephonyGlobals = new TelephonyGlobals(this);        mTelephonyGlobals.onCreate();        .....    }}

这个类定义在文件 packages/services/Telephony/src/com/android/phone/PhoneApp.java 中。

在上面的代码中,依次实例化了 PhoneGlobals 和 TelephonyGlobals 对象,然后调用各自的 onCreate() 方法。

接着看 PhoneGlobals 的过程

public void onCreate() {    .....    // Initialize the telephony framework    PhoneFactory.makeDefaultPhones(this);    .....    phoneMgr = PhoneInterfaceManager.init(this, PhoneFactory.getDefaultPhone());    .....}

这个方法定义在文件 packages/services/Telephony/src/com/android/phone/PhoneGlobals.java 中。

PhoneInterfaceManager创建过程

调用 PhoneInterfaceManager 的 init() 方法初始化 PhoneInterfaceManager。

static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {        synchronized (PhoneInterfaceManager.class) {            if (sInstance == null) {                sInstance = new PhoneInterfaceManager(app, phone);            } else {                Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);            }            return sInstance;        }    }

这个方法定义在文件 packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java 中。

接着看 PhoneInterfaceManager 的构造方法

private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {        mApp = app;        mPhone = phone;        mCM = PhoneGlobals.getInstance().mCM;        .....        publish();    }

这个方法定义在文件 packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java 中。

接着看 publish()

private void publish() {    if (DBG) log("publish: " + this);    ServiceManager.addService("phone", this);}

这个方法定义在文件 packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java 中。

在 publish() 中,把 PhoneInterfaceManager 添加到 System service 中,标签是 phone。读者不了解 System Server 的,可以阅读《Android系统之System Server大纲》一文。

时序图

初识com.android.phone_第4张图片

SubscriptionController的创建过程

回到 PhoneGlobals 的 onCreate 方法,接着看 makeDefaultPhones()

public static void makeDefaultPhone(Context context) {    .....    //根据SIM卡的配置,实例化Phone对象    int numPhones = TelephonyManager.getDefault().getPhoneCount();    sPhones = new Phone[numPhones];    for (int i = 0; i < numPhones; i++) {                    Phone phone = null;                    int phoneType = TelephonyManager.getPhoneType(networkModes[i]);                    if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {                        phone = telephonyComponentFactory.makePhone(context,                                sCommandsInterfaces[i], sPhoneNotifier, i,                                PhoneConstants.PHONE_TYPE_GSM,                                telephonyComponentFactory.getInstance());                    } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {                        phone = telephonyComponentFactory.makePhone(context,                                sCommandsInterfaces[i], sPhoneNotifier, i,                                PhoneConstants.PHONE_TYPE_CDMA_LTE,                                telephonyComponentFactory.getInstance());                    }                    sPhones[i] = phone;                }    // 初始化 SubscriptionController    SubscriptionController.init(context, sCommandsInterfaces);    .....}

这个方法定义在文件 frameworks/opt/telephony/src/java/com/android/internal/telephony/PhoneFactory.java 中。

接着看 init 方法

public static SubscriptionController init(Context c, CommandsInterface[] ci) {    synchronized (SubscriptionController.class) {        if (sInstance == null) {            //实例化对象            sInstance = new SubscriptionController(c);        } else {        }        return sInstance;    }}

这个方法定义在文件 frameworks/opt/telephony/src/java/com/android/internal/telephony/SubscriptionController.java 中。

如上面的代码,new 一个 SubscriptionController 的实例对象,接着看构造方法

protected SubscriptionController(Context c) {    //调用了 init    init(c);}

这个方法定义在文件 frameworks/opt/telephony/src/java/com/android/internal/telephony/SubscriptionController.java 中。

继续接着看 init 方法

protected void init(Context c) {    mContext = c;    mCM = CallManager.getInstance();    mTelephonyManager = TelephonyManager.from(mContext);    .....    if(ServiceManager.getService("isub") == null) {        //添加到 System Server        ServiceManager.addService("isub", this);    }}

这个方法定义在文件 frameworks/opt/telephony/src/java/com/android/internal/telephony/SubscriptionController.java 中。

如上面的代码,在 init 方法中,把 SubscriptionController 添加到 System service 中,标签是 isub。

时序图

初识com.android.phone_第5张图片

总结

在本文初步了解 Phone 的作用,Phone 在手机中的重要性,Phone 所完成的业务,以及运行在 phone 进程中的 PhoneInterfaceManager 和 SubscriptionController 的创建过程,它们在 System service 中的标签分别是 “phone” 和 “isub”。

更多相关文章

  1. Android Studio R.java文件在哪
  2. android 反编译:解决xml二进制文件
  3. android获取各种系统路径的方法
  4. Android中实现下载和解压zip文件功能代码分享
  5. android 应用如何获取系统权限 以及root系统方法
  6. Android 和 JS 交互时调用不成功解决方法
  7. android应用程序最小化的处理方法
  8. Android新线程中更新主线程UI中的View方法汇总
  9. Android文件解压工具类

随机推荐

  1. Android Studio 默认keystore 以及自定义
  2. 理解Android的layout和measure
  3. Android 中的WiFi学习笔记----WIFI启动
  4. android平台移植总结
  5. VMware安装Android全解
  6. 《大话移动APP测试:Android与iOS应用测试
  7. Android -SQLite数据库存储
  8. Android RabbitMQ之Android初探
  9. Android禁止EditText自动弹出软键盘的方
  10. Android Gradle权威指南