Call接打流程分析.ppt_第1页
Call接打流程分析.ppt_第2页
Call接打流程分析.ppt_第3页
Call接打流程分析.ppt_第4页
Call接打流程分析.ppt_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、,U,CALL接打流程分析,Unicair Communication Tec Co., Ltd. 烟台友开通信技术有限公司,目录,1.Android电话系统之RIL分析 2.Android Phone接听处理流程 3.Android Phone去电处理流程,Android电话系统之RIL分析,智能机在硬件上多采用双cpu的架构,一个是基带处理器(BP),一个是应用处理器(AP),BP主要处理数字信号、语音信号的编码解码以及GSM通信协议,手机射频通讯控制等功能。AP主要是运行操作系统和各种应用程序,应用处理器通过AT命令集与带GPRS功能的无线通讯模块通信。 RIL(Radio Interf

2、ace Layer)位于应用程序框架与内核之间,负责数据的可靠传输、AT命令的发送以及response的解析。RIL支持SMS、Voice Call,上网等功能。 Android设计电话系统时,建立了一个虚拟电话系统, RIL则是将虚拟电话系统的标准功能转换成实际的所使用的Modem的AT指令。,RIL,rild,RIL-Java,采用Socket通讯方式,在ril.cpp中创建Socket对象,RIL模块,Phone模块,主要用于与下层的rild进行通信,为上层应用提供电话功能接口,实现电话功能,Android电话系统之RIL分析,Android电话系统的框架构成图,SOCKET,串口,Ri

3、ld,Event loop,Read loop,RILReceiver,RILSender,Ril,异步处理机制,Command Interface,Phone Service,GSMPhone/CDMAPhone,CallNotifier,CallManager,DataConnectionTracker,CallTracker,Connection,DefaultPhoneNotifier,Android电话系统之RIL分析,1. RIL.java Command Interface,大多数Modem都是根据通讯协议提供接口,这些接口都是电话的基本功能的描述是对Modem AT指令的提炼抽

4、象。, dial setMute conference acceptCall rejectCall sendDTMF getCurrrentCalls setupDataCall getPreferredVoicePrivacy hangupWaitingOrBackground,Android中利用Result Message 和RILRequest对象来完成Request和Result的对应关系。,以acceptcall为例看一下接口代码的实现:,acquireWakeLock()函数实际是发送了一个 EVENT_WAKE_LOCK_TIMEOUT消息,调用send函数后将请求消息发送到S

5、ender的架构,Android电话系统之RIL分析,2. RIL.java RILSender,class RILSender extends Handler implements Runnable,RILSender,Send(rr),handleMessage EVENT_SEND,mRequestsList.add(rr),RILRequest类用到的 实例变量:,LocalSocket s; s = mSocket; byte data;,data = rr.mp.marshall(); rr.mp.recycle(); rr.mp = null;,s.getOutputStream

6、().write(dataLength); s.getOutputStream().write(data);,Android电话系统之RIL分析,3. RIL.java RILReceiver,Receiver通过Socket接收读取从RILD传递过来的Response Parcel。Response分为两种类型,一种是URC,一种是命令应答。对于URC将会直接分发到通知注册表中的Handler。而命令应答则通过Receiver的异步通知机制传递到命令的发送者进行相应处理。,Android Phone接听处理流程,来电处理流程(以CDMAPhone为例):,1.创建CdmaPhone时,在其构

7、造方法中调用init函数:,2.创建CdmaCallTracker时: cm.registerForCallStateChanged(this,EVENT_CALL_STATE_CHANGE,null); 最终调用mCallStateRegistrants.add(r);将事件加入RegistrantList列表中去。这样,当底层收到相应的消息后,就能通过注册机制,经过处理,传到相应的Handler里面进行处理。 下面通过实际的模拟来电,看一下消息的传递处理流程。,Android Phone接听处理流程,来电处理流程(以CDMAPhone为例):,打开eclipse在DDMS模式下向模拟器拨号

8、,在RIL.java的RILReceiver线程(run()函数)中接收到rild发来的incoming消息,此消息为主动上报的消息,所以在processUnsolicited (p)函数中处理,然后又转到:,这样消息就转到了mCallStateRegistrants(RegistrantList.java类中)的notifyRegistrants()函数进行处理了,此函数调用internalNotifyRegistrants(); internalNotifyRegistrant的函数如下所示:,消息是由Handler类型的h发出的,所以到Handler类中查找handleMessage,此

9、函数为空实现,Android Phone接听处理流程,来电处理流程(以CDMAPhone为例):,CallTracker类继承自Handler类, CallTracker类为抽象类,其handleMessage(Message msg)函数仍为空,其有两个子类CdmaCallTracker和GsmCallTracker。在CdmaCallTracker.java中handleMessage(Message msg)函数有如下语句: case EVENT_REPOLL_AFTER_DELAY: case EVENT_CALL_STATE_CHANGE: pollCallsWhenSafe();

10、break; 在CallTracker类中,pollCallsWhenSafe()函数的实现如下: protected void pollCallsWhenSafe() needsPoll = true; if (checkNoOperationsPending() lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); cm.getCurrentCalls(lastRelevantPoll); 其中 public CommandsInterface cm; 即为前面讲述的RIL的接口。于是,转到RIL.java中处理。 publi

11、c void getCurrentCalls (Message result) RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result); if (RILJ_LOGD) riljLog(rr.serialString() + “ ” + requestToString(rr.mRequest); send(rr); 当消息处理完后,RIL.java的接收线程又会收到相应的消息,此处为命令响应的消息,进入processSolicited (Parcel p)处理。,Android Phone接听处理流程,来电

12、处理流程(以CDMAPhone为例): 1.cdmacalltracker.java中消息的处理 EVENT_POLL_CALLS_RESULT: -handlePollCalls(AsyncResult)msg.obj); handlPollCalls调用phone.notifyNewRingingConnection(newRinging); PhoneApp中创建CallNotifier: notifier = CallNotifier.init(this, phone, ringer, mBtHandsfree, new CallLogAsync(); CallNotifier注册:r

13、egisterForNewRingingConnection -mNewRingingConnectionRegistrants.addUnique(h,what,obj);(此处为callmanager对象调用的相应的register 函数) EVENT_OPERATION_COMPLETE (事件处理完毕收到的消息) - operationComplete(); 2.进入APP层后,首先在callnotifier.java中进行处理,调用onNewRingingConnection.,Android Phone接听处理流程,如果返回值为true,则调用 PhoneUtils.hangupR

14、ingingCall(ringing);挂断电话,如果上面两方法返回为false, onNewRingingConnection()又会调用startIncomingCallQuery()方法,该方法就查询用户设置的铃声(可能是系统默认铃声,也可能是用户自定义铃声)。 如果查询完成则直接调用onQueryComplete().如果查询超时的话,将会发送一个延时Message RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT ,延时后将默认调用系统的铃声。如果在延时发送Message过程中Query已经完成,由于CallNotifier实现了OnQueryComplete

15、Listener,就会自动调用onQueryComplete()方法,该方法将会首先把可能存在的延时Message给Remove,以防止再次设置铃声。 接着调用onCustomRingQueryComplete()方法。然后该方法里面会调用Ringer的ring()方法启动响铃或震动。 然后会调用showIncomingCall(),通知到状态栏,显示来电界面等。具体流程如下页所讲。,来电处理流程(APP层的处理) 来电挂断或播放振铃,CallNotifier类extends Handler并且implements CallerInfoAsyncQuery.OnQueryCompleteLis

16、tener监听,ignoreAllIncomingCalls checkCallReject,Android Phone接听处理流程,来电界面显示,按接听键处理流程,showIncomingCall() callnotifier.java,mApplication.notificationMgr. updateNotificationAndLaunchIncomingCallUi() ; callnotifier.java,updateInCallNotification(true); NotificationMgr.java,inCallPendingIntent = PendingInte

17、nt.getActivity (mContext, 0, PhoneApp.getInstance().createInCallIntent (currentCall.getPhone().getSubscription(), 0); NotificationMgr.java,InCallScreen.onCreate() 第一次 InCallScreen. onNewIntent() 以后,来电界面显示后,按接听键的处理: case KeyEvent.KEYCODE_CALL: boolean handled = handleCallKey();,if (hasRingingCall) in

18、ternalAnswerCall(); else if (currCallState = CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE),Call的处理状态:,一个phone有且仅有三个call,分别是RingCall,ForgroundCall以及BackgroundCall, 简单理解为每个call对应四种状态: Ring, Active, Hold,Idle,同一时刻三个Call只能有一个Ring状态(RingCall), 一个Active状态(ForgroundCall), 一个Hold状态(BackgroundCall),可以同时有三

19、个Idle状态。,然后调用onPhoneStateChanged更新屏幕,Android Phone拨打处理流程,APP层,关于拨号的代码在联系人目录下:vendorunicairappsContacts3srccomandroidcontactsdialpad 文件夹下 进入DialpadFragment .java onclick方法或onKey方法中调用dialButtonPressed(),final Intent intent = newDialNumberIntent(number); final Intent intent = new Intent(Intent.ACTION_C

20、ALL_PRIVILEGED, Uri.fromParts(tel, number, null); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);,在目录vendorunicairappsPhone3下面的AndroidManifest.xml查找此字符串,intert.ACTION_CALL_PRIVILEGED实际字符串为ent.action.CALL_PRIVILEGED,,从代码中看出,PrivilegedOutgoingCallBroadcaster activity-

21、alias设置了intent-filter,所以需要找到其 targetactivity为OutgoingCallBroadcaster。所以进入OutgoingCallBroadcaster的 onCreate()方法。,Android Phone拨打处理流程,拨号流程:,1.OutgoingCallBroadcaster.java,在其onCreate方法中调用processIntent(),在此函数中先用语句 if (Intent.ACTION_CALL_EMERGENCY.equals(action)判断是否为紧急号码,如果是, callNow = true;然后调用PhoneApp.

22、getInstance().callController.placeCall(intent); startActivity()进入incallscreen.java中处理。 如果不是紧急号码,则执行以下处理: Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); if (number != null) broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number); broadcastIntent.putExtra(EXTRA_ALREADY_CALLE

23、D, callNow); broadcastIntent.putExtra(EXTRA_ORIGINAL_URI, intent.getData().toString(); if (LOGV) Log.v(TAG, Broadcasting intent + broadcastIntent + .); sendOrderedBroadcast(broadcastIntent, PERMISSION, new OutgoingCallReceiver(), null, Activity.RESULT_OK, number, null); 然后会在OutgoingCallReceiver类中的处理

24、接收到的intent,具体流程见下页。,Android Phone拨打处理流程,拨号流程:,OutgoingCallReceiver 接收器 onReceive - doReceive- handleOutgoingCall(context, intent, uri, number);,newIntent = new Intent(Intent.ACTION_CALL, uri);,startOutgoingCall(context, newIntent, uri);,startCallController(newIntent);,PhoneApp.getInstance().callController.placeCall(intent);,placeCallInternal(intent);在此方法中会判断intent中传过来的参数,是否为紧急号码、受限号码,获取语音信箱,PhoneUtils.placeCall(mApp.mContext,phone,number,originalNumber, contactUri,(isEmergencyNumber | isEmergencyIntent), inCallUiSviderGa

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论