Telephony如何为第三方应用提供服务

Telephony

AIDL为第三方应用提供服务。

在frameworks/base/telephony/java/com/android/internal/telephony中有几个aidl文件,

-rw-r--r-- 1 chenzheng chenzheng  1537 2013-03-25 23:19 IPhoneStateListener.aidl 
-rw-r--r-- 1 chenzheng chenzheng  2484 2013-03-25 23:19 IPhoneSubInfo.aidl 
-rw-r--r-- 1 chenzheng chenzheng  7841 2013-03-25 23:19 ITelephony.aidl 
-rw-r--r-- 1 chenzheng chenzheng  1881 2013-03-25 23:19 ITelephonyRegistry.aidl 
-rw-r--r-- 1 chenzheng chenzheng  1963 2013-03-25 23:19 IWapPushManager.aidl 
-rw-r--r-- 1 chenzheng chenzheng  1007 2013-03-25 23:19 OperatorInfo.aidl 

在编译过程中会自动生成对应的Proxy和Stub。以ITelephony.aidl为例,会生成

  • ITelephony.Stub类;
  • ITelephony.Stub.Proxy

PhoneInterfaceManager则继承了ITelephony.Stub类实现其中定义的dial,call等方法。(PhoneInterfaceManager是个单例)
其构建过程中会将调用ServiceManager.addService添加服务。

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

    private void publish() {
        if (DBG) log("publish: " + this);

        ServiceManager.addService("phone", this);
    }

PhoneInterfaceManager服务的使用

在应用中:

ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
phone.call(number);

调用stub的asInterface()方法,会将IBinder类型转换成ITelephony类型,生成ITelephony.Stub.Proxy对象。然后调用该对象的call()方法,就会通过binder ipc调用stub提供的服务实现。

下图简要说明TelephonyManager所调用的跨进程的调用

用户通过Telephonymanager获取各个service。Telephonymanager整合了对上层的接口
例如getCurrentPhoneType。实际是

ITelephony telephony = getITelephony();
return telephony.getActivePhoneType();

通过ITelephony接口来获取的。

又比如getDeviceId,实际是

return getSubscriberInfo().getDeviceId();

而getSubscriberInfo()则是:

return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));

通过IPhoneSubInfo接口获取的。

而他们的具体实现分别在Phone应用的PhoneInterfaceManager和telephony-common 动态库的PhoneSubInfo(当然它也是跑在Phone进程里的)。

问题:

frameworks\opt\telephony和frameworks\base\telephony两个目录下都各有一个android.telephony和com.android.internal.telephony的package。两个包的区别是什么?

粗略的理解,可以理解两个包分别是为第三方应用提供,和为自带应用提供,如Phone应用。 com.android.internal.telephony包的API多分装为动态库,在Phone应用运行时运行在其进程中,其中的对象,或者一些单例都是在Phone进程中的,其他应用也是拿不到的。
而android.telephony则是通过AIDL向第三方提供的服务,第三方应用通过TelephonyManager访问到Telephony向外提供的一部分接口,例如获取状态信息神马的。而android.telephony同样也会调用com.android.internal.telephony中的接口来获取这些信息。这里用到了AIDL来跨进程调用。

frameworks\opt\telephony和frameworks\base\telephony分别得作用是什么?

frameworks\opt\telephony和frameworks\base\telephony目录下都分别有android.telephony和com.android.internal.telephony两个包
对于frameworks\base\telephony android.telephony包是为第三方应用提供的定义的是接口,com.android.internal.telephony是为系统应用提供的接口。
两个包中定义了很多AIDL,而实现则就分散各处的其他进程中了,比如Phone应用中。

frameworks\opt\telephony 则是telephony-common 动态库的实现,主要加载在Phone进程中,其中实现了Telephony的主题,主要负责沟通Phone等应用层和RIL层通信。
frameworks\opt\telephony 目录下同样有android.telephony和com.android.internal.telephony两个包,如果应用使用了telephony-common动态库,那他们和frameworks\base\telephony目录下的包是同一个包。所以从本质上讲frameworks\opt\telephony和frameworks\base\telephony这两个目录是从功能上划分的,理论上合并到一起也都是没问题的。

本文并不完善,多有无奈,之后慢慢补全

你可能感兴趣的:(android,frameworks)