android通话过程RIL层详细分析(代码)

本文深入探讨了 Android 通话过程中 RIL(Radio Interface Layer)层的角色,从 Java 代码到 C/C++ 代码层面详细阐述了拨号请求的流程,包括如何从 DialtactsActivity 启动拨号、通过 OutgoingCallReceiver 接收 ACTION_NEW_OUTGOING_CALL 意图、RIL 请求拨号的 Java 和 C/C++ 部分流程,以及通话状态监听和通知机制。文章还提及了网络状态和通话相关图标的变化原理。
 

拨出电话流程:

在系统源码这个路径下/packages/apps/Phone/src/com/android/phone/DialtactsActivity.java

contactsandroidmanifest.xmlandroid:process="android.process.acore"说明此应用程序运行在acore进程中。DialtactsActivityintent-filteraction属性设置为maincatelog属性设置为launcher,所以此activity能出现首先启动的就是这个activity在主菜单中,并且是点击此应用程序的第一个界面。dialtactsactivity包含四个tab,分别由TwelveKeyDialerRecentCallsListActivity,两个activity-aliasDialtactsContactsEntryActivityDialtactsFavoritesEntryActivity分别表示联系人和收藏tab,但是正真的联系人列表和收藏是由ContactsListActivity负责。

2

进入TwelveKeyDialer OnClick方法,按住的按钮id为:R.id.digits,执行

placecall()

Intent intent = 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.xmlPrivilegedOutgoingCallBroadcasteractivity-alias设置了intent-filter,所以需要找到其targetactivityOutgoingCallBroadcaster。所以进入OutgoingCallBroadcaster


onCreate()

//如果为紧急号码马上启动intent.setClass(this,InCallScreen.class); startActivity(intent);


Intent broadcastIntent = new Intent(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, "Broadcasting intent " + broadcastIntent+ ".");


       sendOrderedBroadcast(broadcastIntent, PERMISSION, null, null,


                            Activity.RESULT_OK, number, null);


4Intent.ACTION_NEW_OUTGOING_CALL实际字符串为android.intent.action.NEW_OUTGOING_CALL,通过查找知道了packegs/phone


下面的androidmanifest.xmlOutgoingCallReceiver Receiver接收此intent消息。找到OutgoingCallReceiver,执行


onReceive()函数


Intent newIntent = new Intent(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()


                  case EVENT_SEND:


                    ...


                   s.getOutputStream().write(dataLength);                  


                    s.getOutputStream().write(data);//从这里流程跑到下面ril.cpp中监听部份


6、请求拨号的c/c++部分流程(APPA层RIL_java进入RIL 层)


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


         // Check for timeouts


         processTimeouts();


         // Check for read-ready


         processReadReadies(&rfds, n);


         // Fire away


         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();


      


      


      


      at_send_command("ATE0Q0V1", NULL);


      


      at_send_command("ATS0=0", NULL);


      ...






  //注册rild socket端口事件监听到事件循环中


  (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);




    如果rild socket端口有数据来了将执行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.2socket监听,收到dialsocket请求


processCommandsCallback


  //读数据到p_record


  ret= record_stream_get_next(p_rs, &p_record, &recordlen);


processCommandBuffer(p_record, recordlen);


   p.setData((uint8_t *) buffer, buflen);


评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值