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這兩個目錄是從功能上劃分的,理論上合併到一起也都是沒問題的。
本文並不完善,多有無奈,之後慢慢補全