日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Telephony 分析【全】

發(fā)布時(shí)間:2023/12/20 Android 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Telephony 分析【全】 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

11年下半年一直在做RIL的移植,主要解決第三方庫的一些bug,使之能更好的工作在公司的PAD上。但是后來發(fā)現(xiàn)遠(yuǎn)遠(yuǎn)不夠,有好多問題出現(xiàn)在Framework層。比方說我們想讓PAD支持熱插拔,盡管底層做好了,但上層還會出現(xiàn)很多問題,如PIN/PUK解鎖功能,用戶把解鎖PIN/PUK的界面打開但時(shí)把卡拔掉了,此時(shí)無法解鎖的,系統(tǒng)如何響應(yīng)此時(shí)情況,怎么做,這都是需要了解Telephony Framework之后知道如何實(shí)現(xiàn)的。

于是研究了一番Telephony的Java框架,剛開始接觸時(shí)感覺挺復(fù)雜很混亂,現(xiàn)在理清了關(guān)系,所以希望能幫到那些還在糾結(jié)中的同志。

大致網(wǎng)絡(luò)連接分析Android Telephony Framework層,關(guān)于ril及其移植的文章有很多所以就不贅述了。

以下部分內(nèi)容引自前段時(shí)期我關(guān)于Telephony的總結(jié)做的PPT,參考了不少前輩的文章,用英文寫的,懶得再譯回來了,湊合著看吧(當(dāng)時(shí)為了翻譯成英文還煞費(fèi)苦心- -!),需要PPT原件可以在此?http://wenku.baidu.com/view/bfe5361afad6195f312ba61c.html?下載,重要的和難理解的地方會做些解釋,文章較長,一篇日志不讓保存所以共分為四部分。

先來個(gè)整體結(jié)構(gòu)圖,有個(gè)大致印象,看完本文回頭再看應(yīng)該會有更深的理解。

?

1.Telephony Framework

Telephony framework contains a set of telephony API for applications. There are two?categaries?of JAVA?pacakges?in telephony framework:

1.The internal telephony packages -??

??com.android.internal.telephony.*,

???source code:?frameworks/base/telephony/java/com/android/internal/telephony

2.The open telephony packages -

??android.telephony.*.

???source code:?frameworks/base/telephony/java/android/telephony

The internal packages are used for Android default telephony application -?Phone.apk, and the open packages are for any 3rd?party telephony applications.


?

Internal Telephony Packages:

frameworks/base/telephony/java/com/android/internal/telephony

The public interface?Phone?is used to control the phone. The abstract class?PhoneBase?implements this interface. And the class?GSMPhone?extends this abstract class.

Phone.java

44 public interface Phone{ 326 String getPhoneName(); 332 int getPhoneType(); 1118 void setPreferredNetworkType(int networkType Message response); 1125 void getPreferredNetworkTypeMessage response); ...

The default telephony application could use?makeDefaultPhones()?and?getDefaultPhone()?in the class?PhoneFactory?to obtain the unique instance of Phone. The code below shows how this be done.

packages/apps/Phone/src/com/android/phone/PhoneApp.java


410???? public void onCreate() { ? ? ? ? ?? ... 425???????? if (phone == null) { 426???????????? // Initialize the telephonyframework 427???????????? PhoneFactory.makeDefaultPhones(this); 428 429???????????? // Get the default phone 430???????????? phone = PhoneFactory.getDefaultPhone();

PhoneFactory.java

56 public static void makeDefaultPhone(Context context) { ... 130 sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); 132 int phoneType = getPhoneType(networkMode); if (phoneType == Phone.PHONE_TYPE_GSM) { 135 sProxyPhone = new PhoneProxy(new GSMPhone(context, sCommandsInterface, sPhoneNotifier)); 137 } else if (phoneType == Phone.PHONE_TYPE_CDMA) {


Let’s suppose the current network mode is in GSM/GPRS, so the default telephony application could obtain a?PhoneProxy?to a?GSMPhone, and use its API to achieve telephony functionalities.ProxyPhone?is also extended from?Phone. It is used to abstract the specific instance of a specific network mode.

PhoneProxy.java

?57?????public PhoneProxy(Phone phone) {

?58?????????mActivePhone = phone;

????????????...

?66?????????mCommandsInterface = ((PhoneBase)mActivePhone).mCM;

?67?????????mCommandsInterface.registerForRadioTechnologyChanged(

?68?????????????????this, EVENT_RADIO_TECHNOLOGY_CHANGED, null);

?69?????}?

????????...

549?????public void getPreferredNetworkType(Message response) {

550?????????mActivePhone.getPreferredNetworkType(response);

551?????}????????


The class?PhoneBase?has a member?mCM?of the type?CommandsInterface. And this is assigned in the constructor of?GSMPhone.


GSMPhone.java

130?????GSMPhone (Context context,?CommandsInterface ci, PhoneNotifier notifier,

???????????????????????????????boolean unitTestMode) {

131?????????super(notifier, context,?ci, unitTestMode);

????????????...


PhoneBase.java

114?????public CommandsInterface mCM;

????????...

203?????protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci,

204?????????????boolean unitTestMode) {

207?????????mLooper = Looper.myLooper();

208?????????mCM = ci;

????????...

757?????public void getPreferredNetworkType(Message response) {

758?????????mCM.getPreferredNetworkType(response);

759?????}


All the telephony functionalities which need sending AT command to RIL daemon should be achieved by the?the?interface?CommandsInterface. And the class?RIL?implements this interface.??Moreover,?RILalso extends the abstract class?BaseCommands?to provide unsolicited result code to default telephony application.


CommandsInterface.java

27?????public interface CommandsInterface {

1332?????void getPreferredNetworkType(Message response);


BaseCommands.java

36 public abstract class BaseCommands implements CommandsInterface {??????


RIL.java

199 public final class RIL extends BaseCommands implements CommandsInterface {

1861?????public void getPreferredNetworkType(Message response)?{

1862?????????RILRequest rr = RILRequest.obtain(

1863?????????????????RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, response);

1867?????????send(rr); //call sender and send to target



?
想說說為何網(wǎng)絡(luò)需要狀態(tài)機(jī)管理,DcDefaultState下面所有狀態(tài)狀態(tài),子狀態(tài)無法處理的EVENT都由他來處理,這是狀態(tài) 機(jī)機(jī)制,大前提。

圖中初始狀態(tài)紅色部分,狀態(tài)切換時(shí)候,事件均由處理,無法處理交給父狀態(tài)處理,當(dāng)一個(gè)EVENT_CONNECT事件時(shí)候,狀態(tài)切換到DcActivingState,此時(shí)若有事件發(fā)給狀態(tài)機(jī)此狀態(tài)處理,無法處理交給父狀態(tài)處理,當(dāng)網(wǎng)絡(luò)連接成功(SetupResult==SUCCESS)切換到綠色表示狀態(tài),綠色分DcActiveState表示網(wǎng)絡(luò)連接成功了,比如此狀態(tài)來個(gè)EVENT_CONNECT事件(此事件網(wǎng)絡(luò)斷開狀態(tài)發(fā)起網(wǎng)絡(luò)連接)不會自己處理因?yàn)?/span>此時(shí)網(wǎng)絡(luò)已經(jīng)連接成功了,連,狀態(tài)只會處理EVENT_DISCONNECT事件),事件交由父狀態(tài)DcDefaultState處理。

通過此機(jī)制,可以讓網(wǎng)絡(luò)狀態(tài)得到穩(wěn)定有序管理。

展示了如何發(fā)起一個(gè)網(wǎng)絡(luò)連接 (最后為連接成功狀態(tài))

?
下圖以HUAWEI-RIL 2.3為例,展示第三方如何網(wǎng)絡(luò)請求響應(yīng)的(ril的機(jī)制要有基本了解)

?

感覺Telephony有點(diǎn)復(fù)雜,事件多,Telephony不僅包括Call,MMS,SIM?card,網(wǎng)絡(luò)連接管理包括運(yùn)營商,電話薄,解鎖功能一塊,感覺非常龐大?,其實(shí)事件雖多,框架基本類似,也就是觸類旁通,掌握一個(gè),自然能夠順藤摸瓜,解決其他問題。 上面的圖根據(jù)ANDROID ICS的源碼畫的,華為模塊的RIL_VERSION 2.3。


下面內(nèi)容就是通知機(jī)制了,網(wǎng)絡(luò)狀態(tài)變化為例,status?bar信號一會2一會滿格,其原理怎么實(shí)現(xiàn)



Telephony framework needs to track the network return value and events???happened in RIL daemon. At the same time, default telephony application should also be able to be notified by telephony framework.

In the constructor of?GSMPhone, a?GsmServiceStateTracker?would be created to track the network status. And in the?contructor?of?GsmServiceStateTracker, it would register to?RIL?for network status message.?


gsm/GSMPhone.java

101?????GsmServiceStateTracker mSST;

130?????public GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier,

??????????????????boolean unitTestMode) {

????????????...

139?????????mSST = new GsmServiceStateTracker (this);


gsm/GsmServiceStateTracker.java

186?????public GsmServiceStateTracker(GSMPhone phone) {

189????????this.phone = phone;

190????????cm = phone.mCM;

204????????cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);


It registers into a registrant list of?BaseCommands.

BaseCommands.java

58??????protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();

????????...

324?????public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) {

325?????????Registrant r =?new Registrant (h, what, obj);

327?????????mVoiceNetworkStateRegistrants.add(r);

328?????}


When network state changes, the endless loop waiting for the message in telephony framework will be notified by RIL daemon. And the message is?deliverred?to registrant.

RIL.java

2395?????private void

2396?????processUnsolicited (Parcel p) {

?????????????????...

2467?????????????case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:

2468?????????????????if (RILJ_LOGD) unsljLog(response);

2469

2470?????????????????mVoiceNetworkStateRegistrants

2471?????????????????????.notifyRegistrants(new?AsyncResult(null, null, null));


GsmServiceStateTracker?is a subclass of Handler.

When RILJ call?notifyRegistrants(), the?registed?handler?obj?will call?sendMessage(msg), thenhandleMessage() will be call.

gsm/GsmServiceStateTracker.java

260?????public void handleMessage (Message msg) {

261?????????AsyncResult ar;

262?????????int[] ints;

263?????????String[] strings;

264?????????Message message;

265

266?????????switch (msg.what) {

????????????????...

304?????????????case?EVENT_NETWORK_STATE_CHANGED:

305?????????????????pollState();

306?????????????????break;

Open telephony packages:

frameworks/base/telephony/java/android/telephony

??????

TelephonyManager?provides a way for 3rd application??interacting with internal telephony packages.

Class Overview (from android?sdk?document)

Provides access to information about the telephony services on the device. Applications can use the methods in this class to determine telephony services and states, as well as to access some types of subscriber information. Applications can also register a listener to receive notification of telephony state changes.

You do not instantiate this class directly; instead, you retrieve a reference to an instance throughContext.getSystemService(Context.TELEPHONY_SERVICE).

Note that access to some telephony information is?permission-protected. Your application cannot access the protected information unless it has the appropriate permissions declared in its manifest file. Where permissions apply, they are noted in the?the?methods through which you access the protected information.




?這個(gè)詳細(xì)一下,這個(gè)演示第三方應(yīng)用,Phone Service及Telephony關(guān)系。

第一條主線,TelephonyManager上半部分PhoneApp一個(gè)非常特殊app,通過調(diào)用PhoneFactory'創(chuàng)建一個(gè)Telephony(Internal),同時(shí)第三方application暴露接口,通過TelephonyManager調(diào)用,TelephonyManager通過ITelephonyandroid的AIDL機(jī)制)獲得PhoneInterfaceManager遠(yuǎn)程對象然后第三方application通過這個(gè)遠(yuǎn)程對象調(diào)用service方法這里調(diào)用兩個(gè)獨(dú)立進(jìn)程之間進(jìn)行如果不清楚aidl可以3rd?application直接調(diào)用了PhoneInterfaceManager方法,實(shí)際上需要通過TelephonyManager才能調(diào)用


第二條主線,TelephonyManager右半部分,TelephonyRegistry,顧名思義,什么東西注冊,這種注冊一般都是為了實(shí)現(xiàn)回調(diào)功能這個(gè)類主要作用就是第三方Appnew的PhoneStateListener需要監(jiān)聽動作通過調(diào)用TelephonyManager注冊到TelephonyRegistry,當(dāng)底層狀態(tài)變化通知GSMPhone時(shí),GSMPhone的DefaultPhoneNotifier通知TelephonyRegistry,然后注冊到TelephonyRegistry的PhoneStateListener監(jiān)聽事件會被觸發(fā)(此時(shí)TelephonyRegistry還會發(fā)個(gè)boardCast),然后回調(diào)上層APP復(fù)寫方法。

(要理清關(guān)系的最好辦法就是結(jié)合圖閱讀源碼,那樣會有更深的理解)

如果上面機(jī)制看不懂也沒關(guān)系,作為SDK開發(fā)只要知道以下部分行,


If we want to track telephony state in 3rd?application:

1??We should?retrive?an instance of?TelephonyManager?and get Phone service. ? ? ?//needed 2 ?Implement a?PhoneStateListener?what you want to listen. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //not needed 3 ?You can also register a?BroadCastReceiver?to receive broadcast if you want. ? ? ? //not needed 4 ?Don’t forget add permission in manifest file. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//needed

Take Settings as example to show how to achieve these.

packages/apps/Settings/src/com/android/settings/deviceinfo/ Status.java

111?????private TelephonyManager mTelephonyManager;

???????

169?????private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {

170?????????@Override

171?????????public void?onDataConnectionStateChanged(int state) {

???????????????UpdateDataState();??//you can override with your own code here

???????

178?????protected void onCreate(Bundle icicle) {????????????

184?????????mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);

268?????protected void onResume() {

278?????????????mTelephonyManager.listen(mPhoneStateListener,

279???????????????????????PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);

337?????private void updateDataState() {

338?????????int state = mTelephonyManager.getDataState();

341?????????switch (state) {



總結(jié)

以上是生活随笔為你收集整理的Android Telephony 分析【全】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。