1. 所有流程的起点是从拨号后按下拨号键开始,此步的代码在/android sourcecode/packages/Contacts/src/com/android/contacts/目录的TwelveKeyDialer.java文件中,相关代码如下:

dialButtonPressed() {.........final String number = mDigits.getText().toString();startActivity(newDialNumberIntent(number));mDigits.getText().clear();finish();}
代码中newDialNumberIntent()方法定义如下:

private Intent newDialNumberIntent(String number) {final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts("tel", number, null));.............}
从newDialNumberIntent的定义可以看出,当拨号键按下以后,TwelveKeyDial会启动一个特定的组件,该组件的ACTION为:ACTION_CALL_PRIVILEGED,经过查找,该ACTION启动的组件是目下:/android sourcecode/packeges/Phone/的一个文件,在该文件下的AndroidMenifest.xml中可以查到:“ACTION_CALL_PRIVILEGED”启动的Activity的名字是:PrivilegedOutgoingCallBroadcast,但是我们到/android sourcecode/packeges/Phone/src/....目下并找不到该文件,因为该文件在AndroidMenifest.xml中标记有点特殊:

<activity-alias />,这个标签的意思是这个Activity是另一个Activity的别名,真实的Activity在标签中用“android:targetActivity = OutgoingCallBroadcast”标出,所以 “ACTION_CALL_PRIVILEGED”启动的PrivilegedOutgoingCallBroadcast 所对应的真实“身份”是 “OutgoingCallBroadcast”。

2. 这个时候电话的数据已经流到OutgoingCallBroadcast.java中了。

在OutgoingCallBroadcast.java的onCreate()方法中有:

protected void onCreate(Bundle icicle) {.......Intent intent = getIntent();........String action = intent.getAction();.......final boolean emergencyNum = (number != null) && PhoneNumUtils.isEmergencyNumber(number);//判断号码是否是紧急号码.......if (Intent.ACTION_CALL_PRIVILEGED.equals(action)) {action = emergencyNum ? Intent.ACTION_CALL_EMERGENCY : Intent.ACTION_CALL;intent.setAction(action);}.......intent.setClass(this, InCallScreen.class);startActivity(intent);}

在这个方法中,判断如果所收到的ACTION是“ACTION_CALL_PRIVILEGED”,那么根据所输入的号码是否是紧急号码进行转换,如果是紧急号码,则ACTION = Intent.ACTION_CALL_EMERGENCY,否则ACTION = Intent.ACTION_CALL,并启动转换Activity :InCallScreen.java

3. InCallScreen.java依然在目录/packeges/Phone/src/com/android/phone下。

InCallScreen的onCreate中调用initInCallScreen初始化打电话界面,并调用registerForPhoneStates注册电话状态监听.

在onNewIntent()方法中有:

protected void onNewIntent(Intent intent) {..........String action  = intent.getAction();..........else if (action.equals(Intent.ACTION_CALL) || action.equals(Intent.ACTION_CALL_EMERGENCY)) {..........InCallInitStatus status = placeCall(intent);}}//placeCallprivate InCallInitStatus placeCall(Intent intent) {..............int callStatus  = PhoneUtils.placeCall(........);}
InCallScreen.java中的placeCall方法调用PhoneUtils.java文件的placeCall方法。

4.PhoneUtils.java依然在目录/packeges/Phone/src/com/android/phone下。

public static int placeCall(...) {Connection connection;connection = PhoneApp.getInstance().mCM.dial(phone, numberToDial);}
继续追踪,在PhoneApp.java中发现,mCM是CallManager.java类的一个对象,而CallManager.java是属于frameworks层的,所以,这个时候数据流已经进入frameworks.

5. 进入/frameworks/base/telephony/java/com/android/internal/telephony目录。

在CallManager.java的dial()方法中,有:

public Connection dial(Phone phone, String dialNumber) throws CallStateException {Phone basePhone = getPhoneBase(phone);Connection result;result = basePhone.dial(dialString);........}private static Phone getPhoneBase(Phone phone) {if (phone instanceof PhoneProxy) {return phone.getForegroundCall().getPhone();}return phone;}

继续追踪会发现:
PhoneBase.java抽象类实现了接口Phone.java,而GSMPhone.java又实现了抽象类PhoneBase,所以:

上述代码中:phone.getForegroundCall()实际相当于GSMPhone对象执行了getForegroundCall()方法。

6. 继续追踪GSMPhone.java,该类位于/frameworks/base/telephony/java/com/android/internal/telephony/gsm/下。

GSMPhone.java:GsmCallTracker mCT;public GsmCall getForegroundCall() {return mCT.foregroundCall;}
可以看出getForegroundCall()函数继续调用GsmCallTracker.java的foregroundCall属性。

7.GsmCallTracker.java位于/frameworks/base/telephony/java/com/android/internal/telephony/gsm/下.

GsmCallTracker.java:GSMCall foregroundCall = new GSMCall(this);

打开GSMCall.java,找到getPhone()方法,发现:

GSMCallTracker owner;public Phone getPhone() {return owner.phone;}

而在GSMCallTracker.java中有如下声明:

GSMPhone phone;

到此,我们得出一下结论:第5部分标记红色的代码所返回的就是GSMPhone的对象,进一步可以得出,第5部分蓝色标记的代码即是调用了GSMPhone对象的dial方法。

8. 在GSMPhone.java中:

GSMCallTracker mCT;public Connection dial(String dialString) throws CallStateException {return dial(dialString, null);}public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException {.......mCT.dial(.......);}

继续调用GSMCallTracker.java中的dial()方法:

GSMCallTracker.java:GSMCallTracker(GSMPhone phone) {cm = phone.mCM;}Connection dial(String dialString, int clirMode, UUSInfo uusInfo) {cm.dial(........);}
追踪mCM,发现 :

public CommandsInterface mCM;

所以GSMCallTracker持有CommandsInterface对象,即RIL.Java类的对象,所以"cm.dial(....)"即是调用RIL类对象的dial()方法。

9. RIL.java

BOSS出现。

RIL对象负责把客户端的通话请求按照一定的格式发送给"rild"socket,至此,请求过程完毕。







更多相关文章

  1. Android(安卓)最火框架XUtils之注解机制详解
  2. Android的事件转递机制
  3. Android权威编程指南读书笔记(1-2章)
  4. Android:使用ViewPager实现左右滑动切换图片 (简单版)
  5. 监控android binder size
  6. StagefrightPlayer&&AwesomePlayer 初步分析
  7. 浅谈Java中Collections.sort对List排序的两种方法
  8. 类和 Json对象
  9. Python list sort方法的具体使用

随机推荐

  1. Android资源访问
  2. Android下使用lamemp3库将PCM录音数据压
  3. Android之如果解决Android(安卓)studio项
  4. ListView中显示圆形图像
  5. android Input系统事件分发流程
  6. Android回部古剑之ViewFlipper之仙人指路
  7. Android开发 ADB配置调试命令图解
  8. Android原理揭秘系列之View、ViewGroup
  9. WebView 使用Android(安卓)原生ToolBar
  10. android应用程序签名详解