diff options
author | Hung-ying Tyan <tyanh@google.com> | 2010-08-18 14:37:59 +0800 |
---|---|---|
committer | Hung-ying Tyan <tyanh@google.com> | 2010-08-24 17:54:47 +0800 |
commit | 3294d44b96f63f647fba3a03604eb028e28a42bc (patch) | |
tree | f6e4ed0b30c0edb0e681f39eef43292da250148a /telephony | |
parent | a83987d2ccc6b235dd3dd5cc6206c257dfe9e0a8 (diff) | |
download | frameworks_base-3294d44b96f63f647fba3a03604eb028e28a42bc.zip frameworks_base-3294d44b96f63f647fba3a03604eb028e28a42bc.tar.gz frameworks_base-3294d44b96f63f647fba3a03604eb028e28a42bc.tar.bz2 |
Add confcall management to SIP calls
and fix the bug of re-assigning connectTime's in SipConnection,
and adding synchronization for SipPhone to be thread-safe,
and set normal audio mode when call not on hold instead of on hold in SipAudioCallImpl,
and fix re-entrance problem in CallManager.setAudioMode() for in-call mode.
Change-Id: I54f39dab052062de1ce141e5358d892d30453a3a
Diffstat (limited to 'telephony')
4 files changed, 97 insertions, 76 deletions
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java index 8e08592..980affa 100644 --- a/telephony/java/com/android/internal/telephony/CallManager.java +++ b/telephony/java/com/android/internal/telephony/CallManager.java @@ -322,7 +322,9 @@ public final class CallManager { } break; } - audioManager.setMode(mode); + // calling audioManager.setMode() multiple times in a short period of + // time seems to break the audio recorder in in-call mode + if (audioManager.getMode() != mode) audioManager.setMode(mode); } private Context getContext() { diff --git a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java index d48f94a..6c989b4 100644 --- a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java +++ b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java @@ -85,8 +85,10 @@ abstract class SipConnectionBase extends Connection { protected void setState(Call.State state) { switch (state) { case ACTIVE: - connectTimeReal = SystemClock.elapsedRealtime(); - connectTime = System.currentTimeMillis(); + if (connectTime == 0) { + connectTimeReal = SystemClock.elapsedRealtime(); + connectTime = System.currentTimeMillis(); + } break; case DISCONNECTED: duration = SystemClock.elapsedRealtime() - connectTimeReal; diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java index a052db0..1325dd3 100755 --- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java +++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java @@ -100,7 +100,7 @@ public class SipPhone extends SipPhoneBase { } public String getPhoneName() { - return mProfile.getProfileName(); + return "SIP:" + getUriString(mProfile); } public String getSipUri() { @@ -222,21 +222,25 @@ public class SipPhone extends SipPhoneBase { } public void conference() throws CallStateException { - if ((foregroundCall.getState() != SipCall.State.ACTIVE) - || (foregroundCall.getState() != SipCall.State.ACTIVE)) { - throw new CallStateException("wrong state to merge calls: fg=" - + foregroundCall.getState() + ", bg=" - + backgroundCall.getState()); + synchronized (SipPhone.class) { + if ((foregroundCall.getState() != SipCall.State.ACTIVE) + || (foregroundCall.getState() != SipCall.State.ACTIVE)) { + throw new CallStateException("wrong state to merge calls: fg=" + + foregroundCall.getState() + ", bg=" + + backgroundCall.getState()); + } + foregroundCall.merge(backgroundCall); } - foregroundCall.merge(backgroundCall); } public void conference(Call that) throws CallStateException { - if (!(that instanceof SipCall)) { - throw new CallStateException("expect " + SipCall.class - + ", cannot merge with " + that.getClass()); + synchronized (SipPhone.class) { + if (!(that instanceof SipCall)) { + throw new CallStateException("expect " + SipCall.class + + ", cannot merge with " + that.getClass()); + } + foregroundCall.merge((SipCall) that); } - foregroundCall.merge((SipCall) that); } public boolean canTransfer() { @@ -248,12 +252,14 @@ public class SipPhone extends SipPhoneBase { } public void clearDisconnected() { - ringingCall.clearDisconnected(); - foregroundCall.clearDisconnected(); - backgroundCall.clearDisconnected(); + synchronized (SipPhone.class) { + ringingCall.clearDisconnected(); + foregroundCall.clearDisconnected(); + backgroundCall.clearDisconnected(); - updatePhoneState(); - notifyPreciseCallStateChanged(); + updatePhoneState(); + notifyPreciseCallStateChanged(); + } } public void sendDtmf(char c) { @@ -261,7 +267,9 @@ public class SipPhone extends SipPhoneBase { Log.e(LOG_TAG, "sendDtmf called with invalid character '" + c + "'"); } else if (foregroundCall.getState().isAlive()) { - foregroundCall.sendDtmf(c); + synchronized (SipPhone.class) { + foregroundCall.sendDtmf(c); + } } } @@ -307,7 +315,9 @@ public class SipPhone extends SipPhoneBase { } public void setMute(boolean muted) { - foregroundCall.setMute(muted); + synchronized (SipPhone.class) { + foregroundCall.setMute(muted); + } } public boolean getMute() { @@ -410,18 +420,20 @@ public class SipPhone extends SipPhoneBase { @Override public void hangup() throws CallStateException { - Log.v(LOG_TAG, "hang up call: " + getState() + ": " + this - + " on phone " + getPhone()); - CallStateException excp = null; - for (Connection c : connections) { - try { - c.hangup(); - } catch (CallStateException e) { - excp = e; + synchronized (SipPhone.class) { + Log.v(LOG_TAG, "hang up call: " + getState() + ": " + this + + " on phone " + getPhone()); + CallStateException excp = null; + for (Connection c : connections) { + try { + c.hangup(); + } catch (CallStateException e) { + excp = e; + } } + if (excp != null) throw excp; + setState(State.DISCONNECTING); } - if (excp != null) throw excp; - setState(State.DISCONNECTING); } void initIncomingCall(SipAudioCall sipAudioCall, boolean makeCallWait) { @@ -454,19 +466,20 @@ public class SipPhone extends SipPhoneBase { } void hold() throws CallStateException { - AudioGroup audioGroup = getAudioGroup(); - if (audioGroup == null) return; - audioGroup.setMode(AudioGroup.MODE_ON_HOLD); setState(State.HOLDING); + AudioGroup audioGroup = getAudioGroup(); + if (audioGroup != null) { + audioGroup.setMode(AudioGroup.MODE_ON_HOLD); + } for (Connection c : connections) ((SipConnection) c).hold(); } void unhold() throws CallStateException { - AudioGroup audioGroup = getAudioGroup(); - if (audioGroup == null) return; - audioGroup.setMode(AudioGroup.MODE_NORMAL); setState(State.ACTIVE); - for (Connection c : connections) ((SipConnection) c).unhold(); + AudioGroup audioGroup = new AudioGroup(); + for (Connection c : connections) { + ((SipConnection) c).unhold(audioGroup); + } } void setMute(boolean muted) { @@ -483,17 +496,26 @@ public class SipPhone extends SipPhoneBase { } void merge(SipCall that) throws CallStateException { - AudioGroup myGroup = getAudioGroup(); + AudioGroup audioGroup = getAudioGroup(); for (Connection c : that.connections) { SipConnection conn = (SipConnection) c; - conn.mergeTo(myGroup); - connections.add(conn); - conn.changeOwner(this); + add(conn); + if (conn.getState() == Call.State.HOLDING) { + conn.unhold(audioGroup); + } } - that.connections.clear(); that.setState(Call.State.IDLE); } + private void add(SipConnection conn) { + SipCall call = conn.getCall(); + if (call == this) return; + if (call != null) call.connections.remove(conn); + + connections.add(conn); + conn.changeOwner(this); + } + void sendDtmf(char c) { AudioGroup audioGroup = getAudioGroup(); if (audioGroup == null) return; @@ -568,7 +590,6 @@ public class SipPhone extends SipPhoneBase { private class SipConnection extends SipConnectionBase { private SipCall mOwner; private SipAudioCall mSipAudioCall; - private AudioGroup mOriginalGroup; private Call.State mState = Call.State.IDLE; private SipProfile mPeer; private boolean mIncoming = false; @@ -673,6 +694,7 @@ public class SipPhone extends SipPhoneBase { } void hold() throws CallStateException { + setState(Call.State.HOLDING); try { mSipAudioCall.holdCall(); } catch (SipException e) { @@ -680,7 +702,9 @@ public class SipPhone extends SipPhoneBase { } } - void unhold() throws CallStateException { + void unhold(AudioGroup audioGroup) throws CallStateException { + mSipAudioCall.setAudioGroup(audioGroup); + setState(Call.State.ACTIVE); try { mSipAudioCall.continueCall(); } catch (SipException e) { @@ -688,16 +712,6 @@ public class SipPhone extends SipPhoneBase { } } - void mergeTo(AudioGroup group) throws CallStateException { - AudioStream stream = mSipAudioCall.getAudioStream(); - if (stream == null) { - throw new CallStateException("wrong state to merge: " - + mSipAudioCall.getState()); - } - if (mOriginalGroup == null) mOriginalGroup = getAudioGroup(); - stream.join(group); - } - @Override protected void setState(Call.State state) { if (state == mState) return; @@ -732,29 +746,36 @@ public class SipPhone extends SipPhoneBase { @Override public void hangup() throws CallStateException { - // TODO: need to pull AudioStream out of the AudioGroup in case - // this conn was part of a conf call - Log.v(LOG_TAG, "hangup conn: " + mPeer.getUriString() + ": " - + ": on phone " + getPhone()); - try { - mSipAudioCall.endCall(); - setState(Call.State.DISCONNECTING); - setDisconnectCause(DisconnectCause.LOCAL); - } catch (SipException e) { - throw new CallStateException("hangup(): " + e); + synchronized (SipPhone.class) { + Log.v(LOG_TAG, "hangup conn: " + mPeer.getUriString() + ": " + + ": on phone " + getPhone().getPhoneName()); + try { + mSipAudioCall.endCall(); + setState(Call.State.DISCONNECTING); + setDisconnectCause(DisconnectCause.LOCAL); + } catch (SipException e) { + throw new CallStateException("hangup(): " + e); + } } } @Override public void separate() throws CallStateException { - // TODO: what's this for SIP? - /* - if (!disconnected) { - owner.separate(this); - } else { - throw new CallStateException ("disconnected"); + synchronized (SipPhone.class) { + SipCall call = (SipCall) SipPhone.this.getBackgroundCall(); + if (call.getState() != Call.State.IDLE) { + throw new CallStateException( + "cannot put conn back to a call in non-idle state: " + + call.getState()); + } + Log.v(LOG_TAG, "separate conn: " + mPeer.getUriString() + + " from " + mOwner + " back to " + call); + + AudioGroup audioGroup = call.getAudioGroup(); // may be null + call.add(this); + mSipAudioCall.setAudioGroup(audioGroup); + call.hold(); } - */ } @Override diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java index 36d65db..4b7e991 100755 --- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java +++ b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java @@ -175,10 +175,6 @@ abstract class SipPhoneBase extends PhoneBase { return state; } - public String getPhoneName() { - return "SIP"; - } - public int getPhoneType() { // FIXME: add SIP phone type return Phone.PHONE_TYPE_GSM; |