天天看點

phone子產品的分析 1         Android系統啟動2         Phone子產品

 1         Android系統啟動

1.1      總體啟動架構圖

(1) init程序啟動

(2) Native服務啟動

(3) System Server,Android服務啟動

(4) Home啟動

phone子產品的分析 1         Android系統啟動2         Phone子產品

1.2    initial程序(system\core\init)

init程序,它是一個由核心啟動的使用者級程序。核心自行啟動(已經被載入記憶體,開始運作,并已初始化所有的裝置驅動程式和資料結構等)之後,就通過啟動一個使用者級程式init的方式,完成引導程序。init始終是第一個程序。

Init程序一起來就根據init.rc和init.xxx.rc腳本檔案建立了幾個基本的服務:

 servicemanamger

 zygote 。。。。

最後Init并不退出,而是擔當起property service的功能。

關于init的詳細資訊,參考相關文章。

1.3    Zygote

Servicemanager和zygote程序就奠定了Android的基礎。Zygote這個程序起來才會建立起真正的Android運作空間,初始化建立的Service都是Navtive service.在.rc腳本檔案中zygote的描述:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

是以Zygote從main(…)--frameworks\base\cmds\app_main.cpp開始。

(1) main(…)---frameworks\base\cmds\app_main.cpp

建立Java Runtime

runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);

(2) [email protected]

建立虛拟機

運作:com.android.internal.os.ZygoteInit:main函數。

(3)main()---com.android.internal.os.ZygoteInit//正真的Zygote。

registerZygoteSocket();//登記Listen端口

startSystemServer();

進入Zygote服務架構。

經過這幾個步驟,Zygote就建立好了,利用Socket通訊,接收ActivityManangerService的請求,Fork應用程式。

1.4      System Server

startSystemServer(com.android.internal.os.ZygoteInit)在Zygote上fork了一個程序: com.android.server.SystemServer.于是SystemServer(SystemServer.java)就建立了。Android的所有服務循環架構都是建立SystemServer(SystemServer.java)上。在SystemServer.java中看不到循環結構,隻是可以看到建立了init2的實作函數,建立了一大堆服務,并AddService到service Manager。

main() ( com/android/server/SystemServer )

{

 init1();

}

Init1()是在Native空間實作的(com_andoird_server_systemServer.cpp)。我們一看這個函數就知道了,init1->system_init() (System_init.cpp)

在system_init()我們看到了循環閉合管理架構。

{

 Call "com/android/server/SystemServer", "init2"

 ProcessState::self()->startThreadPool();

     IPCThreadState::self()->joinThreadPool();

}

init2()@SystemServer.java中建立了Android中所有要用到的服務。

這個init2()建立了一個線程,來New Service和AddService來建立服務

在其上建立了多個android服務,包括我們以後的“指紋識别”,也會是在這個總的服務架構内實施,需要做到資訊的收發處理,可以了解為。與底層JNI如何通信,與上層app如何互相傳遞資訊。

對于如何建立某個功能子產品的服務,不需要關注太多底層的東西(包括init,zygote等等)。需要關注如上的第四步 System Server

1.5      Home啟動

在ServerThread(SystemServer.java)後半段,我們可以看到系統在啟動完所有的Android服務後,做了這樣一些動作:

(1) 使用xxx.systemReady()通知各個服務,系統已經就緒。

(2)  特别對于ActivityManagerService.systemReady(回調)

2         Phone子產品

為了對android的server如何工作有個大緻的了解,以Phone子產品電話為例。

流程圖

phone子產品的分析 1         Android系統啟動2         Phone子產品

2.1      過程分析

Phone服務:是指Phone所能提供的各種服務(來電去電,短信,SIM的鎖定,資料連結傳輸等)與service不是同一個概念。

Phone 中的service是ITelephony和ITelephonyRegistry的實作類,PhoneInterfaceManager.java和TelephonyRegistry.java,後續說明。

GSMPhone 管理了電話服務的内部功能,也對RIL層進行了封裝,上層應用不能直接跟RIL本地代碼打交道,而是間接通過GSMPhone.但是應用層為了更友善的通路電話服務,需要在GSMPhone之上的TelephonyManager。

TelephonyManager通過兩個IBinder接口ITelephony和ITelephonyRegistry來完成這項工作。

ITelephony是電話服務使用者(使用者層或架構其他部分)主動進行RIL通路的路徑,它的服務端實作類不在代碼中,而是在Phone應用PhoneInterfaceManager.java(packages/apps/Phone/src/com/android/phone/)中。PhoneInterfaceManager.publish中以”phone”為名注冊該服務,提供撥号界面、呼叫、挂機等呼叫相關控制,也提供SIM PIN、開關Radio等操作,他的實作是通過調用Phone接口來操作。

ItelephonyRegistry提供一個通知機制,将底層狀态變更通知給電話服務的使用者(使用者層或架構其他部分),是使用者被動通知的路徑,通知消息如網絡狀态、信号強弱更新、電話狀态更新等。它的服務端實作在架構代碼中TelephonyRegistry.java(frameworks/base/services/java/com/android/server/)。

底層通知的來源,是GSMPhone通過PhoneNotifier的實作者DefaultPhoneNotifier将具體的事件轉化為函數調用并且通知到TelephonyRegistry。TelephonyRegistry再通過兩種方式通知給使用者,其一是廣播事件,另外一種是通過服務使用者在TelephonyRegistry中注冊的IphoneStateListener接口,實作回調。

SystemServer.java實作了電話服務的添加

………

ServiceManager.addService("telephony.registry",new TelephonyRegistry(context));

………

對于在SystemServer.java中添加的Service,SystemServer.java 中的init1()函數保證了Service在背景不斷運作,具體的底層實作,需要檢視文檔和源碼。

2.2      去電流程

不論打電話的方式是何種(撥号盤撥打,通話記錄中撥号,聯系人中撥号。。),都會觸發outgoingCallBroadcast的onCreate()函數,獲得Action & Number,并對其進行判斷,并且廣播給outgoingCallReceiver内部類,發送Intent.ACTION_NEW_OUTGOING_CALL消息。

outgoingCallReceiver收到Intent消息,調用onReceiver() -> doReceiver(),啟動InCallScreen界面。

進入InCallScreen後,可以分為15個函數調用。

具體的分析如下:

1.進入InCallScreen類中,如果是第一次進入,調用onCreate()函數(1),如果在通話過程再一次的撥打電話,調用onNewIntent()函數(2)。兩個函數都會調用IntentResolveIntent()函數(3),在這個函數中調用InCallScreen類中的成員方法placeCall()函數(4)。

InCallScreen中的placeCall()函數調用類PhoneUtils.placeCall()函數(5),PhoneUtils.placeCall()函數調用phone.dial()函數,至此app層的函數調用結束,轉到frameworks層。

InCallScreen.java 和PhoneUtils.Java在packages\apps\phone\src\com\android\phone…

(6) PhoneUtils.java中

static int placeCall(Phone phone, String number, Uri contactRef)

(7) Connection cn = phone.dial(number); 

GSMPhone.java

在phone應用程式中,通過PhoneFactory來擷取GSMPhone執行個體。

 GSMPhone()....

(8)dial(String dialString)

(9)mCT.dial(mmi.dialingNumber, mmi.getCLIRMode()); (PS: GsmCallTracker mCT)

GsmCallTracker.java

GsmCallTracker類 dial (String dialString)...

(10)dial (String dialString, int clirMode) {

...

(11)cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());

(ps: CommandInterface cm = phone.mCM)

...

}

因為 RIL.java (frameworks\base\telephony\java\com\android\internal\telephony):

public final class RIL extends BaseCommands implements CommandsInterface是以 cm.dial

實際上調用的是 RIL.java 中的dial -(12)

RIL.java

(12)dial (String address, int clirMode, Message result)

LRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);

(13)send()

(14) msg.sendToTarget();

target.sendMessage(this); (frameworks/base/core/java/android/os/Message.java)

//Handler.java (frameworks\base\core\java\android\os)

boolean sendMessage(Message msg){ 

       return sendMessageDelayed(msg, 0);

}

-->   return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);

--->    sent = queue.enqueueMessage(msg, uptimeMillis);

(15) RIL.java

class RILSender extends Handler implements Runnable{

//把消息放入到消息隊列

public void handleMessage(Message msg)

..

s.getOutputStream().write(dataLength);                    

s.getOutputStream().write(data);

...

 因為在 RIL.java 檔案中有 static final String SOCKET_NAME_RIL = "rild";

 run()函數中有:

                    s = new LocalSocket();

                    l = new LocalSocketAddress(SOCKET_NAME_RIL,

                            LocalSocketAddress.Namespace.RESERVED);

                    s.connect(l);

                    ...

                    mSocket = s;}

是以可以确定s.getOutputStream().write(data) 是往 rild 的socket寫資料。

到這裡,frameworks 請求結束,通過socket轉到RIL層處理 dial請求。

2.3      來電流程

1.建立GsmPhone時,mCT = new GsmCallTracker(this);

2.建立GsmCallTracker時:

    cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); -->   

    mCallStateRegistrants.add(r);

3.RIL中的RILReceiver線程首先讀取從rild中傳來的資料:processResponse -> processUnsolicited

4.對應于incoming call,RIL收到RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 消息,觸發mCallStateRegistrants中的所有記錄。

5.GsmCallTracker處理EVENT_CALL_STATE_CHANGE,調用pollCallsWhenSafe

6.函數pllCallsWhenSafe 處理:

     lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);

     cm.getCurrentCalls(lastRelevantPoll);

7.RIL::getCurrentCalls

    RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);

    ...

    send(rr);

8.接着RIL調用processSolicited處理RIL_REQUEST_GET_CURRENT_CALLS的傳回結果

9.GsmCallTracker的handleMessage被觸發,處理事件EVENT_POLL_CALLS_RESULT,調用函數 

    handlePollCalls

10.handlPollCalls 調用

    phone.notifyNewRingingConnection(newRinging);

11.PhoneApp中建立CallNotifier

12.CallNotifier注冊:

registerForNewRingingConnection ->

mNewRingingConnectionRegistrants.addUnique(h, what, obj);

2.4   小結

對Phone子產品的分析,并對具體的來電、去電流程的跟蹤,電話服務的架構式可以确定的,但是具體的實作細節還不清楚,這也是接下來的工作。

對于今後的新子產品Service,大體可以這樣實作:

1.            Service完成的内容要明确,實作可以按照大多數子產品那樣編寫AIDL檔案,産生對應的java檔案,通過繼承與實作方式,來具體實作Service内容

2.            上層不可以直接的調用Service内的函數,需要通過一個xxxManager.java來友善的操作Service發送的消息。如Phone中的TelephonyManager.java來管理操作,具體的操作又是通過ITelephony 和ITelephonyRegistry來完成。

3.            Service響應底層的事件,通過Broadcast發送Intent消息,應用層接收到消息事件,進行相應的處理。

4.            Service可以設定監聽,等到有回報時,進行處理

5.            Service啟動可以在SystemServer.java 中添加。