CallNotifier构造方法中调用registerForNotifications() 方法,触发PHONE_INCOMING_RING
private void registerForNotifications() {
mCM.registerForIncomingRing(this, PHONE_INCOMING_RING, null);private CallManager mCM;
/** * 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; } } }; } }