深入分析Android系统中电话服务的注册机制
android android phone service framework 131

在Android系统架构中,电话服务是一个核心系统服务,它向应用程序提供了与电话硬件交互的接口。本文将深入分析Android系统中电话服务如何注册到系统框架中,以及它如何与其他组件进行通信。

1. Android系统服务概览

在Android系统中,系统服务是以进程间通信(IPC)的方式提供给应用程序使用的。这些服务通常运行在system_server进程中,但电话服务是个例外,它运行在自己的独立进程中。

电话服务的实现主要包含在com.android.phone包中,并且会被打包成独立的APK文件安装在系统中。尽管它是一个独立的APK,但它仍然需要与系统框架进行集成,让其他应用可以通过标准API来访问电话功能。

2. 电话服务的核心组件

在分析服务注册之前,我们需要了解电话服务的几个核心组件:

  1. PhoneGlobals: 电话应用的Application类,负责初始化电话服务相关组件

  2. PhoneInterfaceManager: 实现了ITelephony.Stub接口,是电话服务的具体实现

3. 服务注册的代码分析

3.1 PhoneInterfaceManager的初始化

电话服务的注册过程始于PhoneGlobalsonCreate()方法中,它会调用PhoneInterfaceManager.init()方法来初始化电话接口管理器:

// 位于packages/services/Telephony/src/com/android/phone/PhoneGlobals.java
// 链接: https://android.googlesource.com/platform/packages/services/Telephony/+/refs/heads/android10-release/src/com/android/phone/PhoneGlobals.java
@Override
public void onCreate() {
    // ...其他初始化代码
    
    // 初始化PhoneInterfaceManager
    phoneMgr = PhoneInterfaceManager.init(this);
    
    // ...更多初始化代码
}

PhoneInterfaceManager.init()方法是一个静态方法,它会创建PhoneInterfaceManager的单例实例:

// 位于packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java
    /* package */ static PhoneInterfaceManager init(PhoneGlobals app, FeatureFlags featureFlags) {
        synchronized (PhoneInterfaceManager.class) {
            if (sInstance == null) {
                sInstance = new PhoneInterfaceManager(app, featureFlags);
            } else {
                Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
            }
            return sInstance;
        }
    }

3.2 服务注册到ServiceManager

PhoneInterfaceManager的构造函数中会调用publish()方法,将自己注册到系统的ServiceManager中:

// 位于packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java
private PhoneInterfaceManager(PhoneGlobals app, FeatureFlags featureFlags) {
    mApp = app;
    mPhone = phone;
    mCM = PhoneGlobals.getInstance().mCM;
    // ...更多初始化代码
    
    publish();
}

 private void publish() {
    if (DBG) log("publish: " + this);
    TelephonyFrameworkInitializer
            .getTelephonyServiceManager()
            .getTelephonyServiceRegisterer()
            .register(this);
}

这段代码是关键,它将PhoneInterfaceManager对象注册为名为"telephony"的系统服务。

4. 电话服务与telephony.registry的区别

在Android系统中,除了名为"telephony"的服务,还有一个名为"telephony.registry"的服务。这两个服务是不同的:

  1. telephony服务:由PhoneInterfaceManager实现

  2. telephony.registry服务:由TelephonyRegistry实现

TelephonyRegistry也是在系统启动过程中注册的,但它是在SystemServer中注册的:

// 位于frameworks/base/services/core/java/com/android/server/SystemServer.java
private void startServices() {
    // ...其他服务启动代码
    
    traceBeginAndSlog("StartTelephonyRegistry");
    telephonyRegistry = new TelephonyRegistry(context);
    ServiceManager.addService("telephony.registry", telephonyRegistry);
    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    
    // ...更多服务启动代码
}

6. 总结

通过上面的分析,我们理解了Android系统中电话服务的注册过程:

  1. PhoneGlobals在启动时初始化PhoneInterfaceManager

  2. PhoneInterfaceManager调用publish将自己注册为系统服务

  3. 应用通过TelephonyManagerContext.TELEPHONY_SERVICE常量来访问电话服务

  4. 电话服务(telephony)和电话注册服务(telephony.registry)是两个不同的服务,分别负责不同的功能

这种基于Binder和ServiceManager的服务注册和访问机制是Android系统架构的核心部分,不仅用于电话服务,也用于其他系统服务如WindowManager、ActivityManager等。


参考资料

  1. Android Open Source Project: https://source.android.com/

  2. Android源码: https://android.googlesource.com/

  3. Android系统源码: frameworks/base和packages/services/Telephony

深入分析Android系统中电话服务的注册机制
http://blog.xinrao.moe/archives/shen-ru-fen-xi-androidxi-tong-zhong-dian-hua-fu-wu-de-zhu-ce-ji-zhi
作者
伏秋洛
发布于
更新于
许可