summaryrefslogtreecommitdiff
path: root/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
diff options
context:
space:
mode:
Diffstat (limited to 'telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java')
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java230
1 files changed, 127 insertions, 103 deletions
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index d813ecaf9f5b..2485dcb4e5b0 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -37,42 +37,42 @@ import com.android.internal.telephony.*;
* {@hide}
*/
public final class CdmaCallTracker extends CallTracker {
- static final String LOG_TAG = "CDMA";
-
+ static final String LOG_TAG = "CDMA";
+
private static final boolean REPEAT_POLLING = false;
private static final boolean DBG_POLL = false;
//***** Constants
- static final int MAX_CONNECTIONS = 7; // only 7 connections allowed in GSM
- static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call
+ static final int MAX_CONNECTIONS = 1; // only 1 connection allowed in CDMA
+ static final int MAX_CONNECTIONS_PER_CALL = 1; // only 1 connection allowed per call
//***** Instance Variables
-
+
CdmaConnection connections[] = new CdmaConnection[MAX_CONNECTIONS];
RegistrantList voiceCallEndedRegistrants = new RegistrantList();
RegistrantList voiceCallStartedRegistrants = new RegistrantList();
// connections dropped durin last poll
- ArrayList<CdmaConnection> droppedDuringPoll
- = new ArrayList<CdmaConnection>(MAX_CONNECTIONS);
+ ArrayList<CdmaConnection> droppedDuringPoll
+ = new ArrayList<CdmaConnection>(MAX_CONNECTIONS);
- CdmaCall ringingCall = new CdmaCall(this);
+ CdmaCall ringingCall = new CdmaCall(this);
// A call that is ringing or (call) waiting
CdmaCall foregroundCall = new CdmaCall(this);
CdmaCall backgroundCall = new CdmaCall(this);
CdmaConnection pendingMO;
boolean hangupPendingMO;
-
+
CDMAPhone phone;
-
+
boolean desiredMute = false; // false = mute off
Phone.State state = Phone.State.IDLE;
-
+
// boolean needsPoll;
@@ -88,7 +88,34 @@ public final class CdmaCallTracker extends CallTracker {
cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
}
-
+
+ public void dispose() {
+ cm.unregisterForCallStateChanged(this);
+ cm.unregisterForOn(this);
+ cm.unregisterForNotAvailable(this);
+
+ for(CdmaConnection c : connections) {
+ try {
+ if(c != null) hangup(c);
+ } catch (CallStateException ex) {
+ Log.e(LOG_TAG, "unexpected error on hangup during dispose");
+ }
+ }
+
+ try {
+ if(pendingMO != null) hangup(pendingMO);
+ } catch (CallStateException ex) {
+ Log.e(LOG_TAG, "unexpected error on hangup during dispose");
+ }
+
+ clearDisconnected();
+
+ }
+
+ protected void finalize() {
+ Log.d(LOG_TAG, "CdmaCallTracker finalized");
+ }
+
//***** Instance Methods
//***** Public Methods
@@ -96,12 +123,19 @@ public final class CdmaCallTracker extends CallTracker {
Registrant r = new Registrant(h, what, obj);
voiceCallStartedRegistrants.add(r);
}
+ public void unregisterForVoiceCallStarted(Handler h) {
+ voiceCallStartedRegistrants.remove(h);
+ }
public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
voiceCallEndedRegistrants.add(r);
}
+ public void unregisterForVoiceCallEnded(Handler h) {
+ voiceCallEndedRegistrants.remove(h);
+ }
+
private void
fakeHoldForegroundBeforeDial() {
List<Connection> connCopy;
@@ -116,7 +150,7 @@ public final class CdmaCallTracker extends CallTracker {
conn.fakeHoldBeforeDial();
}
}
-
+
/**
* clirMode is one of the CLIR_ constants
*/
@@ -139,13 +173,13 @@ public final class CdmaCallTracker extends CallTracker {
// for the newly dialed connection
switchWaitingOrHoldingAndActive();
- // Fake local state so that
+ // Fake local state so that
// a) foregroundCall is empty for the newly dialed connection
// b) hasNonHangupStateChanged remains false in the
// next poll, so that we don't clear a failed dialing call
fakeHoldForegroundBeforeDial();
- }
-
+ }
+
if (foregroundCall.getState() != CdmaCall.State.IDLE) {
//we should have failed in !canDial() above before we get here
throw new CallStateException("cannot dial in current state");
@@ -161,33 +195,33 @@ public final class CdmaCallTracker extends CallTracker {
pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
// handlePollCalls() will notice this call not present
- // and will mark it as dropped.
+ // and will mark it as dropped.
pollCallsWhenSafe();
} else {
// Always unmute when initiating a new call
setMute(false);
- cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
+ cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
}
updatePhoneState();
phone.notifyCallStateChanged();
-
+
return pendingMO;
}
-
+
Connection
dial (String dialString) throws CallStateException {
return dial(dialString, CommandsInterface.CLIR_DEFAULT);
}
-
+
void
acceptCall () throws CallStateException {
// FIXME if SWITCH fails, should retry with ANSWER
// in case the active/holding call disappeared and this
// is no longer call waiting
-
+
if (ringingCall.getState() == CdmaCall.State.INCOMING) {
Log.i("phone", "acceptCall: incoming...");
// Always unmute when answering a new call
@@ -218,21 +252,21 @@ public final class CdmaCallTracker extends CallTracker {
if (ringingCall.getState() == CdmaCall.State.INCOMING) {
throw new CallStateException("cannot be in the incoming state");
} else {
- cm.switchWaitingOrHoldingAndActive(
- obtainCompleteMessage(EVENT_SWITCH_RESULT));
+ cm.sendCDMAFeatureCode("", obtainCompleteMessage(EVENT_SWITCH_RESULT));
}
}
void
conference() throws CallStateException {
- cm.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT));
+ // three way calls in CDMA will be handled by feature codes
+ Log.e(LOG_TAG, "conference: not possible in CDMA");
}
void
explicitCallTransfer() throws CallStateException {
cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
}
-
+
void
clearDisconnected() {
internalClearDisconnected();
@@ -241,7 +275,7 @@ public final class CdmaCallTracker extends CallTracker {
phone.notifyCallStateChanged();
}
- boolean
+ boolean
canConference() {
return foregroundCall.getState() == CdmaCall.State.ACTIVE
&& backgroundCall.getState() == CdmaCall.State.HOLDING
@@ -265,21 +299,19 @@ public final class CdmaCallTracker extends CallTracker {
boolean
canTransfer() {
- return foregroundCall.getState() == CdmaCall.State.ACTIVE
- && backgroundCall.getState() == CdmaCall.State.HOLDING;
+ Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
+ return false;
}
-
+
//***** Private Instance Methods
-
+
private void
internalClearDisconnected() {
ringingCall.clearDisconnected();
foregroundCall.clearDisconnected();
- backgroundCall.clearDisconnected();
+ backgroundCall.clearDisconnected();
}
-
-
-
+
/**
* Obtain a message to use for signalling "invoke getCurrentCalls() when
* this operation and all other pending operations are complete
@@ -288,7 +320,7 @@ public final class CdmaCallTracker extends CallTracker {
obtainCompleteMessage() {
return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
}
-
+
/**
* Obtain a message to use for signalling "invoke getCurrentCalls() when
* this operation and all other pending operations are complete
@@ -308,26 +340,26 @@ public final class CdmaCallTracker extends CallTracker {
private void
operationComplete() {
pendingOperations--;
-
+
if (DBG_POLL) log("operationComplete: pendingOperations=" +
pendingOperations + ", needsPoll=" + needsPoll);
if (pendingOperations == 0 && needsPoll) {
lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
- cm.getCurrentCalls(lastRelevantPoll);
+ cm.getCurrentCalls(lastRelevantPoll);
} else if (pendingOperations < 0) {
// this should never happen
Log.e(LOG_TAG,"CdmaCallTracker.pendingOperations < 0");
pendingOperations = 0;
}
}
-
+
private void
updatePhoneState() {
Phone.State oldState = state;
-
+
if (ringingCall.isRinging()) {
state = Phone.State.RINGING;
} else if (pendingMO != null ||
@@ -335,7 +367,7 @@ public final class CdmaCallTracker extends CallTracker {
state = Phone.State.OFFHOOK;
} else {
state = Phone.State.IDLE;
- }
+ }
if (state == Phone.State.IDLE && oldState != state) {
voiceCallEndedRegistrants.notifyRegistrants(
@@ -349,13 +381,13 @@ public final class CdmaCallTracker extends CallTracker {
phone.notifyPhoneStateChanged();
}
}
-
+
// ***** Overwritten from CallTracker
-
+
protected void
handlePollCalls(AsyncResult ar) {
List polledCalls;
-
+
if (ar.exception == null) {
polledCalls = (List)ar.result;
} else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
@@ -375,7 +407,7 @@ public final class CdmaCallTracker extends CallTracker {
boolean needsPollDelay = false;
boolean unknownConnectionAppeared = false;
- for (int i = 0, curDC = 0, dcSize = polledCalls.size()
+ for (int i = 0, curDC = 0, dcSize = polledCalls.size()
; i < connections.length; i++) {
CdmaConnection conn = connections[i];
DriverCall dc = null;
@@ -432,7 +464,7 @@ public final class CdmaCallTracker extends CallTracker {
// which is neither a ringing call or one we created.
// Either we've crashed and re-attached to an existing
// call, or something else (eg, SIM) initiated the call.
-
+
Log.i(LOG_TAG,"Phantom call appeared " + dc);
// If it's a connected call, set the connect time so that
@@ -449,8 +481,8 @@ public final class CdmaCallTracker extends CallTracker {
hasNonHangupStateChanged = true;
} else if (conn != null && dc == null) {
// Connection missing in CLCC response that we were
- // tracking.
- droppedDuringPoll.add(conn);
+ // tracking.
+ droppedDuringPoll.add(conn);
// Dropped connections are removed from the CallTracker
// list but kept in the Call list
connections[i] = null;
@@ -458,7 +490,7 @@ public final class CdmaCallTracker extends CallTracker {
// Connection in CLCC response does not match what
// we were tracking. Assume dropped call and new call
- droppedDuringPoll.add(conn);
+ droppedDuringPoll.add(conn);
connections[i] = new CdmaConnection (dc, this, i);
if (connections[i].getCall() == ringingCall) {
@@ -494,11 +526,11 @@ public final class CdmaCallTracker extends CallTracker {
// This is the first poll after an ATD.
// We expect the pending call to appear in the list
// If it does not, we land here
- if (pendingMO != null) {
- Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
+ if (pendingMO != null) {
+ Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
+ foregroundCall.getState());
- droppedDuringPoll.add(pendingMO);
+ droppedDuringPoll.add(pendingMO);
pendingMO = null;
hangupPendingMO = false;
}
@@ -519,7 +551,7 @@ public final class CdmaCallTracker extends CallTracker {
if (conn.cause == Connection.DisconnectCause.LOCAL) {
cause = Connection.DisconnectCause.INCOMING_REJECTED;
} else {
- cause = Connection.DisconnectCause.INCOMING_MISSED;
+ cause = Connection.DisconnectCause.INCOMING_MISSED;
}
if (Phone.DEBUG_PHONE) {
@@ -532,8 +564,7 @@ public final class CdmaCallTracker extends CallTracker {
// Local hangup
droppedDuringPoll.remove(i);
conn.onDisconnect(Connection.DisconnectCause.LOCAL);
- } else if (conn.cause ==
- Connection.DisconnectCause.INVALID_NUMBER) {
+ } else if (conn.cause == Connection.DisconnectCause.INVALID_NUMBER) {
droppedDuringPoll.remove(i);
conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER);
}
@@ -575,7 +606,7 @@ public final class CdmaCallTracker extends CallTracker {
/*package*/ void
hangup (CdmaConnection conn) throws CallStateException {
if (conn.owner != this) {
- throw new CallStateException ("CdmaConnection " + conn
+ throw new CallStateException ("CdmaConnection " + conn
+ "does not belong to CdmaCallTracker " + this);
}
@@ -584,14 +615,14 @@ public final class CdmaCallTracker extends CallTracker {
// GSM index assigned yet
if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
- hangupPendingMO = true;
+ hangupPendingMO = true;
} else {
- try {
- cm.hangupConnection (conn.getGSMIndex(), obtainCompleteMessage());
+ try {
+ cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
} catch (CallStateException ex) {
// Ignore "connection not found"
// Call may have hung up already
- Log.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
+ Log.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
+ conn);
}
}
@@ -602,20 +633,20 @@ public final class CdmaCallTracker extends CallTracker {
/*package*/ void
separate (CdmaConnection conn) throws CallStateException {
if (conn.owner != this) {
- throw new CallStateException ("CdmaConnection " + conn
+ throw new CallStateException ("CdmaConnection " + conn
+ "does not belong to CdmaCallTracker " + this);
}
try {
- cm.separateConnection (conn.getGSMIndex(),
+ cm.separateConnection (conn.getCDMAIndex(),
obtainCompleteMessage(EVENT_SEPARATE_RESULT));
} catch (CallStateException ex) {
// Ignore "connection not found"
// Call may have hung up already
- Log.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
+ Log.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
+ conn);
}
- }
-
+ }
+
//***** Called from CDMAPhone
/*package*/ void
@@ -623,13 +654,13 @@ public final class CdmaCallTracker extends CallTracker {
desiredMute = mute;
cm.setMute(desiredMute, null);
}
-
+
/*package*/ boolean
getMute() {
return desiredMute;
- }
+ }
+
-
//***** Called from CdmaCall
/* package */ void
@@ -684,7 +715,7 @@ public final class CdmaCallTracker extends CallTracker {
int count = call.connections.size();
for (int i = 0; i < count; i++) {
CdmaConnection cn = (CdmaConnection)call.connections.get(i);
- if (cn.getGSMIndex() == index) {
+ if (cn.getCDMAIndex() == index) {
cm.hangupConnection(index, obtainCompleteMessage());
return;
}
@@ -698,27 +729,27 @@ public final class CdmaCallTracker extends CallTracker {
int count = call.connections.size();
for (int i = 0; i < count; i++) {
CdmaConnection cn = (CdmaConnection)call.connections.get(i);
- cm.hangupConnection(cn.getGSMIndex(), obtainCompleteMessage());
+ cm.hangupConnection(cn.getCDMAIndex(), obtainCompleteMessage());
}
} catch (CallStateException ex) {
Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
}
}
-
+
/* package */
CdmaConnection getConnectionByIndex(CdmaCall call, int index)
throws CallStateException {
int count = call.connections.size();
for (int i = 0; i < count; i++) {
CdmaConnection cn = (CdmaConnection)call.connections.get(i);
- if (cn.getGSMIndex() == index) {
+ if (cn.getCDMAIndex() == index) {
return cn;
}
}
return null;
}
-
+
private Phone.SuppService getFailedService(int what) {
switch (what) {
case EVENT_SWITCH_RESULT:
@@ -733,16 +764,22 @@ public final class CdmaCallTracker extends CallTracker {
return Phone.SuppService.UNKNOWN;
}
+ private void handleRadioNotAvailable() {
+ // handlePollCalls will clear out its
+ // call list when it gets the CommandException
+ // error result from this
+ pollCallsWhenSafe();
+ }
+
//****** Overridden from Handler
- public void
+ public void
handleMessage (Message msg) {
AsyncResult ar;
-
+
switch (msg.what) {
case EVENT_POLL_CALLS_RESULT:{
- //TODO Remove
- Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
+ Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
ar = (AsyncResult)msg.obj;
if(msg == lastRelevantPoll) {
@@ -759,25 +796,17 @@ public final class CdmaCallTracker extends CallTracker {
ar = (AsyncResult)msg.obj;
operationComplete();
break;
-
-// TODO
+
case EVENT_SWITCH_RESULT:
-// case EVENT_CONFERENCE_RESULT:
-// case EVENT_SEPARATE_RESULT:
-// case EVENT_ECT_RESULT:
- ar = (AsyncResult)msg.obj;
- if (ar.exception != null) {
- // TODO: will be handles by InCall Supp. Service use case
- //phone.notifySuppServiceFailed(getFailedService(msg.what));
- }
- operationComplete();
+ ar = (AsyncResult)msg.obj;
+ operationComplete();
break;
case EVENT_GET_LAST_CALL_FAIL_CAUSE:
int causeCode;
ar = (AsyncResult)msg.obj;
- operationComplete();
+ operationComplete();
if (ar.exception != null) {
// An exception occurred...just treat the disconnect
@@ -788,7 +817,7 @@ public final class CdmaCallTracker extends CallTracker {
} else {
causeCode = ((int[])ar.result)[0];
}
-
+
for (int i = 0, s = droppedDuringPoll.size()
; i < s ; i++
) {
@@ -802,31 +831,26 @@ public final class CdmaCallTracker extends CallTracker {
phone.notifyCallStateChanged();
droppedDuringPoll.clear();
break;
-
-// TODO: check if needed
-// case EVENT_REPOLL_AFTER_DELAY:
+
case EVENT_CALL_STATE_CHANGE:
- Log.d(LOG_TAG, "Event EVENT_CALL_STATE_CHANGE Received"); //TODO Remove
pollCallsWhenSafe();
break;
- case EVENT_RADIO_AVAILABLE:{
- Log.d(LOG_TAG, "Event EVENT_RADIO_AVAILABLE Received"); //TODO Remove
+ case EVENT_RADIO_AVAILABLE:
handleRadioAvailable();
- }
break;
-
+
case EVENT_RADIO_NOT_AVAILABLE:
- Log.d(LOG_TAG, "Event EVENT_RADIO_NOT_AVAILABLE Received"); //TODO Remove
- //handleRadioNotAvailable(); //TODO
+ handleRadioNotAvailable();
break;
+
default:{
- throw new RuntimeException("unexpected event not handled");
+ throw new RuntimeException("unexpected event not handled");
}
}
}
-
- private void log(String msg) {
+
+ protected void log(String msg) {
Log.d(LOG_TAG, "[CdmaCallTracker] " + msg);
}