I've downloaded the entire source code for the master branch from
https://android.googlesource.com/platform/frameworks/base/+/master, and am trying to decipher the chain of events on an incoming call.
I assume that the ACTION_ANSWER intent is started but beyond that don't know what happens before or after.
Can anyone help?
Let's begin by looking at CallNotifier:
/** * Phone app module that listens for phone state changes and
various other * events from the telephony layer, and triggers any
resulting UI behavior * (like starting the Ringer and Incoming Call
UI, playing in-call tones, * updating notifications, writing call log
entries, etc.) */
One of the messages that this Handler responds to is: CallStateMonitor.PHONE_NEW_RINGING_CONNECTION
:
case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:
log("RINGING... (new)");
onNewRingingConnection((AsyncResult) msg.obj);
mSilentRingerRequested = false;
break;
onNewRingingConnection(AsyncResult)
eventually (and, in general case) calls ringAndNotifyOfIncomingCall(Connection c)
:
private void ringAndNotifyOfIncomingCall(Connection c) {
if (PhoneUtils.isRealIncomingCall(c.getState())) {
mRinger.ring();
} else {
if (VDBG) log("- starting call waiting tone...");
if (mCallWaitingTonePlayer == null) {
mCallWaitingTonePlayer = new InCallTonePlayer(
InCallTonePlayer.TONE_CALL_WAITING);
mCallWaitingTonePlayer.start();
}
}
// CallModeler.onNewRingingConnection(Connection)
mCallModeler.onNewRingingConnection(c);
}
CallModeler.onNewRingingConnection(Connection)
(Link) notifies attached listeners:
for (int i = 0; i < mListeners.size(); ++i) {
mListeners.get(i).onIncoming(call);
}
These listeners implement CallModeler.Listener
interface. CallHandlerServiceProxy is one such listener, and its onIncoming(Call)
callback fires CallHandlerServiceProxy.processIncoming(Call)
:
private void processIncoming(Call call) {
....
// ICallHandlerService
mCallHandlerServiceGuarded.onIncoming(call,
RejectWithTextMessageManager.loadCannedResponses());
....
}
CallHandlerService defines a ICallHandlerService.Stub
member and its onIncoming(Call, List<String>)
method looks like:
@Override
public void onIncoming(Call call, List<String> textResponses) {
....
mMainHandler.sendMessage(mMainHandler.obtainMessage(
ON_UPDATE_CALL_WITH_TEXT_RESPONSES, incomingCall));
....
}
This is how mMainHandler
handles case ON_UPDATE_CALL_WITH_TEXT_RESPONSES
:
case ON_UPDATE_CALL_WITH_TEXT_RESPONSES:
AbstractMap.SimpleEntry<Call, List<String>> entry
= (AbstractMap.SimpleEntry<Call, List<String>>) msg.obj;
Log.i(TAG, "ON_INCOMING_CALL: " + entry.getKey());
// CallList
mCallList.onIncoming(entry.getKey(), entry.getValue());
break;
CallList keeps a list of listeners that implement CallList.Listener
, and fires their onIncomingCall(Call)
event from its CallList.onIncoming(Call, List<String>)
method.
Now, let's look at InCallPresenter:
/** * Takes updates from the CallList and notifies the InCallActivity
(UI) * of the changes. * Responsible for starting the activity for a
new call and finishing the activity when all calls * are
disconnected. * Creates and manages the in-call state and provides a
listener pattern for the presenters * that want to listen in on the
in-call state changes. * TODO: This class has become more of a state
machine at this point. Consider renaming. */
InCallPresenter
implements CallList.Listener
interface, and is responsible for launching InCallActivity
that provides the UI for all phone related operations. The following comment (taken from InCallPresenter.startOrFinishUi(InCallState)
) brings the above-mentioned chain of events together:
/* A new Incoming call means that the user needs to be notified of the
the call (since it wasn't them who initiated it). We do this
through full screen notifications and happens indirectly through {@link
StatusBarListener}. The process for incoming calls is as follows:
1) CallList - Announces existence of new INCOMING call
2) InCallPresenter - Gets announcement and calculates that the new
InCallState should be set to INCOMING.
3) InCallPresenter - This method is called to see if we need to
start or finish the app given the new state.
4) StatusBarNotifier - Listens to InCallState changes. InCallPresenter
calls StatusBarNotifier explicitly to issue a
FullScreen Notification that will either start the
InCallActivity or show the user a top-level
notification dialog if the user is in
an immersive app. That notification can also start
the InCallActivity.
5) InCallActivity - Main activity starts up and at the end of its
onCreate will call InCallPresenter::setActivity()
to let the presenter know that start-up is complete.
[ AND NOW YOU'RE IN THE CALL. voila! ] */
I hope this answers your question, or at the very least, shows you where to look. Feel free to correct anything I overlooked/misinterpreted.
have a look at this Grep code InCallScreen.java
else if (action.equals(Intent.ACTION_ANSWER)) {
internalAnswerCall();
app.setRestoreMuteOnInCallResume(false);
return InCallInitStatus.SUCCESS;
Hope below Code Help you.
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch(state){
case TelephonyManager.CALL_STATE_IDLE:
//Not in call: Play music
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//A call is dialing, active or on hold
break;
case TelephonyManager.CALL_STATE_RINGING:
//Incoming call: Pause music
break;
}
}
The google reference is
http://developer.android.com/reference/android/telephony/TelephonyManager.html