我们从按下拨号开始分析呼出电话的流程。此流程从拨号盘分析到RIL层。
@DialpadFragment.java public void dialButtonPressed() { //得到号码 final String number = mDigits.getText().toString(); //得到拨号的Intent final Intent intent = ContactsUtils.getCallIntent(number, (getActivity() instanceof DialtactsActivity ? ((DialtactsActivity)getActivity()).getCallOrigin() : null)); startActivity(intent); mClearDigitsOnStop = true; getActivity().finish(); }来看上面得到Intent的过程:
@ContactsUtils.java public static Intent getCallIntent(String number, String callOrigin) { 用号码构建一个类似tel:10086的Uri return getCallIntent(getCallUri(number), callOrigin); } public static Intent getCallIntent(Uri uri, String callOrigin) { final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, uri); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (callOrigin != null) { intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN, callOrigin); } return intent; }这个过程可以看出,发出的Intent由一下几个结构组成:
然后经过startActivity发送出去。那么是那个Activity接受的呢?
这个过程主要针对紧急呼叫处理(OutgoingCallBroadcaster.java)。
在Phone模块的AndroidManifest.xml文件中有如下描述:<activity-alias android:name="PrivilegedOutgoingCallBroadcaster" android:targetActivity="OutgoingCallBroadcaster" android:screenOrientation="nosensor" android:permission="android.permission.CALL_PRIVILEGED"> <intent-filter> <action android:name="android.intent.action.CALL_PRIVILEGED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="tel" /> </intent-filter> </activity-alias>activity-alias说明这个节点描述的Activity是另一个Activity的别名,也就是说,当前的PrivilegedOutgoingCallBroadcaster是指向OutgoingCallBroadcaster的。
@OutgoingCallBroadcaster.java protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.outgoing_call_broadcaster); mWaitingSpinner = (ProgressBar) findViewById(R.id.spinner); Intent intent = getIntent(); processIntent(intent); }继续往下看:
private void processIntent(Intent intent) { final Configuration configuration = getResources().getConfiguration(); String action = intent.getAction(); String number = PhoneNumberUtils.getNumberFromIntent(intent, this); //得到当前的号码 if (number != null) { if (!PhoneNumberUtils.isUriNumber(number)) { number = PhoneNumberUtils.convertKeypadLettersToDigits(number); number = PhoneNumberUtils.stripSeparators(number); } } else { } //判断是否是紧急拨号 final boolean isExactEmergencyNumber = (number != null) && PhoneNumberUtils.isLocalEmergencyNumber(number, this); final boolean isPotentialEmergencyNumber = (number != null) && PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, this); if (Intent.ACTION_CALL_PRIVILEGED.equals(action)) { if (isPotentialEmergencyNumber) { //紧急拨号的action action = Intent.ACTION_CALL_EMERGENCY; } else { //非紧急拨号的action action = Intent.ACTION_CALL; } //重新设置Action,当前不是紧急呼叫,因此Action改为ACTION_CALL intent.setAction(action); } if (Intent.ACTION_CALL.equals(action)) { if (isPotentialEmergencyNumber) { //判断不成立 } //当前的callNow为false callNow = false; } else if (Intent.ACTION_CALL_EMERGENCY.equals(action)) { //紧急呼叫的处理 } else { } Uri uri = intent.getData(); String scheme = uri.getScheme(); if (Constants.SCHEME_SIP.equals(scheme) || PhoneNumberUtils.isUriNumber(number)) { //互联网通话的处理 } //重新构建Intent Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); if (number != null) { broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number); } PhoneUtils.checkAndCopyPhoneProviderExtras(intent, broadcastIntent); broadcastIntent.putExtra(EXTRA_ALREADY_CALLED, callNow); broadcastIntent.putExtra(EXTRA_ORIGINAL_URI, uri.toString()); broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); //添加一个2秒的定时器,2秒内Intent没有收到的话,就显示一个进度条 mHandler.sendEmptyMessageDelayed(EVENT_OUTGOING_CALL_TIMEOUT, OUTGOING_CALL_TIMEOUT_THRESHOLD); //发送广播,而且指明了接收者是OutgoingCallReceiver sendOrderedBroadcastAsUser(broadcastIntent, UserHandle.OWNER, PERMISSION, new OutgoingCallReceiver(), null, Activity.RESULT_OK, number, null); }这个过程其实就是对原始的Intent进行解析,对是否紧急呼叫进行不同的处理,对于正常的呼叫,需要重新构建Intent并发送出去。新的Intent构成:
public void onReceive(Context context, Intent intent) { //去掉3妙的定时器 mHandler.removeMessages(EVENT_OUTGOING_CALL_TIMEOUT); doReceive(context, intent); finish(); } public void doReceive(Context context, Intent intent) { //这里的得到的是false alreadyCalled = intent.getBooleanExtra(OutgoingCallBroadcaster.EXTRA_ALREADY_CALLED, false); if (alreadyCalled) { return; } //得到号码 number = getResultData(); final PhoneGlobals app = PhoneGlobals.getInstance(); //OTASP功能,CDMA制式支持 if (TelephonyCapabilities.supportsOtasp(app.phone)) { } //得到号码的Uri originalUri = intent.getStringExtra( OutgoingCallBroadcaster.EXTRA_ORIGINAL_URI); Uri uri = Uri.parse(originalUri); //把字母转换为数字,比如:a-->2;d-->3;g-->4等 number = PhoneNumberUtils.convertKeypadLettersToDigits(number); //把所有字符转换为数字 number = PhoneNumberUtils.stripSeparators(number); //继续处理 startSipCallOptionHandler(context, intent, uri, number); } private void startSipCallOptionHandler(Context context, Intent intent, Uri uri, String number) { //再次构建Intent Intent newIntent = new Intent(Intent.ACTION_CALL, uri); newIntent.putExtra(EXTRA_ACTUAL_NUMBER_TO_DIAL, number); //把原始的Intent数据拷贝过来 //主要去解析EXTRA_GATEWAY_PROVIDER_PACKAGE和EXTRA_GATEWAY_URI,而这两项均为null PhoneUtils.checkAndCopyPhoneProviderExtras(intent, newIntent); //还有一个Intent Intent selectPhoneIntent = new Intent(ACTION_SIP_SELECT_PHONE, uri); //指明接受者是SipCallOptionHandler selectPhoneIntent.setClass(context, SipCallOptionHandler.class); //把上面的Intent放到EXTRA_NEW_CALL_INTENT中 selectPhoneIntent.putExtra(EXTRA_NEW_CALL_INTENT, newIntent); //用新的task装载 selectPhoneIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //发送,走起 context.startActivity(selectPhoneIntent); }上面的操作又是发起了一个Intent,构成有:
@SipCallOptionHandler.java public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //得到Intent Intent intent = getIntent(); String action = intent.getAction(); //外层的Intent if (!OutgoingCallBroadcaster.ACTION_SIP_SELECT_PHONE.equals(action)) { finish(); return; } //得到拨号的Intent mIntent = (Intent) intent.getParcelableExtra(OutgoingCallBroadcaster.EXTRA_NEW_CALL_INTENT); if (mIntent == null) { finish(); return; } //是否支持互联网通话 boolean voipSupported = PhoneUtils.isVoipSupported(); mSipProfileDb = new SipProfileDb(this); mSipSharedPreferences = new SipSharedPreferences(this); mCallOption = mSipSharedPreferences.getSipCallOption(); Uri uri = mIntent.getData(); String scheme = uri.getScheme(); //得到通话的号码 mNumber = PhoneNumberUtils.getNumberFromIntent(mIntent, this); //是否有网络 boolean isInCellNetwork = PhoneGlobals.getInstance().phoneMgr.isRadioOn(); //是否是tel:或者sip:的协议 boolean isKnownCallScheme = Constants.SCHEME_TEL.equals(scheme)||Constants.SCHEME_SIP.equals(scheme); boolean isRegularCall = Constants.SCHEME_TEL.equals(scheme) && !PhoneNumberUtils.isUriNumber(mNumber); if (!isKnownCallScheme) { //异常处理,处理非法协议。 setResultAndFinish(); return; } if (!voipSupported) { if (!isRegularCall) { showDialog(DIALOG_NO_VOIP); } else { //当前不是IP通话,因此走这里 setResultAndFinish(); } return; } setResultAndFinish(); }继续看setResultAndFinish
private void setResultAndFinish() { //放在主线程中操作 runOnUiThread(new Runnable() { public void run() { if (mOutgoingSipProfile != null) { //互联网通话 if (!isNetworkConnected()) { showDialog(DIALOG_NO_INTERNET_ERROR); return; } createSipPhoneIfNeeded(mOutgoingSipProfile); mIntent.putExtra(OutgoingCallBroadcaster.EXTRA_SIP_PHONE_URI, mOutgoingSipProfile.getUriString()); if (mMakePrimary) { mSipSharedPreferences.setPrimaryAccount( mOutgoingSipProfile.getUriString()); } } if (mUseSipPhone && mOutgoingSipProfile == null) { showDialog(DIALOG_START_SIP_SETTINGS); return; } else { //正常拨号 PhoneGlobals.getInstance().callController.placeCall(mIntent); } finish(); } }); }
上面可以看出,在SipCallOptionHandler.java文件中主要针对互联网通话进行处理,注意,这里的互联网通话和IP拨号不同。
@CallController.java public void placeCall(Intent intent) { //拨打 CallStatusCode status = placeCallInternal(intent); //显示InCallScreen mApp.displayCallScreen(!intent.getBooleanExtra(Constants.EXTRA_IS_VIDEO_CALL, false), forPlaceCall); } private CallStatusCode placeCallInternal(Intent intent) { //得到号码 number = PhoneUtils.getInitialNumber(intent); //得到Phone对象 phone = PhoneUtils.pickPhoneBasedOnNumber(mCM, scheme, number, sipPhoneUri); //检查当前状态 okToCallStatus = checkIfOkToInitiateOutgoingCall(phone.getServiceState().getState()); //得到联系人的数据 Uri contactUri = intent.getData(); //拨号 int callStatus = PhoneUtils.placeCall(mApp, phone, number, contactUri, (isEmergencyNumber || isEmergencyIntent), inCallUiState.providerGatewayUri); }上面得到了一个极其重要的变量,Phone变量,我们待会儿详细分析他的来历,这里只需要记住,Phone是通过PhoneUtils.pickPhoneBasedOnNumber()的方式得到的。
@PhoneUtils.java public static int placeCall(Context context, Phone phone, String number, Uri contactRef, boolean isEmergencyCall, Uri gatewayUri) { //得到app final PhoneGlobals app = PhoneGlobals.getInstance(); //号码 numberToDial = number; //拨号 connection = app.mCM.dial(phone, numberToDial); //设置音频模式 setAudioMode(); return status; }上面的dial是通过app.mCM完成的,而这个mCM就是在PhoneGlobals.java中的onCreate时初始化的:
mCM = CallManager.getInstance();
说明dial是通过CallManager去执行dial的:
@CallManager.java public Connection dial(Phone phone, String dialString) throws CallStateException { //得到basePhone Phone basePhone = getPhoneBase(phone); //根据当前的通话状态决定是否可以继续拨号 if (!canDial(phone)) { throw new CallStateException("cannot dial in current state"); } if ( hasActiveFgCall() ) { //已经有电话存在 } //拨号 result = basePhone.dial(dialString); return result; }
代码走到这里,就简化为调用一个Phone对象的dial方法了,此时要想继续往下分析,就必须知道这个Phone对象的来历。下面我们要做两件事:
1、查出Phone对象到底来自于哪里。
2、我们如何通过PhoneUtils.pickPhoneBasedOnNumber()的方式得到了这个Phone对象。
@PhoneGlobals.java public void onCreate() { //创建Phone对象 PhoneFactory.makeDefaultPhones(this); //得到创建的Phone对象 phone = PhoneFactory.getDefaultPhone(); //初始化CallManager并把Phone对象注册给CallManager mCM = CallManager.getInstance(); mCM.registerPhone(phone); //初始化NotificationMgr notificationMgr = NotificationMgr.init(this); phoneMgr = PhoneInterfaceManager.init(this, phone); //开启SIP服务 mHandler.sendEmptyMessage(EVENT_START_SIP_SERVICE); //铃声初始化 ringer = Ringer.init(this); //得到电源管理服务 mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); //距离传感器 if (proximitySensorModeEnabled()) { mAccelerometerListener = new AccelerometerListener(this, this); } //按键管理 mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); //电源管理 mPowerManagerService = IPowerManager.Stub.asInterface(ServiceManager.getService("power")); //又是各种初始化 callController = CallController.init(this); inCallUiState = InCallUiState.init(this); callerInfoCache = CallerInfoCache.init(this); notifier = CallNotifier.init(this, phone, ringer, new CallLogAsync()); //SIM卡状态监听 IccCard sim = phone.getIccCard(); if (sim != null) { sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null); } mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null); PhoneUtils.initializeConnectionHandler(mCM); mTtyEnabled = getResources().getBoolean(R.bool.tty_enabled); //注册一个Filter IntentFilter intentFilter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED); intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); intentFilter.addAction(Intent.ACTION_HEADSET_PLUG); intentFilter.addAction(Intent.ACTION_DOCK_EVENT); intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); intentFilter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); registerReceiver(mReceiver, intentFilter); //注册Filter检测媒体按键的事件 IntentFilter mediaButtonIntentFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON); mediaButtonIntentFilter.setPriority(1); registerReceiver(mMediaButtonReceiver, mediaButtonIntentFilter); //注册Filter检测音频服务 AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); am.registerMediaButtonEventReceiverForCalls(new ComponentName(this.getPackageName(), MediaButtonBroadcastReceiver.class.getName())); PhoneUtils.setAudioMode(mCM); }可以看到,Phone模块在初始化过程就是对CallManager、CallController、NotificationMgr等进行初始化。同时注册各项必须的服务。而关于Phone对象的创建是通过PhoneFactory.makeDefaultPhones(this)实现的。我们继续往下看创建的过程:
@PhoneFactory.java public static void makeDefaultPhones(Context context) { makeDefaultPhone(context); } public static void makeDefaultPhone(Context context) { //打开telephony的Socket new LocalServerSocket("com.android.internal.telephony"); //Phone的通知管理 sPhoneNotifier = new DefaultPhoneNotifier(); //得到RILJ sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); //得到当前的网络类型 int phoneType = TelephonyManager.getPhoneType(networkMode); //根据当前的网络类型创建响应的PhoneProxy if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { //用GSMPhone创建PhoneProxy sProxyPhone = new PhoneProxy(new GSMPhone(context,sCommandsInterface, sPhoneNotifier)); } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { switch (TelephonyManager.getLteOnCdmaModeStatic()) { case PhoneConstants.LTE_ON_CDMA_TRUE: //用CDMALTEPhone创建PhoneProxy sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,sCommandsInterface, sPhoneNotifier)); break; case PhoneConstants.LTE_ON_CDMA_FALSE: default: //用CDMAPhone创建PhoneProxy sProxyPhone = new PhoneProxy(new CDMAPhone(context,sCommandsInterface, sPhoneNotifier)); break; } } }
上面看到,我们创建的Phone对象其实只是一个Phone的代理(PhoneProxy)而已,而创建这个代理对象需要分两步:
1、首先根据当前的网络类型创建不同的PhoneBase对象,也就是GSMPhone/CDMALTEPhone/CDMAPhone等;
2、然后再用这个PhoneBase对象去构建PhoneProxy对象。
那么,PhoneProxy和GSMPhone又是什么东西呢?我们来看看他们的继承关系:public class PhoneProxy extends Handler implements Phone再来看GSMPhone:
public class GSMPhone extends PhoneBase public abstract class PhoneBase extends Handler implements Phone上面的继承关系说明, PhoneProxy和GSMPhone其实都是一个Handler,而且是继承了Phone的接口。这么做的好处是什么呢?
sProxyPhone = new PhoneProxy(new GSMPhone(context,sCommandsInterface, sPhoneNotifier));上面可以看出,创建GSMPhone对象需要用到2个特殊的变量,sCommandsInterface和sPhoneNotifier:
sPhoneNotifier = new DefaultPhoneNotifier(); sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);看来sPhoneNotifier就是DefaultPhoneNotifier对象,而DefaultPhoneNotifier作用就是当相应的Phone有消息从底层上来时,将会通过DefaultPhoneNotifier把消息发送给上层,也就是说,sPhoneNotifier充当了通知的作用。
@GSMPhone.java public GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier) { this(context,ci,notifier, false); } public GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) { //把参数传递给父类,也就是PhoneBase类 super(notifier, context, ci, unitTestMode); //mCM是在父类(PhoneBase)中初始化的 mCM.setPhoneType(PhoneConstants.PHONE_TYPE_GSM); //各种初始化 mCT = new GsmCallTracker(this); mSST = new GsmServiceStateTracker (this); mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor); mDataConnectionTracker = new GsmDataConnectionTracker (this); mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this); mSimSmsIntManager = new SimSmsInterfaceManager(this, mSMS); mSubInfo = new PhoneSubInfo(this); //对mCM进行各种注册 mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); mCM.registerForOn(this, EVENT_RADIO_ON, null); mCM.setOnUSSD(this, EVENT_USSD, null); mCM.setOnSuppServiceNotification(this, EVENT_SSN, null); mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); //设置系统属性,GSMPhone被激活 SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE, new Integer(PhoneConstants.PHONE_TYPE_GSM).toString()); }GSMPhone的初始化过程分为两个重要步骤,第一个步骤是在其父类中完成的,主要是用传递下来的sPhoneNotifier去初始化mNotifier,用传递下来的sCommandsInterface初始化mCM。第二个步骤就是在当前类中完成剩余的mCT、mSST、mSMS、mDataConnectionTracker等重要成员变量的初始化过程。
@PhoneProxy.java public PhoneProxy(PhoneBase phone) { mActivePhone = phone; mResetModemOnRadioTechnologyChange = SystemProperties.getBoolean( TelephonyProperties.PROPERTY_RESET_ON_RADIO_TECH_CHANGE, false); mIccSmsInterfaceManagerProxy = new IccSmsInterfaceManagerProxy( phone.getIccSmsInterfaceManager()); mIccPhoneBookInterfaceManagerProxy = new IccPhoneBookInterfaceManagerProxy( phone.getIccPhoneBookInterfaceManager()); mPhoneSubInfoProxy = new PhoneSubInfoProxy(phone.getPhoneSubInfo()); mCommandsInterface = ((PhoneBase)mActivePhone).mCM; mCommandsInterface.registerForRilConnected(this, EVENT_RIL_CONNECTED, null); mCommandsInterface.registerForOn(this, EVENT_RADIO_ON, null); mCommandsInterface.registerForVoiceRadioTechChanged( this, EVENT_VOICE_RADIO_TECH_CHANGED, null); mIccCardProxy = new IccCardProxy(phone.getContext(), mCommandsInterface); if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) { // For the purpose of IccCardProxy we only care about the technology family mIccCardProxy.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS); } else if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { mIccCardProxy.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT); } }在这个过程中把刚才的GSMPhone注册给了mActivePhone变量,然后又创建了一些代理对象,比如mIccSmsInterfaceManagerProxy、IccPhoneBookInterfaceManagerProxy、mPhoneSubInfoProxy、mIccCardProxy等。
至此,Phone的来历我们就摸清了,用一句话来表述就是,Phone对象就是GSMPhone对象(GSM制式下)。
@PhoneGlobals.java public void onCreate() { //创建Phone对象并获取 PhoneFactory.makeDefaultPhones(this); phone = PhoneFactory.getDefaultPhone(); //初始化CallManager mCM = CallManager.getInstance(); //把Phone注册给CallManager mCM.registerPhone(phone); }我们看到, 得到Phone对象后就把他注册给了CallManager,而所谓的注册其实就是把Phone对象传递给mDefaultPhone,同时把它放在一个叫做mPhones的数组中:
@CallManager.java public boolean registerPhone(Phone phone) { Phone basePhone = getPhoneBase(phone); if (basePhone != null && !mPhones.contains(basePhone)) { if (mPhones.isEmpty()) { //第一次注册时,mPhones列表当然为空 mDefaultPhone = basePhone; } mPhones.add(basePhone); } }这样一来, 我们就可以通过getDefaultPhone的方式从CallManager中得到Phone:
public Phone getDefaultPhone() { return mDefaultPhone; }我们回到上面拨号的过程,上面看到,在拨号的过程中,我们需要Phone时是通过以下方式得到Phone对象的:
phone = PhoneUtils.pickPhoneBasedOnNumber(mCM, scheme, number, sipPhoneUri);我们继续往下看:
@PhoneUtils.java public static Phone pickPhoneBasedOnNumber(CallManager cm, String scheme, String number, String primarySipUri) { return cm.getDefaultPhone(); }这里的cm就是传递下来了CallManager,因此pickPhoneBasedOnNumber的方式其实就是调用了CallManager中的getDefaultPhone方法,这种形式正好符合我们的预期。
由此,我们不仅在3.1节中分析了Phone对象的创建过程,而且也在当前节中分析了得到Phone对象的方法。
@GSMPhone.java public Connection dial(String dialString) throws CallStateException { return dial(dialString, null); }再次调用,此时uusInfo为空。
public Connection dial (String dialString, UUSInfo uusInfo) throws CallStateException { return mCT.dial(newDialString, uusInfo); }我们将上面的代码简化到最关键的一句话,就是调用mCT的dial方法。而这里的mCT就是在GSMPhone的构造函数初始化的GsmCallTracker对象:
mCT = new GsmCallTracker(this);因此我们又要来到GsmCallTracker中:
@GsmCallTracker.java Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException { return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo); }继续调用:
Connection dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException { //构建一个GSM连接 pendingMO = new GsmConnection(phone.getContext(), checkForTestEmergencyNumber(dialString), this, foregroundCall); //拨号 cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage()); //更新Phone状态 updatePhoneState(); //发送状态更新通知 phone.notifyPreciseCallStateChanged(); }在上面这个过程中,调用了cm的dial方法,这里的cm是Phone对象的mCM:
GsmCallTracker (GSMPhone phone) { this.phone = phone; cm = phone.mCM; }而在前面分析过,GSMPhone中的mCM是在其父类PhoneBase中被初始化的:
@PhoneBase.java protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode) { this.mNotifier = notifier; this.mContext = context; mCM = ci; }这里看到,mCM其实就是传递下来的CommandsInterface,在往上追溯的话,其实就是当初创建GSMPhone时传递的RIL对象。因此framework拨号的最后,是走到了RIL.java中,并构建拨号的请求发送给RILC,也就是RIL层:
@RIL.java public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) { //构建RIL层的请求码:RIL_REQUEST_DIAL RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); rr.mp.writeString(address); rr.mp.writeInt(clirMode); if (uusInfo == null) { rr.mp.writeInt(0); // UUS information is absent } else { rr.mp.writeInt(1); // UUS information is present rr.mp.writeInt(uusInfo.getType()); rr.mp.writeInt(uusInfo.getDcs()); rr.mp.writeByteArray(uusInfo.getUserData()); } //发送 send(rr); }发送的过程就是把相应的RILRequest通过mSender发送出去:
private void send(RILRequest rr) { Message msg; if (mSocket == null) { rr.onError(RADIO_NOT_AVAILABLE, null); rr.release(); return; } msg = mSender.obtainMessage(EVENT_SEND, rr); acquireWakeLock(); msg.sendToTarget(); }继续看一下mSender的处理流程:
@Override public void handleMessage(Message msg) { //得到要发送的数据 RILRequest rr = (RILRequest)(msg.obj); switch (msg.what) { case EVENT_SEND: //得到Socket LocalSocket s; s = mSocket; byte[] data; data = rr.mp.marshall(); rr.mp.recycle(); rr.mp = null; dataLength[0] = dataLength[1] = 0; dataLength[2] = (byte)((data.length >> 8) & 0xff); dataLength[3] = (byte)((data.length) & 0xff); //把数据发送给RIL层 s.getOutputStream().write(dataLength); s.getOutputStream().write(data); break; case EVENT_WAKE_LOCK_TIMEOUT: } }
经过以上的过程,就把拨号的请求发送到了RIL层。
现在我们贴出整个拨出号码的流程图: