示例#1
0
 @Override
 protected void onCallEnded(DisconnectCause cause) {
   if (getDisconnectCause() != DisconnectCause.LOCAL) {
     setDisconnectCause(cause);
   }
   synchronized (SipPhone.class) {
     setState(Call.State.DISCONNECTED);
     SipAudioCall sipAudioCall = mSipAudioCall;
     // FIXME: This goes null and is synchronized, but many uses aren't sync'd
     mSipAudioCall = null;
     String sessionState = (sipAudioCall == null) ? "" : (sipAudioCall.getState() + ", ");
     if (SCN_DBG)
       log(
           "[SipAudioCallAdapter] onCallEnded: "
               + mPeer.getUriString()
               + ": "
               + sessionState
               + "cause: "
               + getDisconnectCause()
               + ", on phone "
               + getPhone());
     if (sipAudioCall != null) {
       sipAudioCall.setListener(null);
       sipAudioCall.close();
     }
     mOwner.onConnectionEnded(SipConnection.this);
   }
 }
示例#2
0
 @Override
 public void hangup() throws CallStateException {
   synchronized (SipPhone.class) {
     if (SCN_DBG)
       log(
           "hangup: conn="
               + mPeer.getUriString()
               + ": "
               + mState
               + ": on phone "
               + getPhone().getPhoneName());
     if (!mState.isAlive()) return;
     try {
       SipAudioCall sipAudioCall = mSipAudioCall;
       if (sipAudioCall != null) {
         sipAudioCall.setListener(null);
         sipAudioCall.endCall();
       }
     } catch (SipException e) {
       throw new CallStateException("hangup(): " + e);
     } finally {
       mAdapter.onCallEnded(
           ((mState == Call.State.INCOMING) || (mState == Call.State.WAITING))
               ? DisconnectCause.INCOMING_REJECTED
               : DisconnectCause.LOCAL);
     }
   }
 }
示例#3
0
    @Override
    public void separate() throws CallStateException {
      synchronized (SipPhone.class) {
        SipCall call =
            (getPhone() == SipPhone.this)
                ? (SipCall) getBackgroundCall()
                : (SipCall) getForegroundCall();
        if (call.getState() != Call.State.IDLE) {
          throw new CallStateException(
              "cannot put conn back to a call in non-idle state: " + call.getState());
        }
        if (SCN_DBG)
          log("separate: conn=" + mPeer.getUriString() + " from " + mOwner + " back to " + call);

        // separate the AudioGroup and connection from the original call
        Phone originalPhone = getPhone();
        AudioGroup audioGroup = call.getAudioGroup(); // may be null
        call.add(this);
        mSipAudioCall.setAudioGroup(audioGroup);

        // put the original call to bg; and the separated call becomes
        // fg if it was in bg
        originalPhone.switchHoldingAndActive();

        // start audio and notify the phone app of the state change
        call = (SipCall) getForegroundCall();
        mSipAudioCall.startAudio();
        call.onConnectionStateChanged(this);
      }
    }
示例#4
0
 void unhold(AudioGroup audioGroup) throws CallStateException {
   mSipAudioCall.setAudioGroup(audioGroup);
   setState(Call.State.ACTIVE);
   try {
     mSipAudioCall.continueCall(TIMEOUT_HOLD_CALL);
   } catch (SipException e) {
     throw new CallStateException("unhold(): " + e);
   }
 }
示例#5
0
  public boolean canTake(Object incomingCall) {
    // FIXME: Is synchronizing on the class necessary, should we use a mLockObj?
    // Also there are many things not synchronized, of course
    // this may be true of CdmaPhone and GsmPhone too!!!
    synchronized (SipPhone.class) {
      if (!(incomingCall instanceof SipAudioCall)) {
        if (DBG) log("canTake: ret=false, not a SipAudioCall");
        return false;
      }
      if (mRingingCall.getState().isAlive()) {
        if (DBG) log("canTake: ret=false, ringingCall not alive");
        return false;
      }

      // FIXME: is it true that we cannot take any incoming call if
      // both foreground and background are active
      if (mForegroundCall.getState().isAlive() && mBackgroundCall.getState().isAlive()) {
        if (DBG) {
          log("canTake: ret=false," + " foreground and background both alive");
        }
        return false;
      }

      try {
        SipAudioCall sipAudioCall = (SipAudioCall) incomingCall;
        if (DBG) log("canTake: taking call from: " + sipAudioCall.getPeerProfile().getUriString());
        String localUri = sipAudioCall.getLocalProfile().getUriString();
        if (localUri.equals(mProfile.getUriString())) {
          boolean makeCallWait = mForegroundCall.getState().isAlive();
          mRingingCall.initIncomingCall(sipAudioCall, makeCallWait);
          if (sipAudioCall.getState() != SipSession.State.INCOMING_CALL) {
            // Peer cancelled the call!
            if (DBG) log("    canTake: call cancelled !!");
            mRingingCall.reset();
          }
          return true;
        }
      } catch (Exception e) {
        // Peer may cancel the call at any time during the time we hook
        // up ringingCall with sipAudioCall. Clean up ringingCall when
        // that happens.
        if (DBG) log("    canTake: exception e=" + e);
        mRingingCall.reset();
      }
      if (DBG) log("canTake: NOT taking !!");
      return false;
    }
  }
示例#6
0
 void acceptCall() throws CallStateException {
   try {
     mSipAudioCall.answerCall(TIMEOUT_ANSWER_CALL);
   } catch (SipException e) {
     throw new CallStateException("acceptCall(): " + e);
   }
 }
示例#7
0
 @Override
 public void onCallEnded(SipAudioCall call) {
   if (SACA_DBG) log("onCallEnded: call=" + call);
   onCallEnded(
       call.isInCall()
           ? Connection.DisconnectCause.NORMAL
           : Connection.DisconnectCause.INCOMING_MISSED);
 }
示例#8
0
 void hold() throws CallStateException {
   setState(Call.State.HOLDING);
   try {
     mSipAudioCall.holdCall(TIMEOUT_HOLD_CALL);
   } catch (SipException e) {
     throw new CallStateException("hold(): " + e);
   }
 }
示例#9
0
    void initIncomingCall(SipAudioCall sipAudioCall, boolean makeCallWait) {
      SipProfile callee = sipAudioCall.getPeerProfile();
      SipConnection c = new SipConnection(this, callee);
      mConnections.add(c);

      Call.State newState = makeCallWait ? State.WAITING : State.INCOMING;
      c.initIncomingCall(sipAudioCall, newState);

      setState(newState);
      notifyNewRingingConnectionP(c);
    }
示例#10
0
 private static Call.State getCallStateFrom(SipAudioCall sipAudioCall) {
   if (sipAudioCall.isOnHold()) return Call.State.HOLDING;
   int sessionState = sipAudioCall.getState();
   switch (sessionState) {
     case SipSession.State.READY_TO_CALL:
       return Call.State.IDLE;
     case SipSession.State.INCOMING_CALL:
     case SipSession.State.INCOMING_CALL_ANSWERING:
       return Call.State.INCOMING;
     case SipSession.State.OUTGOING_CALL:
       return Call.State.DIALING;
     case SipSession.State.OUTGOING_CALL_RING_BACK:
       return Call.State.ALERTING;
     case SipSession.State.OUTGOING_CALL_CANCELING:
       return Call.State.DISCONNECTING;
     case SipSession.State.IN_CALL:
       return Call.State.ACTIVE;
     default:
       slog("illegal connection state: " + sessionState);
       return Call.State.DISCONNECTED;
   }
 }
示例#11
0
 AudioGroup getAudioGroup() {
   if (mSipAudioCall == null) return null;
   return mSipAudioCall.getAudioGroup();
 }
示例#12
0
 boolean getMute() {
   return (mSipAudioCall == null) ? false : mSipAudioCall.isMuted();
 }
示例#13
0
 void setMute(boolean muted) {
   if ((mSipAudioCall != null) && (muted != mSipAudioCall.isMuted())) {
     if (SCN_DBG) log("setState: prev muted=" + !muted + " new muted=" + muted);
     mSipAudioCall.toggleMute();
   }
 }
示例#14
0
 @Override
 public void onCallEstablished(SipAudioCall call) {
   onChanged(call);
   // Race onChanged synchronized this isn't
   if (mState == Call.State.ACTIVE) call.startAudio();
 }
示例#15
0
 @Override
 public void onCallHeld(SipAudioCall call) {
   onChanged(call);
   // Race onChanged synchronized this isn't
   if (mState == Call.State.HOLDING) call.startAudio();
 }
示例#16
0
 void dial() throws SipException {
   setState(Call.State.DIALING);
   mSipAudioCall = mSipManager.makeAudioCall(mProfile, mPeer, null, TIMEOUT_MAKE_CALL);
   mSipAudioCall.setListener(mAdapter);
 }
示例#17
0
 void initIncomingCall(SipAudioCall sipAudioCall, Call.State newState) {
   setState(newState);
   mSipAudioCall = sipAudioCall;
   sipAudioCall.setListener(mAdapter); // call back to set state
   mIncoming = true;
 }