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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Telephony 分析【全】

發布時間:2023/12/20 Android 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Telephony 分析【全】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

于是研究了一番Telephony的Java框架,剛開始接觸時感覺挺復雜很混亂,現在理清了關系,所以希望能幫到那些還在糾結中的同志。

大致網絡連接分析Android Telephony Framework層,關于ril及其移植的文章有很多所以就不贅述了。

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

先來個整體結構圖,有個大致印象,看完本文回頭再看應該會有更深的理解。

?

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



?
想說說為何網絡需要狀態機管理,DcDefaultState下面所有狀態狀態,子狀態無法處理的EVENT都由他來處理,這是狀態 機機制,大前提。

圖中初始狀態紅色部分,狀態切換時候,事件均由處理,無法處理交給父狀態處理,一個EVENT_CONNECT事件時候,狀態切換到DcActivingState,此時若有事件發給狀態此狀態處理,無法處理交給父狀態處理,網絡連接成功(SetupResult==SUCCESS)切換到綠色表示狀態,綠色分DcActiveState表示網絡連接成功了,比如此狀態來個EVENT_CONNECT事件(此事件網絡斷開狀態發起網絡連接)不會自己處理因為此時網絡已經連接成功了,連,狀態只會處理EVENT_DISCONNECT事件),事件交由父狀態DcDefaultState處理。

通過此機制,可以讓網絡狀態得到穩定有序管理。

展示了如何發起一個網絡連接 (最后為連接成功狀態)

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

?

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


下面內容就是通知機制了,網絡狀態變化為例,status?bar信號一會2一會滿格,其原理怎么實現



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.




?這個詳細一下,這個演示第三方用,Phone Service及Telephony關系。

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


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

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

如果上面機制看不懂也沒關系,作為SDK開發只要知道以下部分行,


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) {



總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。