Android 源碼分析-打電話和發短信

1. ITelephony接口和ISms接口以及AIDL
 在我們的Android應用中,當需要實現電話撥號時,我們需要進行如下調用
 ITelephony phone = (ITelephony)ITelephony.Stub.asInterface(ServiceManager.getService("phon"))
 phone.dial("10086");
   對於短信應用,我們需要的是調用SmsManager,代碼如下
   SmsManager manager = SmsManager.getDefault();
   manager.sendTextMessage("10086",null,"hi,this is sms",null,null);
   這裏,SmsManager對ISms做了一層包裝,實質上是通過調用
   ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
   simISms.sendRawPdu....
  
  可以看到,應用都是採用AIDL來實現IPC的跨進程調度。
  對於AIDL應用,調用進程方存在的是一個實現接口的Proxy對象,通過Proxy對象與被調用進程中的Stub對象進行
  通訊來實現IPC的跨進程調度,所以,在被調用進程一端必定有一個ITelephony.Stub類以及ISms.Stub類的實現。

  2. PhoneInterfaceManager和SimSmsInterfaceManager
   ITelephony.Stub 的實現類爲com.android.phone.PhoneInterfaceManager
   ISms.Stub的實現類爲com.android.internal.telephony.gsm.SimSmsInterfaceManager
   從這兩個類的構造器的調用代碼裏可以很清楚的看到進行了Service的註冊工作
   ServiceManager.addService("phone",this);
   ServiceManager.addService("isms",this);

  3. PhoneApp,InCallScreen,PhoneUtils及其他相關類
  從SimSmsInteferManager的相關方法實現中可以看到,具體就是調用GSMPhone的SmsDispatcher實例來進行相關操作的。
  從PhoneInterfaceManager會維持一個Phone對象的引用,當撥號應用時,PhoneInterfaceManager會將構造好的Intent傳遞
給PhoneApp應用,該Intent的className指定則爲InCallScreen,從中我們可以看到InCallScreen具體是通過PhoneUtils調用Phone的
相關方法來實現。
  PhoneInterfaceManager怎麼獲取到對應的Phone對象,然後又怎麼將Phone對象傳遞到InCallScreen中呢?
  具體這裏涉及到了PhoneApp這個類,從這個類維護了一個 PhoneInterfaceManager的引用(phoneMgr)以及一個Phone引用(phone),
從該類的onCreate方法中我們可以清楚的看到,PhoneApp通過PhoneFactory獲取了一個Phone實例,並通過該實例實現了PhoneInterfaceManager對象。
因此,我們現在只需要關注PhoneFactory具體提供的是一個什麼樣的Phone實例了。
  另外,PhoneApp類還提供了一個靜態方法getInstance供InCallScreen調用,InCallScreen正是通過調用該方法獲得PhoneApp實例從而
獲得對應的Phone實例的。
  接下來,我們通過查看PhoneFactory的方法可以看到,Phone對象對應的就是一個GSMPhone實例。

  4。GSMPhone與RIL
  從GSM的構造器可以看出,他依賴一個CommandInterface接口實例,通過PhoneFactory的makeDefaultPhones方法,我們可以看到,根據系統環境變量
ro.radio.noril來判斷是否需要採用RIL框架實現,如果該參數不爲空,則採用Simultedcommands(主要是爲了測試需要提供的模擬實現).否則,採用RIL。
  通過Google才知道,RIL其實是智能手機上實現AP與BP之間通信的一種設計思想,具體大家可以參見這篇文章http://www.eetchina.com/ARTICLES/2006OCT/PDF/CPCOL_2006OCT26_EMB_TA_170.PDF?SOURCES=DOWNLOAD
  在RIL.java 中我們很驚喜的看到,RIL對對消息的處理是將消息通過LocalSocket發送到以rild爲名稱的有名端口。這個有名Socket的創建在ril.cpp代碼中。
  s_fdListen = android_get_control_socket(SOCKET_NAME_RIL)
  原來Android通話和發短信的應用是JAVA與C++代碼之間透過Socket連接來傳輸消息來實現的。

  5.關於C代碼與硬件之間的交互
  這部分工作其實就是C代碼通過串口發送AT指令來撥號,收發短信。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章