CallNotifier构造方法中调用registerForNotifications() 方法,触发PHONE_INCOMING_RING
private void registerForNotifications() {
mCM.registerForIncomingRing(this, PHONE_INCOMING_RING, null);
private CallManager mCM;
调用frameworks\opt\telephony\src\java\com\android\internal\telephony\CallManager
/**
* Notifies when an incoming call rings.<p>
*
* Messages received from this:
* Message.obj will be an AsyncResult
* AsyncResult.userObj = obj
* AsyncResult.result = a Connection. <p>
*/
public void registerForIncomingRing(Handler h, int what, Object obj){
mIncomingRingRegistrants.addUnique(h, what, obj);
}
PHONE_INCOMING_RING调用mRinger.ring()方法
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case PHONE_NEW_RINGING_CONNECTION:
case PHONE_NEW_RINGING_CONNECTION2:
if (DBG) log("RINGING... (new)");
onNewRingingConnection((AsyncResult) msg.obj, msg.what);
mSilentRingerRequested = false;
break;
case PHONE_INCOMING_RING:
case PHONE_INCOMING_RING2:
if (DBG) log("PHONE_INCOMING_RING ! ");
// repeat the ring when requested by the RIL, and when the user has NOT
// specifically requested silence.
if (msg.obj != null && ((AsyncResult) msg.obj).result != null) {
PhoneBase pb = (PhoneBase)((AsyncResult)msg.obj).result;
boolean bSipRing = pb instanceof SipPhone;
boolean bIsRejected = false;
Call ringCall = pb.getRingingCall();
if (null != ringCall) {
bIsRejected = PhoneUtils.getShouldSendToVoiceMailFlag(ringCall.getLatestConnection());
}
if ((pb.getState() == PhoneConstants.State.RINGING)
&& (!mSilentRingerRequested)
&& (!bIsRejected)
&& ok2Ring) {
if (DBG) log("RINGING... (PHONE_INCOMING_RING event)");
boolean provisioned = Settings.Global.getInt(mApplication.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
//For sip call, the ringer will start in onCustomRingQueryComplete
if (provisioned && !bSipRing) {
mRinger.ring();
}
} else {
if (DBG) log("RING before NEW_RING, skipping");
}
}
break;
最终调用com.android.phone.Ringer ring()方法中的makelooper(); r.play();
private void makeLooper() {
if (mRingThread == null) {
mRingThread = new Worker("ringer");
if (mRingThread.getLooper() == null) {
return ;
}
mRingHandler = new Handler(mRingThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
Ringtone r = null;
switch (msg.what) {
case PLAY_RING_ONCE:
if (DBG) log("mRingHandler: PLAY_RING_ONCE...");
if (mRingtone == null && !hasMessages(STOP_RING)) {
// create the ringtone with the uri
if (DBG) log("creating ringtone: " + mCustomRingtoneUri);
r = RingtoneManager.getRingtone(mContext, mCustomRingtoneUri);
synchronized (Ringer.this) {
if (!hasMessages(STOP_RING)) {
mRingtone = r;
}
}
}
r = mRingtone;
if (r != null && !hasMessages(STOP_RING) && !r.isPlaying()) {
if (DBG) {
log("play ringtone... ");
}
PhoneUtils.setAudioMode();
r.play();
synchronized (Ringer.this) {
if (mFirstRingStartTime < 0) {
mFirstRingStartTime = SystemClock.elapsedRealtime();
}
}
}
break;
case STOP_RING:
if (DBG) log("mRingHandler: STOP_RING...");
r = (Ringtone) msg.obj;
if (r != null) {
r.stop();
} else {
if (DBG) log("- STOP_RING with null ringtone! msg = " + msg);
}
getLooper().quit();
break;
}
}
};
}
}