Android4.22来电铃声流程

来源:互联网 发布:java junit单元测试 编辑:程序博客网 时间:2024/04/29 03:57

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;                    }                }            };        }    }



0 0