【网学网提醒】:网学会员为需要朋友们搜集整理了android 通话处理流程(不错的资料)相关资料,希望对各位网友有所帮助!
android通话处理流程(转)
第一部分:从java端发送at命令的处理流程。拨出电话流程:1、contacts的androidmanifest.xmlandroid:process="android.process.acore"说明此应用程序运行在acore进程中。DialtactsActivity的intent-filter的action属性设置为main,catelog属性设置为launcher,所以此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(非第一次)internalResolveIntentplaceCall(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_loopfor(;;){...n=select(nfds,&;rfds,NULL,NULL,ptv);//CheckfortimeoutsprocessTimeouts();//Checkforread-readyprocessReadReadies(&;rfds,n);//FireawayfirePending();}(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();at_send_command("ATE0Q0V1",NULL);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);//statuscheckedatendstatus=p.readInt32(&;request);status=p.readInt32(&;token);//请求队列中的序号
pRI=(RequestInfo*)calloc(1,sizeof(RequestInfo));pRI->token=token;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....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){
ret=pRI->pCI->responseFunction(p,response,responselen);if(ret!=0){p.setDataPosition(errorOffset);p.writeInt32(ret);}}sendResponse(p);sendResponseRaw(p.data(),p.dataSize());6.4、串口监听收到atd命令的应答"OK"或"nocarrier"等readerLoop()line=readline();processLine(line);handleFinalResponse(line);pthread_cond_signal(&;s_commandcond);//至此,前面的等待结束,接着执行RIL_onRequestComplete函数blockingWrite(fd,(void*)&;header,sizeof(header));blockingWrite(fd,data,dataSize);
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.javainit2()Threadthr=newServerThread();thr.setName("android.server.ServerThread");thr.start();ServerThread.run()com.android.server.status.StatusBarPolicy.installIcons(context,statusBar);sInstance=newStatusBarPolicy(context,service);//phone_signalmPhone=(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);mPhoneData=IconData.makeIcon("phone_signal",null,com.android.internal.R.drawable.stat_sys_signal_null,0,0);mPhoneIcon=service.addIcon(mPhoneData,null);//registerforphonestatenotifications.((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE)).listen(mPhoneStateListener,PhoneStateListener.LISTEN_SERVICE_STATE|PhoneStateListener.LISTEN_SIGNAL_STRENGTH|PhoneStateListener.LISTEN_CALL_STATE|PhoneStateListener.LISTEN_DATA_CONNECTION_STATE|PhoneStateListener.LISTEN_DATA_ACTIVITY);//实际是调用的是TelephonyRegistry.listen,此listen函数会将Iphonestatelistener添加到对应的的handler数组中,到时来了事件会轮询回调。//data_connectionmDataData=IconData.makeIcon("data_connection",null,com.android.internal.R.drawable.stat_sys_data_connected_g,0,0);
mDataIcon=service.addIcon(mDataData,null);service.setIconVisibility(mDataIcon,false);b、事件通知部分==>PhoneFactory.javamakeDefaultPhones()sPhoneNotifier=newDefaultPhoneNotifier();useNewRIL(context);phone=newGSMPhone(context,newRIL(context),sPhoneNotifier);forexample==>DataConnectionTracker.javanotifyDefaultData(Stringreason)phone.notifyDataConnection(reason);mNotifier.notifyDataConnection(this,reason);==>DefaultPhoneNotifier.javamRegistry=ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),sender.isDataConnectivityPossible(),reason,sender.getActiveApn(),sender.getInterfaceName(null));
第五部分:gprs拨号上网的通路原理。上层java
程序调用gprs流程:=>PhoneApp.javaonCreate()PhoneFactory.makeDefaultPhones(this);phone=newGSMPhone(context,newSimulatedCommands(),sPhoneNotifier);mDataConnection=newDataConnectionTracker(this);createAllPdpList();//建立缺省pdpconnectionpdp=newPdpConnection(phone);
dataLink=newPppLink(phone.mDataConnection);dataLink.setOnLinkChange(this,EVENT_LINK_STATE_CHANGED,null);dataLink=newPppLink(phone.mDataConnection);dataLink.setOnLinkChange(this,EVENT_LINK_STATE_CHANGED,null);
//某个条件触发执行trySetupData(Stringreason)setupData(reason);pdp=findFreePdp();Messagemsg=obtainMessage();msg.what=EVENT_DATA_SETUP_COMPLETE;msg.obj=reason;pdp.connect(apn,msg);phone.mCM.setupDefaultPDP(apn.apn,apn.user,apn.password,obtainMess
age(EVENT_SETUP_PDP_DONE));
//收到EVENT_SETUP_PDP_DONE消息=>pdpconnection.javahandleMessage()caseEVENT_SETUP_PDP_DONE:dataLink.connect();//dataLink是pppLink.javaSystemService.start(SERVICE_PPPD_GPRS);//启动pppd_grps服务poll.what=EVENT_POLL_DATA_CONNECTION;sendMessageDelayed(poll,POLL_SYSFS_MILLIS);//启动轮询,看是否成功连接gprscheckPPP()//每隔5秒轮询,看是否连接成功,或断开//如果已经连接mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP);//执行到pdpconnection.handleMessage()caseEVENT_LINK_STATE_CHANGEDonLinkStateChanged(ls);
caseLINK_UP:notifySuccess(onConnectCompleted);onCompleted.sendToTarget();
//执行dataConnectionTracker.java的handleMessage()caseEVENT_DATA_SETUP_COMPLETEnotifyDefaultData(reason);setupDnsProperties();setState(State.CONNECTED);phone.notifyDataConnection(reason);startNetStatPoll();resetPollStats();1、读取发送出去的包数和接受到的包数2、如果发送的数据包且没有收到应答包数n大于等于看门狗追踪的限定包数。2.1、开始轮询pdpcontextlist,尝试恢复网络连接2.2、如果轮询24次后还没有联通网络则停止网络状态轮询,进行一次ping实验。2.2.1、如果ping成功则,重新进行网络状态轮询,否则发送EVENT_START_RECOVERY事件。//resetreconnecttimernextReconnectDelay=RECONNECT_DELAY_INITIAL_MILLIS;着重c++部分代码的角度分析=>DataConnectionTracker.javatrySetupData(Stringreason)setupData(reason);=>PdpConnection.javapdp.connect(apn,msg);=>RIL.JAVAphone.mCM.setupDefaultPDP(apn.apn,apn.user,apn.password,obtainMessage(EVENT_SETUP_PDP_DONE));send(rr);
//sendsockettoRIL
//enterc++layer=>ril.cppprocessCommandsCallback(intfd,shortflags,void*param)processCommandBuffer(p_record,recordlen);status=p.readInt32(&;request);pRI->pCI=&;(s_commands[request]);pRI->pCI->dispatchFunction(p,pRI);dispatchStrings();s_callbacks.onRequest(pRI->pCI->requestNumber,pStrings,datalen,pRI);=>reference-ril.conRequest();requestSetupDefaultPDP(data,datalen,t);err=write_at_to_data_channel("ATD*99***1#",1);
//afterawhile.get"connect"fromdatachannel,soneedtosendsocketmessagetojavalayer.p.writeInt32(RESPONSE_SOLICITED);p.writeInt32(pRI->token);//theserialNointherequestlist.errorOffset=p.dataPosition();p.writeInt32(e);if(e==RIL_E_SUCCESS){
ret=pRI->pCI->responseFunction(p,response,responselen);
if(ret!=0){p.setDataPosition(errorOffset);p.writeInt32(ret);}}
sendResponse(p);sendResponseRaw(p.data(),p.dataSize());ret=blockingWrite(fd,(void*)&;header,sizeof(header));blockingWrite(fd,data,dataSize);
=>RIL.JAVARILReceiver.run();length=readRilMessage(is,buffer);p=Parcel.obtain();p.unmarshall(buffer,0,length);p.setDataPosition(0);processResponse(p);processSolicited(p);serial=p.readInt();error=p.readInt();rr=findAndRemoveRequestF
romList(serial);ret=responseStrings(p);if(rr.mResult!=null){AsyncResult.forMessage(rr.mResult,ret,null);rr.mResult.sendToTarget();}
=>pdpConnection.javahandleMessage()caseEVENT_SETUP_PDP_DONE:...dataLink.connect();=>pppLink.javaSystemProperties.set(PROPERTY_PPPD_EXIT_CODE,"");SystemService.start(SERVICE_PPPD_GPRS);//启动pppd_grps服务
poll.what=EVENT_POLL_DATA_CONNECTION;sendMessageDelayed(poll,POLL_SYSFS_MILLIS);dataConnection.state=State.CONNECTING;handleMessage()caseEVENT_POLL_DATA_CONNECTIONcheckPPP();if(ArrayUtils.equals(mCheckPPPBuffer,UP_ASCII_STRING,UP_ASCII_STRING.length)||ArrayUtils.equals(mCheckPPPBuffer,UNKNOWN_ASCII_STRING,UNKNOWN_ASCII_STRING.length)&;&;dataConnection.state==State.CONNECTING)if(mLinkChangeRegistrant!=null){mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP);=>pdpConnection.javahandleMessage()caseEVENT_LINK_STATE_CHANGED:DataLink.LinkStatels=(DataLink.LinkState)ar.result;onLinkStateChanged(ls);caseLINK_UP:notifySuccess(onConnectCompleted);AsyncResult.forMessage(onCompleted);onCompleted.sendToTarget();
=>DataConnectionTracker.javahandleMessage()caseEVENT_DATA_SETUP_COMPLETE:...SystemProperties.set("gsm.defaultpdpcontext.active","true");notifyDefaultData(reason);setupDnsProperties();//设置dns,gw,我们的实现方式是在pppd中设置的,不用pppd拨号的适用。
setState(State.CONNECTED);phone.notifyDataConnection(reason);mNotifier.notifyDataConnection(this,reason);=>DefaultPhoneNotifier.java//mRegistry=ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));构造函数中初始化了mRegistrymRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),sender.isDataConnectivityPossible(),reason,sender.getActiveApn(),sender.getInterfaceName(null));startNetStatPoll();}第六部分:通话相关的语音通路切换原理、震动接口6、语音通路6.1、设置语音通路的路由目前我们有两处处理:a、CallTracker.java中handlePollCalls()检测到+clcc返回的电话列表中有状态为DriverCall.State.ALERTING(表示拨打电话后,对方已经振铃),此时需要设置语音通路为MODE_IN_CALLb、PhoneUtils.java中setAudioMode()函数c、调用通路分析AudioManageraudioManager=(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);audioManager.setMode(mode);AudioManager.setMode(mode);AudioService.setMode(mode);AudioSystem.setMode(mode);(nativefunction)android_media_AudioSystem.cpp==>android_media_AudioSystem_setMode()AudioSystem.cpp==>setMode()constsp
&;af=AudioSystem::get_audio_flinger();
binder=sm->getService(String16("media.audio_flinger"));...gAudioFlinger=interface_cast(binder);...returngAudioFlinger;通过查找“media.audio_flinger”发现AudioFlinger.cpp==>instantiate()//Main_mediaserver.cpp中被实例化。defaultServiceManage
r()->addService(String16("media.audio_flinger"),newAudioFlinger());mAudioHardware=AudioHardwareInterface::create();LOGV("CreatingVendorSpecificAudioHardware");hw=createAudioHardware();returnnewAudioHardwareMarvell();returnaf->setMode(mode);AudioHardwareLittle.cpp==>setMode(mode)doRouting();enable_incall_headphone()//orothers...system("alsactl-f/etc/alsactl/asound.state_nonerestore");system("alsactl-f/etc/alsactl/asound.state_headset_r_srestore");6.2、来电播放振铃,挂断或接听停止振铃。==>Phone.apponCreate()ringer=newRinger(phone);VibratormVibrator=newVibrator();mService=IHardwareService.Stub.asInterface(ServiceManager.getService("hardware"));notifier=newCallNotifier(this,phone,ringer,mBtHandsfree);mPhone.registerForIncomingRing(this,PHONE_INCOMING_RING,null);mPhone.registerForPhoneStateChanged(this,PHONE_STATE_CHANGED,null);mPhone.registerForDisconnect(this,PHONE_DISCONNECT,null);...casePHONE_INCOMING_RING:
mRinger.ring();mHardwareService.setAttentionLight(true);mVibratorThread.start();while(mContinueVibrating){mVibrator.vibrate(VIBRATE_LENGTH);SystemClock.sleep(VIBRATE_LENGTH+PAUSE_LENGTH);}...makeLooper();mRingHandler.sendEmptyMessage(PLAY_RING_ONCE);...casePLAY_RING_ONCE:PhoneUtils.setAudioMode(mContext,AudioManager.MODE_RINGTONE);r.play();...casePHONE_DISCONNECT:casePHONE_STATE_CHANGED:...mRinger.stopRing();Messagemsg=mRingHandler.obtainMessage(STOP_RING);msg.obj=mRingtone;mRingHandler.sendMessage(msg);caseSTOP_RING:r.stop();getLooper().quit();...mVibrator.cancel();第七部分:通话相关的notification服务7、通话相关的notification服务。7.1、NotificationMgr
==>PhoneApp.javaonCreate()NotificationMgr.init(this)//NotificationMgr.java//此类主要负责电话通知的具体表现(通知和取消通知),未接图标、通话中、蓝牙激活中、保持中,静音、免提等。封装了简单的瞬间显示文本消息的功能。提供漫游数据连接禁止的通知封装和漫游数据连接允许时取消通知sMe=newNotificationMgr(context);mNotificationMgr=(NotificationManagercontext.getSystemService(Context.NOTIFICATION_SERVICE);mStatusBar=(StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);//主要用于显示静音和speaker状态的图表(在状态条右边显示)sMe.updateNotifications();//主要功能是:1、查询是否有未读的未接听电话,并显示到状态栏图标,和通知列表2、根据是否是电话状态,更新状态栏图表和通知列表(可能是激活,蓝牙,保持等)7.2、CallNotifier==>PhoneApp.javaonCreate()notifier=newCallNotifier(this,phone,ringer,mBtHandsfree);//此类主要是监听通话相关的事件,然后进行例如来电播放铃声,震动。挂断、接听停止振铃等(调用Ringer类实现此功能),根据不同的状态调用调用NotificationMgr进行具体
的通知和取消通知。第八部分:通话相关的各种server电话通信相关的服务:(1)、从ServiceManager得到的:a、wifiServiceb、PhoneInterfaceManagerc、PhoneSubInfod、SimPhoneBookInterfaceManagere、SimSmsInterfaceManagerf、TelephonyRegistryg、NetStatServiceh、ConnectivityService
(2)、从ApplicationContext得到的:a、TelephonyManager