拨出电话流程:
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
进入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.xml中PrivilegedOutgoingCallBroadcasteractivity-alias设置了intent-filter,所以需要找到其targetactivity为OutgoingCallBroadcaster。所以进入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);
4、Intent.ACTION_NEW_OUTGOING_CALL实际字符串为android.intent.action.NEW_OUTGOING_CALL,通过查找知道了packegs/phone
下面的androidmanifest.xml中OutgoingCallReceiver 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.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);