private void addRemoveConf(View callView) {
   CTCall call = (CTCall) callView.getTag(); // get the call to add/remove
   if (confList.contains(call)) {
     // Move call to private list. If selected call was moved set conference to hold
     confList.remove(call);
     privateList.add(call);
     call.iIsInConferece = false;
     TiviPhoneService.doCmd("*-" + call.iCallId);
     if (call == TiviPhoneService.calls.selectedCall) setConfOnHold();
   } else {
     // move from private to conference. If the conference is on hold (does not
     // contains selected call) then new call will be set to hold also if it is
     // not the selected call.
     privateList.remove(call);
     confList.add(call);
     call.iIsInConferece = true;
     if (call != TiviPhoneService.calls.selectedCall && !call.iIsOnHold && isConfOnHold()) {
       call.iIsOnHold = true;
       TiviPhoneService.doCmd("*h" + call.iCallId);
     }
     TiviPhoneService.doCmd("*+" + call.iCallId);
   }
   if (call.iIsOnHold) {
     callView.setBackgroundResource(R.drawable.call_mng_hold);
   } else {
     callView.setBackgroundResource(R.drawable.call_mng_normal);
   }
   updateContentView();
 }
  /**
   * Look for a new call in the lists and set it as selected (active) call.
   *
   * @param call the call to terminate
   * @return the new selected call or null if call was not the selected (active) call
   */
  private CTCall switchToNextCall(CTCall call, boolean userPressed) {
    CTCall nextCall = null;

    // If this is not the selected call, just terminate and handle call log.
    if (call != TiviPhoneService.calls.selectedCall) {
      if (userPressed) {
        TiviPhoneService.doCmd("*e" + call.iCallId);
      }
      return null;
    }

    if (confList.size() >= 1) nextCall = confList.get(0);
    else if (privateList.size() >= 1) nextCall = privateList.get(0);
    else if (inOutList.size() >= 1) nextCall = inOutList.get(0);

    // Terminate current call, switch to next.
    TiviPhoneService.doCmd("*e" + call.iCallId);

    if (nextCall != null) {
      TiviPhoneService.calls.setCurCall(nextCall); // switch selected call
      if (nextCall.iIsOnHold) {
        nextCall.iIsOnHold = false;
        TiviPhoneService.doCmd("*u" + nextCall.iCallId);
      }
    }
    return nextCall;
  }
  private void switchCallHold(CTCall call, View view) {

    // If call is currently not on hold, try to set it to hold
    if (!call.iIsOnHold) {
      if (call == TiviPhoneService.calls.selectedCall) // Never put selected call in hold mode
      return;

      if (inOutList.contains(call)) return;

      // handle conference calls only: we can set a call to hold mode without switching selected
      // call
      if (confList.contains(call)) {
        if (isConfOnHold()) // if conference is on hold, no need to process
        return;
      }
      view.setBackgroundResource(R.drawable.call_mng_hold);
      call.iIsOnHold = true;
      TiviPhoneService.doCmd("*h" + call.iCallId);
    }
    // Try to set to non-hold mode
    else {
      CTCall otherCall = TiviPhoneService.calls.selectedCall;

      if (confList.contains(call)) {
        // empty - may be we need some code later
      }
      // try to set the clicked call to un-hold state
      else if (privateList.contains(call)) {

        // The clicked call will become the selected call, thus if the current selected
        // call is a conference call we need to set conference to hold first.
        if (confList.contains(otherCall)) {
          setConfOnHold();
        } else {
          View otherView = findContentViewByTag(otherCall);
          otherCall.iIsOnHold = true;
          otherView.setBackgroundResource(R.drawable.call_mng_hold);
          TiviPhoneService.doCmd("*h" + otherCall.iCallId);
        }
      } else return;

      // un-hold the clicked call and set it as new current selected call
      call.iIsOnHold = false;
      view.setBackgroundResource(R.drawable.call_mng_normal);
      TiviPhoneService.calls.setCurCall(call);
      TiviPhoneService.doCmd("*u" + call.iCallId);
    }
  }
 @Override
 protected void onDestroy() {
   super.onDestroy();
   if (phoneIsBound) {
     phoneService.removeStateChangeListener(this);
   }
   doUnbindService();
 }
 /** Set all call in conference list to hold mode. */
 private void setConfOnHold() {
   for (CTCall c : confList) {
     if (c.iIsOnHold) continue;
     View view = findContentViewByTag(c);
     c.iIsOnHold = true;
     view.setBackgroundResource(R.drawable.call_mng_hold);
     TiviPhoneService.doCmd("*h" + c.iCallId);
   }
 }
 public void onServiceConnected(ComponentName className, IBinder service) {
   // This is called when the connection with the service has been
   // established, giving us the service object we can use to
   // interact with the service.  Because we have bound to a explicit
   // service that we know is running in our own process, we can
   // cast its IBinder to a concrete class and directly access it.
   phoneService = ((TiviPhoneService.LocalBinder) service).getService();
   phoneIsBound = true;
   serviceBound();
   phoneService.addStateChangeListener(CallManager.this);
 }
  synchronized void answerCall(boolean userPressed, CTCall call) {

    View view = findContentViewByTag(call);

    if (userPressed) {
      TiviPhoneService.doCmd("*a" + call.iCallId);
      return;
    }
    inOutList.remove(call);
    privateList.add(call);

    // user answered call, disable answer button, move call to private call list, update display
    ImageButton btn = (ImageButton) view.findViewById(R.id.CallMngAnswerCall);
    btn.setVisibility(View.INVISIBLE);
    btn.setEnabled(false);

    // If users answers a call and another call is selected then put that
    // call on hold and set answered call as selected call.
    if (call != TiviPhoneService.calls.selectedCall) {
      CTCall otherCall = TiviPhoneService.calls.selectedCall;
      TiviPhoneService.calls.setCurCall(call);
      switchCallHold(otherCall, view);
    }
  }
  synchronized void endCall(boolean userPressed, CTCall call) {
    if (call == null) {
      Log.w(LOG_TAG, "Call Manager: Null call during end call processing: " + userPressed);
      return;
    }
    // We need these counts to decide what to do
    int confCnt = confList.size(); // same as TiviPhoneService.calls.getCallCnt(CTCalls.eConfCall);
    int privCnt =
        privateList.size(); // same as TiviPhoneService.calls.getCallCnt(CTCalls.ePrivateCall);
    int inOutCnt =
        inOutList.size(); // same as TiviPhoneService.calls.getCallCnt(CTCalls.eStartupCall);

    // Check if this is the only/last call - that's the easy part
    if ((confCnt + privCnt + inOutCnt) <= 1) {
      // Our user pressed the end call button, end our call, otherwise just terminate this Activity
      if (userPressed) {
        TiviPhoneService.doCmd("*e" + call.iCallId);
      }
      finish();
      return;
    }

    /*
     *  The following code handles cases with more then one call.
     */
    int callType;
    if (inOutList.contains(call)) callType = CTCalls.eStartupCall;
    else if (privateList.contains(call)) callType = CTCalls.ePrivateCall;
    else if (confList.contains(call)) callType = CTCalls.eConfCall;
    else return;

    switch (callType) {
        /*
         * If the startup call is not the selected call then just terminate the call and
         * handle call log.
         *
         * Otherwise check if we have another call that we can set as new selected call.
         */
      case CTCalls.eStartupCall:
        if (!inOutList.remove(call)) return; // already handled

        inOutCnt--;
        switchToNextCall(call, userPressed);
        call.iEnded = 2;
        break;

        /*
         * If the private call is not the selected call then just terminate the call and
         * handle call log.
         *
         * Otherwise check if we have another call that we can set as new selected call.
         */
      case CTCalls.ePrivateCall:
        if (!privateList.remove(call)) return; // already handled

        privCnt--;
        switchToNextCall(call, userPressed);
        call.iEnded = 2;
        break;

        /*
         * Same handling as private calls.
         */
      case CTCalls.eConfCall:
        if (!confList.remove(call)) return; // already handled

        confCnt--;
        switchToNextCall(call, userPressed);
        call.iEnded = 2;
        break;
    }
  }