android通话流程浅析RIL层.docx
- 文档编号:5421530
- 上传时间:2022-12-16
- 格式:DOCX
- 页数:31
- 大小:24.71KB
android通话流程浅析RIL层.docx
《android通话流程浅析RIL层.docx》由会员分享,可在线阅读,更多相关《android通话流程浅析RIL层.docx(31页珍藏版)》请在冰豆网上搜索。
android通话流程浅析RIL层
拨出电话流程:
1在系统源码这个路径下/packages/apps/Phone/src/com/android/phone/DialtactsActivity.java
contacts的androidmanifest.xmlandroid:
process="android.process.acore"说明此应用程序运行在acore进程中。
DialtactsActivity的intent-filter的action属性设置为main,catelog属性设置为launcher,所以此activity能出现,首先启动的就是这个activity在主菜单中,并且是点击此应用程序的第一个界面。
dialtactsactivity包含四个tab,分别由TwelveKeyDialer、RecentCallsListActivity,两个activity-aliasDialtactsContactsEntryActivity和DialtactsFavoritesEntryActivity分别表示联系人和收藏tab,但是正真的联系人列表和收藏是由ContactsListActivity负责。
2
进入TwelveKeyDialerOnClick方法,按住的按钮id为:
R.id.digits,执行
placecall()
Intentintent=newIntent(Intent.ACTION_CALL_PRIVILEGED,
Uri.fromParts("tel",number,null));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
3、
intert.ACTION_CALL_PRIVILEGED实际字符串为android.intent.action.CALL_PRIVILEGED,通过查找知道了packegs/phone下面的androidmanifest.xml中PrivilegedOutgoingCallBroadcasteractivity-alias设置了intent-filter,所以需要找到其targetactivity为OutgoingCallBroadcaster。
所以进入OutgoingCallBroadcaster的
onCreate()
//如果为紧急号码马上启动intent.setClass(this,InCallScreen.class);startActivity(intent);
IntentbroadcastIntent=newIntent(Intent.ACTION_NEW_OUTGOING_CALL);
if(number!
=null)broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER,number);
broadcastIntent.putExtra(EXTRA_ALREADY_CALLED,callNow);
broadcastIntent.putExtra(EXTRA_ORIGINAL_URI,intent.getData().toString());
if(LOGV)Log.v(TAG,"Broadcastingintent"+broadcastIntent+".");
sendOrderedBroadcast(broadcastIntent,PERMISSION,null,null,
Activity.RESULT_OK,number,null);
4、Intent.ACTION_NEW_OUTGOING_CALL实际字符串为android.intent.action.NEW_OUTGOING_CALL,通过查找知道了packegs/phone
下面的androidmanifest.xml中OutgoingCallReceiverReceiver接收此intent消息。
找到OutgoingCallReceiver,执行
onReceive()函数
IntentnewIntent=newIntent(Intent.ACTION_CALL,uri);
newIntent.putExtra(Intent.EXTRA_PHONE_NUMBER,number);
newIntent.setClass(context,InCallScreen.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5、请求拨号的java部分流程
onCreate(第一次)/onNewIntent(非第一次)
internalResolveIntent
placeCall(intent);
PhoneUtils.placeCall(mPhone,number,intent.getData());
phone.dial(number);
mCT.dial(newDialString);
dial(dialString,CommandsInterface.CLIR_DEFAULT);
cm.dial(pendingMO.address,clirMode,obtainCompleteMessage());//obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
send(rr);
msg=mSender.obtainMessage(EVENT_SEND,rr);
acquireWakeLock();
msg.sendToTarget();
RILSender.handleMessage()
caseEVENT_SEND:
...
s.getOutputStream().write(dataLength);
s.getOutputStream().write(data);//从这里流程跑到下面ril.cpp中监听部份
6、请求拨号的c/c++部分流程
6.1、初始化事件循环,启动串口监听,注册socket监听。
rild.c->main()
(1)、RIL_startEventLoop
//建立事件循环线程
ret=pthread_create(&s_tid_dispatch,&attr,eventLoop,NULL);
//注册进程唤醒事件回调
ril_event_set(&s_wakeupfd_event,s_fdWakeupRead,true,
processWakeupCallback,NULL);
rilEventAddWakeup(&s_wakeupfd_event);
//建立事件循环
ril_event_loop
for(;;){
...
n=select(nfds,&rfds,NULL,NULL,ptv);
//Checkfortimeouts
processTimeouts();
//Checkforread-ready
processReadReadies(&rfds,n);
//Fireaway
firePending();
}
(2)、funcs=rilInit(&s_rilEnv,argc,rilArgv);//实际是通过动态加载动态库的方式执行reference-ril.c中的RIL_Init
//单独启动一个线程读取串口数据
ret=pthread_create(&s_tid_mainloop,&attr,mainLoop,NULL);
fd=open(s_device_path,O_RDWR);
ret=at_open(fd,onUnsolicited);
ret=pthread_create(&s_tid_reader,&attr,readerLoop,&attr);
RIL_requestTimedCallback(initializeCallback,NULL,&TIMEVAL_0);
在initializeCallback中执行的程序:
setRadioState(RADIO_STATE_OFF);
at_handshake();
/*note:
wedon'tcheckerrorshere.Everythingimportantwill
behandledinonATTimeoutandonATReaderClosed*/
/*atchannelistolerantofechobutitmust*/
/*haveverboseresultcodes*/
at_send_command("ATE0Q0V1",NULL);
/*Noauto-answer*/
at_send_command("ATS0=0",NULL);
...
//注册rildsocket端口事件监听到事件循环中
(3)、RIL_register(funcs);
s_fdListen=android_get_control_socket(SOCKET_NAME_RIL);
ret=listen(s_fdListen,4);
ril_event_set(&s_listen_event,s_fdListen,false,
listenCallback,NULL);//将此端口加入事件select队列
rilEventAddWakeup(&s_listen_event);
如果rildsocket端口有数据来了将执行listencallback函数
listencallback
//为此客户端连接创建新的监听句柄,s_fdListen继续监听其他客户端的连接。
s_fdCommand=accept(s_fdListen,(sockaddr*)&peeraddr,&socklen);
ril_event_set(&s_commands_event,s_fdCommand,1,
processCommandsCallback,p_rs);//将此端口加入事件select队列
rilEventAddWakeup(&s_commands_event);
6.2、socket监听,收到dial的socket请求
processCommandsCallback
//读数据到p_record中
ret=record_stream_get_next(p_rs,&p_record,&recordlen);
processCommandBuffer(p_record,recordlen);
p.setData((uint8_t*)buffer,buflen);
//statuscheckedatend
status=p.readInt32(&request);
status=p.readInt32(&token);//请求队列中的序号
pRI=(RequestInfo*)calloc(1,sizeof(RequestInfo));
pRI->token=token;
/*
包含#include"ril_commands.h"语句,结构体如下:
typedefstruct{
intrequestNumber;
void(*dispatchFunction)(Parcel&p,structRequestInfo*pRI);
int(*responseFunction)(Parcel&p,void*response,size_tresponselen);
}CommandInfo;
*/
pRI->pCI=&(s_commands[request]);
pRI->p_next=s_pendingRequests;
s_pendingRequests=pRI;
pRI->pCI->dispatchFunction(p,pRI);
//假设是接收了dial指令,pRI->PCI->dispatchFunction(p,pRI),调用dispatchDial(p,pRI)
dispatchDial(p,pRI)
s_callbacks.onRequest(pRI->pCI->requestNumber,&dial,sizeof(dial),pRI);
inreference-ril.conRequest()
...
switch(request){
caseRIL_REQUEST_DIAL:
requestDial(data,datalen,t);
asprintf(&cmd,"ATD%s%s;",p_dial->address,clir);
ret=at_send_command(cmd,NULL);
err=at_send_command_full(command,NO_RESULT,NULL,NULL,0,pp_outResponse);
err=at_send_command_full_nolock(command,type,responsePrefix,smspdu,timeoutMsec,sponse);
err=writeline(command);
//此处等待,直到收到成功应答或失败的应答,如:
ok,connect,errorcme等
err=pthread_cond_wait(&s_commandcond,&s_commandmutex);
waiting....
waiting....
/*successorfailureisignoredbytheupperlayerhere.
itwillcallGET_CURRENT_CALLSanddeterminesuccessthatway*/
RIL_onRequestComplete(t,RIL_E_SUCCESS,NULL,0);
p.writeInt32(RESPONSE_SOLICITED);
p.writeInt32(pRI->token);
errorOffset=p.dataPosition();
p.writeInt32(e);
if(e==RIL_E_SUCCESS){
/*processresponseonsuccess*/
ret=pRI->pCI->responseFunction(p,response,responselen);
if(ret!
=0){
p.setDataPosition(errorOffset);
p.writeInt32(ret);
}
}
sendResponse(p);
sendResponseRaw(p.data(),p.dataSize());
blockingWrite(fd,(void*)&header,sizeof(header));
blockingWrite(fd,data,dataSize);
6.4、串口监听收到atd命令的应答"OK"或"nocarrier"等
readerLoop()
line=readline();
processLine(line);
handleFinalResponse(line);
pthread_cond_signal(&s_commandcond);//至此,前面的等待结束,接着执行RIL_onRequestComplete函数
6.5、java层收到应答后的处理,以dial为例子.
ril.java->RILReceiver.run()
for(;;)
{
...
length=readRilMessage(is,buffer);
p=Parcel.obtain();
p.unmarshall(buffer,0,length);
p.setDataPosition(0);
processResponse(p);
type=p.readInt();
if(type==RESPONSE_SOLICITED){
processSolicited(p);
serial=p.readInt();
rr=findAndRemoveRequestFromList(serial);
rr.mResult.sendToTarget();
......
}
CallTracker.java->handleMessage(Messagemsg)
switch(msg.what){
caseEVENT_OPERATION_COMPLETE:
ar=(AsyncResult)msg.obj;
operationComplete();
cm.getCurrentCalls(lastRelevantPoll);
第二部分:
unsolicited消息从modem上报到java的流程。
c++部份
readerLoop()
line=readline();
processLine(line);
handleUnsolicited(line);
if(s_unsolHandler!
=NULL){
s_unsolHandler(line1,line2);//实际执行的是voidonUnsolicited(constchar*s,constchar*sms_pdu)
if(strStartsWith(s,"+CRING:
")
||strStartsWith(s,"RING")
||strStartsWith(s,"NOCARRIER")
||strStartsWith(s,"+CCWA")
)
RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,NULL,0);
p.writeInt32(RESPONSE_UNSOLICITED);
p.writeInt32(unsolResponse);
ret=s_unsolResponses[unsolResponseIndex].responseFunction(p,data,datalen);
ret=sendResponse(p);
sendResponseRaw(p.data(),p.dataSize());
ret=blockingWrite(fd,(void*)&header,sizeof(header));
blockingWrite(fd,data,dataSize);
java部份
ril.java->RILReceiver.run()
for(;;)
{
...
length=readRilMessage(is,buffer);
p=Parcel.obtain();
p.unmarshall(buffer,0,length);
p.setDataPosition(0);
processResponse(p);
processUnsolicited(p);
response=p.readInt();
switch(response){
...
caseRIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
ret=responseVoid(p);break;
...
}
switch(response){
caseRIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
if(RILJ_LOGD)unsljLog(response);
mCallStateRegistrants
.notifyRegistrants(newAsyncResult(null,null,null));
...
}
第三部分、第四部分:
猫相关的各种状态的监听和通知机制/通话相关的图标变换的工作原理。
网络状态,edge,gprs图标的处理
a、注册监听部分
==>SystemServer.java
init2()
Threadthr=newServerThread();
thr.setName("android.server.ServerThread");
thr.start();
ServerThread.run()
com.android.server.status.StatusBarPolicy.installIcons(context,statusBar);
sInstance=newStatusBarPolicy(context,service);
//phone_signal
mPhone=(TelephonyManager)context.getSystemSe
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- android 通话 流程 浅析 RIL