Loading src/java/com/android/internal/telephony/gsm/GsmCallTracker.java +91 −13 Original line number Original line Diff line number Diff line Loading @@ -192,6 +192,9 @@ public final class GsmCallTracker extends CallTracker { // note that this triggers call state changed notif // note that this triggers call state changed notif clearDisconnected(); clearDisconnected(); // flag used to determine if mCi.dial needs to be sent now or later boolean isDialRequestPending = false; if (!canDial()) { if (!canDial()) { throw new CallStateException("cannot dial in current state"); throw new CallStateException("cannot dial in current state"); } } Loading @@ -204,13 +207,14 @@ public final class GsmCallTracker extends CallTracker { // but the dial might fail before this happens // but the dial might fail before this happens // and we need to make sure the foreground call is clear // and we need to make sure the foreground call is clear // for the newly dialed connection // for the newly dialed connection switchWaitingOrHoldingAndActive(); switchWaitingOrHoldingAndActive(clirMode); // Fake local state so that // Fake local state so that // a) foregroundCall is empty for the newly dialed connection // a) foregroundCall is empty for the newly dialed connection // b) hasNonHangupStateChanged remains false in the // b) hasNonHangupStateChanged remains false in the // next poll, so that we don't clear a failed dialing call // next poll, so that we don't clear a failed dialing call fakeHoldForegroundBeforeDial(); fakeHoldForegroundBeforeDial(); isDialRequestPending = true; } } if (mForegroundCall.getState() != GsmCall.State.IDLE) { if (mForegroundCall.getState() != GsmCall.State.IDLE) { Loading @@ -232,11 +236,16 @@ public final class GsmCallTracker extends CallTracker { // and will mark it as dropped. // and will mark it as dropped. pollCallsWhenSafe(); pollCallsWhenSafe(); } else { } else { // if isDialRequestPending is true, we would postpone the dial // request for the second call till we get the hold confirmation // for the first call. if (!isDialRequestPending) { // Always unmute when initiating a new call // Always unmute when initiating a new call setMute(false); setMute(false); mCi.dial(mPendingMO.mAddress, clirMode, uusInfo, obtainCompleteMessage()); mCi.dial(mPendingMO.mAddress, clirMode, uusInfo, obtainCompleteMessage()); } } } updatePhoneState(); updatePhoneState(); mPhone.notifyPreciseCallStateChanged(); mPhone.notifyPreciseCallStateChanged(); Loading @@ -259,6 +268,26 @@ public final class GsmCallTracker extends CallTracker { return dial(dialString, clirMode, null); return dial(dialString, clirMode, null); } } void dialPendingCall(int clirMode) { if (mPendingMO.mAddress == null || mPendingMO.mAddress.length() == 0 || mPendingMO.mAddress.indexOf(PhoneNumberUtils.WILD) >= 0) { // Phone number is invalid mPendingMO.mCause = Connection.DisconnectCause.INVALID_NUMBER; // handlePollCalls() will notice this call not present // and will mark it as dropped. pollCallsWhenSafe(); } else { // Always unmute when initiating a new call setMute(false); mCi.dial(mPendingMO.mAddress, clirMode, obtainCompleteMessage()); } updatePhoneState(); mPhone.notifyPreciseCallStateChanged(); } void void acceptCall () throws CallStateException { acceptCall () throws CallStateException { // FIXME if SWITCH fails, should retry with ANSWER // FIXME if SWITCH fails, should retry with ANSWER Loading Loading @@ -308,6 +337,19 @@ public final class GsmCallTracker extends CallTracker { mCi.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT)); mCi.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT)); } } void switchWaitingOrHoldingAndActive(int clirMode) throws CallStateException { if (mRingingCall.getState() == GsmCall.State.INCOMING) { throw new CallStateException("cannot be in the incoming state"); } else if (callSwitchPending == false) { mCi.switchWaitingOrHoldingAndActive( obtainCompleteMessage(EVENT_SWITCH_RESULT, clirMode)); callSwitchPending = true; } else { Rlog.w(LOG_TAG, "Call Switch request ignored due to pending response"); } } void void explicitCallTransfer() { explicitCallTransfer() { mCi.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT)); mCi.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT)); Loading Loading @@ -382,18 +424,36 @@ public final class GsmCallTracker extends CallTracker { mLastRelevantPoll = null; mLastRelevantPoll = null; mNeedsPoll = true; mNeedsPoll = true; if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" + if (DBG_POLL) { mPendingOperations + ", needsPoll=" + mNeedsPoll); log("obtainCompleteMessage: pendingOperations=" + mPendingOperations + ", needsPoll=" + mNeedsPoll); } return obtainMessage(what); return obtainMessage(what); } } private Message obtainCompleteMessage(int what, int clirMode) { mPendingOperations++; mLastRelevantPoll = null; mNeedsPoll = true; if (DBG_POLL) { log("obtainCompleteMessage: pendingOperations=" + mPendingOperations + ", needsPoll=" + mNeedsPoll); } return obtainMessage(what, clirMode); } private void private void operationComplete() { operationComplete() { mPendingOperations--; mPendingOperations--; if (DBG_POLL) log("operationComplete: pendingOperations=" + if (DBG_POLL) { mPendingOperations + ", needsPoll=" + mNeedsPoll); log("operationComplete: pendingOperations=" + mPendingOperations + ", needsPoll=" + mNeedsPoll); } if (mPendingOperations == 0 && mNeedsPoll) { if (mPendingOperations == 0 && mNeedsPoll) { mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); Loading Loading @@ -472,8 +532,9 @@ public final class GsmCallTracker extends CallTracker { } } } } if (DBG_POLL) log("poll: conn[i=" + i + "]=" + if (DBG_POLL) { conn+", dc=" + dc); log("poll: conn[i=" + i + "]=" + conn+", dc=" + dc); } if (conn == null && dc != null) { if (conn == null && dc != null) { // Connection appeared in CLCC response that we don't know about // Connection appeared in CLCC response that we don't know about Loading Loading @@ -870,8 +931,9 @@ public final class GsmCallTracker extends CallTracker { ar = (AsyncResult)msg.obj; ar = (AsyncResult)msg.obj; if (msg == mLastRelevantPoll) { if (msg == mLastRelevantPoll) { if (DBG_POLL) log( if (DBG_POLL) { "handle EVENT_POLL_CALL_RESULT: set needsPoll=F"); log("handle EVENT_POLL_CALL_RESULT: set needsPoll=F"); } mNeedsPoll = false; mNeedsPoll = false; mLastRelevantPoll = null; mLastRelevantPoll = null; handlePollCalls((AsyncResult)msg.obj); handlePollCalls((AsyncResult)msg.obj); Loading @@ -883,8 +945,24 @@ public final class GsmCallTracker extends CallTracker { operationComplete(); operationComplete(); break; break; // This event will also be called when the call is placed // on hold while there is another dialed call. If Hold succeeds, // dialPendingCall would be invoked.Else getCurrentCalls is anyways // invoked through operationComplete,which will get the new // call states depending on which UI would be updated. case EVENT_SWITCH_RESULT: case EVENT_SWITCH_RESULT: callSwitchPending = false; callSwitchPending = false; ar = (AsyncResult)msg.obj; if (ar.exception != null) { mPhone.notifySuppServiceFailed(getFailedService(msg.what)); } else { if (ar.userObj != null) { dialPendingCall((Integer) ar.userObj); } } operationComplete(); break; case EVENT_CONFERENCE_RESULT: case EVENT_CONFERENCE_RESULT: case EVENT_SEPARATE_RESULT: case EVENT_SEPARATE_RESULT: case EVENT_ECT_RESULT: case EVENT_ECT_RESULT: Loading Loading
src/java/com/android/internal/telephony/gsm/GsmCallTracker.java +91 −13 Original line number Original line Diff line number Diff line Loading @@ -192,6 +192,9 @@ public final class GsmCallTracker extends CallTracker { // note that this triggers call state changed notif // note that this triggers call state changed notif clearDisconnected(); clearDisconnected(); // flag used to determine if mCi.dial needs to be sent now or later boolean isDialRequestPending = false; if (!canDial()) { if (!canDial()) { throw new CallStateException("cannot dial in current state"); throw new CallStateException("cannot dial in current state"); } } Loading @@ -204,13 +207,14 @@ public final class GsmCallTracker extends CallTracker { // but the dial might fail before this happens // but the dial might fail before this happens // and we need to make sure the foreground call is clear // and we need to make sure the foreground call is clear // for the newly dialed connection // for the newly dialed connection switchWaitingOrHoldingAndActive(); switchWaitingOrHoldingAndActive(clirMode); // Fake local state so that // Fake local state so that // a) foregroundCall is empty for the newly dialed connection // a) foregroundCall is empty for the newly dialed connection // b) hasNonHangupStateChanged remains false in the // b) hasNonHangupStateChanged remains false in the // next poll, so that we don't clear a failed dialing call // next poll, so that we don't clear a failed dialing call fakeHoldForegroundBeforeDial(); fakeHoldForegroundBeforeDial(); isDialRequestPending = true; } } if (mForegroundCall.getState() != GsmCall.State.IDLE) { if (mForegroundCall.getState() != GsmCall.State.IDLE) { Loading @@ -232,11 +236,16 @@ public final class GsmCallTracker extends CallTracker { // and will mark it as dropped. // and will mark it as dropped. pollCallsWhenSafe(); pollCallsWhenSafe(); } else { } else { // if isDialRequestPending is true, we would postpone the dial // request for the second call till we get the hold confirmation // for the first call. if (!isDialRequestPending) { // Always unmute when initiating a new call // Always unmute when initiating a new call setMute(false); setMute(false); mCi.dial(mPendingMO.mAddress, clirMode, uusInfo, obtainCompleteMessage()); mCi.dial(mPendingMO.mAddress, clirMode, uusInfo, obtainCompleteMessage()); } } } updatePhoneState(); updatePhoneState(); mPhone.notifyPreciseCallStateChanged(); mPhone.notifyPreciseCallStateChanged(); Loading @@ -259,6 +268,26 @@ public final class GsmCallTracker extends CallTracker { return dial(dialString, clirMode, null); return dial(dialString, clirMode, null); } } void dialPendingCall(int clirMode) { if (mPendingMO.mAddress == null || mPendingMO.mAddress.length() == 0 || mPendingMO.mAddress.indexOf(PhoneNumberUtils.WILD) >= 0) { // Phone number is invalid mPendingMO.mCause = Connection.DisconnectCause.INVALID_NUMBER; // handlePollCalls() will notice this call not present // and will mark it as dropped. pollCallsWhenSafe(); } else { // Always unmute when initiating a new call setMute(false); mCi.dial(mPendingMO.mAddress, clirMode, obtainCompleteMessage()); } updatePhoneState(); mPhone.notifyPreciseCallStateChanged(); } void void acceptCall () throws CallStateException { acceptCall () throws CallStateException { // FIXME if SWITCH fails, should retry with ANSWER // FIXME if SWITCH fails, should retry with ANSWER Loading Loading @@ -308,6 +337,19 @@ public final class GsmCallTracker extends CallTracker { mCi.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT)); mCi.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT)); } } void switchWaitingOrHoldingAndActive(int clirMode) throws CallStateException { if (mRingingCall.getState() == GsmCall.State.INCOMING) { throw new CallStateException("cannot be in the incoming state"); } else if (callSwitchPending == false) { mCi.switchWaitingOrHoldingAndActive( obtainCompleteMessage(EVENT_SWITCH_RESULT, clirMode)); callSwitchPending = true; } else { Rlog.w(LOG_TAG, "Call Switch request ignored due to pending response"); } } void void explicitCallTransfer() { explicitCallTransfer() { mCi.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT)); mCi.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT)); Loading Loading @@ -382,18 +424,36 @@ public final class GsmCallTracker extends CallTracker { mLastRelevantPoll = null; mLastRelevantPoll = null; mNeedsPoll = true; mNeedsPoll = true; if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" + if (DBG_POLL) { mPendingOperations + ", needsPoll=" + mNeedsPoll); log("obtainCompleteMessage: pendingOperations=" + mPendingOperations + ", needsPoll=" + mNeedsPoll); } return obtainMessage(what); return obtainMessage(what); } } private Message obtainCompleteMessage(int what, int clirMode) { mPendingOperations++; mLastRelevantPoll = null; mNeedsPoll = true; if (DBG_POLL) { log("obtainCompleteMessage: pendingOperations=" + mPendingOperations + ", needsPoll=" + mNeedsPoll); } return obtainMessage(what, clirMode); } private void private void operationComplete() { operationComplete() { mPendingOperations--; mPendingOperations--; if (DBG_POLL) log("operationComplete: pendingOperations=" + if (DBG_POLL) { mPendingOperations + ", needsPoll=" + mNeedsPoll); log("operationComplete: pendingOperations=" + mPendingOperations + ", needsPoll=" + mNeedsPoll); } if (mPendingOperations == 0 && mNeedsPoll) { if (mPendingOperations == 0 && mNeedsPoll) { mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); Loading Loading @@ -472,8 +532,9 @@ public final class GsmCallTracker extends CallTracker { } } } } if (DBG_POLL) log("poll: conn[i=" + i + "]=" + if (DBG_POLL) { conn+", dc=" + dc); log("poll: conn[i=" + i + "]=" + conn+", dc=" + dc); } if (conn == null && dc != null) { if (conn == null && dc != null) { // Connection appeared in CLCC response that we don't know about // Connection appeared in CLCC response that we don't know about Loading Loading @@ -870,8 +931,9 @@ public final class GsmCallTracker extends CallTracker { ar = (AsyncResult)msg.obj; ar = (AsyncResult)msg.obj; if (msg == mLastRelevantPoll) { if (msg == mLastRelevantPoll) { if (DBG_POLL) log( if (DBG_POLL) { "handle EVENT_POLL_CALL_RESULT: set needsPoll=F"); log("handle EVENT_POLL_CALL_RESULT: set needsPoll=F"); } mNeedsPoll = false; mNeedsPoll = false; mLastRelevantPoll = null; mLastRelevantPoll = null; handlePollCalls((AsyncResult)msg.obj); handlePollCalls((AsyncResult)msg.obj); Loading @@ -883,8 +945,24 @@ public final class GsmCallTracker extends CallTracker { operationComplete(); operationComplete(); break; break; // This event will also be called when the call is placed // on hold while there is another dialed call. If Hold succeeds, // dialPendingCall would be invoked.Else getCurrentCalls is anyways // invoked through operationComplete,which will get the new // call states depending on which UI would be updated. case EVENT_SWITCH_RESULT: case EVENT_SWITCH_RESULT: callSwitchPending = false; callSwitchPending = false; ar = (AsyncResult)msg.obj; if (ar.exception != null) { mPhone.notifySuppServiceFailed(getFailedService(msg.what)); } else { if (ar.userObj != null) { dialPendingCall((Integer) ar.userObj); } } operationComplete(); break; case EVENT_CONFERENCE_RESULT: case EVENT_CONFERENCE_RESULT: case EVENT_SEPARATE_RESULT: case EVENT_SEPARATE_RESULT: case EVENT_ECT_RESULT: case EVENT_ECT_RESULT: Loading