1.DialpadFragment 的 dialButtonPressed(),用户输入号码(不是紧急号码)后,按下该键,dialButtonPressed 方法被调用。
private Intent newDialNumberIntent(String number) {
final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
Uri.fromParts("tel", number, null));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent;
}
final Intent intent = newDialNumberIntent(number);
if (getActivity() instanceof DialtactsActivity) {
intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN,
DialtactsActivity.CALL_ORIGIN_DIALTACTS);
}
startActivity(intent);
mDigits.getText().clear(); // TODO: Fix bug 1745781
getActivity().finish();
2.跳转到 Phone 应用的 OutgoingCallBroadcaster,onCreate
onCreate 调用 processIntent(intent);
3.processIntent 调用
if (DBG) Log.v(TAG, "Broadcasting intent: " + broadcastIntent + ".");
sendOrderedBroadcast(broadcastIntent, PERMISSION, new OutgoingCallReceiver(),
null, // scheduler
Activity.RESULT_OK, // initialCode
number, // initialData: initial value for the result data
null); // initialExtras
}
4.进入 OutgoingCallBroadcaster的内部Receiver OutgoingCallReceiver,调用 startSipCallOptionHandler(context, intent, uri, number);
private void startSipCallOptionHandler(Context context, Intent intent,
.....
Intent newIntent = new Intent(Intent.ACTION_CALL, uri);
newIntent.putExtra(EXTRA_ACTUAL_NUMBER_TO_DIAL, number);
newIntent.putExtra(SUBSCRIPTION_KEY, mSubscription);
PhoneUtils.checkAndCopyPhoneProviderExtras(intent, newIntent);
// Finally, launch the SipCallOptionHandler, with the copy of the
// original CALL intent stashed away in the EXTRA_NEW_CALL_INTENT
// extra.
Intent selectPhoneIntent = new Intent(ACTION_SIP_SELECT_PHONE, uri);
selectPhoneIntent.setClass(context, SipCallOptionHandler.class);
selectPhoneIntent.putExtra(EXTRA_NEW_CALL_INTENT, newIntent);
selectPhoneIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (DBG) Log.v(TAG, "startSipCallOptionHandler(): " +
"calling startActivity: " + selectPhoneIntent);
context.startActivity(selectPhoneIntent);
// ...and see SipCallOptionHandler.onCreate() for the next step of the sequence.
}
5.进入 SipCallOptionHandler。
6.在SipCallOptionHandler 的 setResultAndFinish()中。
7.调用 PhoneApp.getInstance().callController.placeCall(mIntent);
8.进入 CallControl , CallStatusCode status = placeCallInternal(intent);
9.调用 placeCallInternal,调用
int callStatus = PhoneUtils.placeCall(mApp.mContext,
phone,
number,
contactUri,
(isEmergencyNumber || isEmergencyIntent),
inCallUiState.providerGatewayUri);
10.进入 PhoneUtils的 placeCall
调用 connection = app.mCM.dial(phone, numberToDial);
11.进入 CallManager 的 dial 方法
public Connection dial(Phone phone, String dialString) throws CallStateException {
Phone basePhone = getPhoneBase(phone);
Connection result;
if (VDBG) {
Log.d(LOG_TAG, " dial(" + basePhone + ", "+ dialString + ")");
Log.d(LOG_TAG, this.toString());
}
if ( hasActiveFgCall() ) {
Phone activePhone = getActiveFgCall().getPhone();
boolean hasBgCall = !(activePhone.getBackgroundCall().isIdle());
if (DBG) {
Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == basePhone));
}
if (activePhone != basePhone) {
if (hasBgCall) {
Log.d(LOG_TAG, "Hangup");
getActiveFgCall().hangup();
} else {
Log.d(LOG_TAG, "Switch");
activePhone.switchHoldingAndActive();
}
}
}
result = basePhone.dial(dialString);
if (VDBG) {
Log.d(LOG_TAG, "End dial(" + basePhone + ", "+ dialString + ")");
Log.d(LOG_TAG, this.toString());
}
return result;
}
12.调用 basePhone.dial(dialString)
13.调用 GSMPhone 的 dial
public Connection
dial (String dialString, UUSInfo uusInfo) throws CallStateException {
// Need to make sure dialString gets parsed properly
String newDialString = PhoneNumberUtils.stripSeparators(dialString);
// handle in-call MMI first if applicable
if (handleInCallMmiCommands(newDialString)) {
return null;
}
// Only look at the Network portion for mmi
String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString);
GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this, mUiccApplication);
if (LOCAL_DEBUG) Log.d(LOG_TAG,
"dialing w/ mmi '" + mmi + "'...");
if (mmi == null) {
return mCT.dial(newDialString, uusInfo);
} else if (mmi.isTemporaryModeCLIR()) {
return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode(), uusInfo);
} else if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_MULTIMODE_CDMA, false)
&& mmi.isGlobalDevMmi()) {
return mCT.dial(mmi.dialingNumber, uusInfo);
} else {
mPendingMMIs.add(mmi);
mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
mmi.processCode();
// FIXME should this return null or something else?
return null;
}
}
14.调用 GsmCallTracker 的 dial
Connection
dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException {
.....
cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage());
....
}
15. cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage())m调用 RIL 的 dial
16.封装成RILRequest,交给 rild