@Override
  public void onBackPressed() {
    Log.i(this, "onBackPressed");

    // BACK is also used to exit out of any "special modes" of the
    // in-call UI:

    if (!mConferenceManagerFragment.isVisible() && !mCallCardFragment.isVisible()) {
      return;
    }

    if (mDialpadFragment != null && mDialpadFragment.isVisible()) {
      mCallButtonFragment.displayDialpad(false /* show */, true /* animate */);
      return;
    } else if (mConferenceManagerFragment.isVisible()) {
      showConferenceCallManager(false);
      return;
    }

    // Always disable the Back key while an incoming call is ringing
    final Call call = CallList.getInstance().getIncomingCall();
    if (call != null) {
      Log.d(this, "Consume Back press for an incoming call");
      return;
    }

    // Nothing special to do.  Fall back to the default behavior.
    super.onBackPressed();
  }
  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    final CallList calls = CallList.getInstance();
    final Call call = calls.getFirstCall();
    getPresenter().init(getActivity(), call);
  }
  /**
   * Called when a call becomes disconnected. Called everytime an existing call changes from being
   * connected (incoming/outgoing/active) to disconnected.
   */
  @Override
  public void onDisconnect(Call call) {
    hideDialpadForDisconnect();
    maybeShowErrorDialogOnDisconnect(call);

    // We need to do the run the same code as onCallListChange.
    onCallListChange(CallList.getInstance());

    if (isActivityStarted()) {
      mInCallActivity.dismissKeyguard(false);
    }
  }
  private void relaunchedFromDialer(boolean showDialpad) {
    mShowDialpadRequested = showDialpad;
    mAnimateDialpadOnShow = true;

    if (mShowDialpadRequested) {
      // If there's only one line in use, AND it's on hold, then we're sure the user
      // wants to use the dialpad toward the exact line, so un-hold the holding line.
      final Call call = CallList.getInstance().getActiveOrBackgroundCall();
      if (call != null && call.getState() == State.ONHOLD) {
        TelecomAdapter.getInstance().unholdCall(call.getId());
      }
    }
  }
  private void internalResolveIntent(Intent intent) {
    final String action = intent.getAction();

    if (action.equals(intent.ACTION_MAIN)) {
      // This action is the normal way to bring up the in-call UI.
      //
      // But we do check here for one extra that can come along with the
      // ACTION_MAIN intent:

      if (intent.hasExtra(SHOW_DIALPAD_EXTRA)) {
        // SHOW_DIALPAD_EXTRA can be used here to specify whether the DTMF
        // dialpad should be initially visible.  If the extra isn't
        // present at all, we just leave the dialpad in its previous state.

        final boolean showDialpad = intent.getBooleanExtra(SHOW_DIALPAD_EXTRA, false);
        Log.d(this, "- internalResolveIntent: SHOW_DIALPAD_EXTRA: " + showDialpad);

        relaunchedFromDialer(showDialpad);
      }

      if (intent.getBooleanExtra(NEW_OUTGOING_CALL_EXTRA, false)) {
        intent.removeExtra(NEW_OUTGOING_CALL_EXTRA);
        Call call = CallList.getInstance().getOutgoingCall();
        if (call == null) {
          call = CallList.getInstance().getPendingOutgoingCall();
        }

        Bundle extras = null;
        if (call != null) {
          extras = call.getTelecommCall().getDetails().getExtras();
        }
        if (extras == null) {
          // Initialize the extras bundle to avoid NPE
          extras = new Bundle();
        }

        Point touchPoint = null;
        if (TouchPointManager.getInstance().hasValidPoint()) {
          // Use the most immediate touch point in the InCallUi if available
          touchPoint = TouchPointManager.getInstance().getPoint();
        } else {
          // Otherwise retrieve the touch point from the call intent
          if (call != null) {
            touchPoint = (Point) extras.getParcelable(TouchPointManager.TOUCH_POINT);
          }
        }

        // This is only true in the case where an outgoing call is initiated by tapping
        // on the "Select account dialog", in which case we skip the initial animation. In
        // most other cases the circular reveal is done by OutgoingCallAnimationActivity.
        final boolean showCircularReveal =
            intent.getBooleanExtra(SHOW_CIRCULAR_REVEAL_EXTRA, false);
        mCallCardFragment.animateForNewOutgoingCall(touchPoint, showCircularReveal);

        // InCallActivity is responsible for disconnecting a new outgoing call if there
        // is no way of making it (i.e. no valid call capable accounts)
        if (InCallPresenter.isCallWithNoValidAccounts(call)) {
          TelecomAdapter.getInstance().disconnectCall(call.getId());
        }

        dismissKeyguard(true);
      }

      Call pendingAccountSelectionCall = CallList.getInstance().getWaitingForAccountCall();
      if (pendingAccountSelectionCall != null) {
        mCallCardFragment.setVisible(false);
        Bundle extras = pendingAccountSelectionCall.getTelecommCall().getDetails().getExtras();

        final List<PhoneAccountHandle> phoneAccountHandles;
        if (extras != null) {
          phoneAccountHandles =
              extras.getParcelableArrayList(android.telecom.Call.AVAILABLE_PHONE_ACCOUNTS);
        } else {
          phoneAccountHandles = new ArrayList<>();
        }

        SelectPhoneAccountListener listener =
            new SelectPhoneAccountListener() {
              @Override
              public void onPhoneAccountSelected(
                  PhoneAccountHandle selectedAccountHandle, boolean setDefault) {
                InCallPresenter.getInstance()
                    .handleAccountSelection(selectedAccountHandle, setDefault);
              }

              @Override
              public void onDialogDismissed() {
                InCallPresenter.getInstance().cancelAccountSelection();
              }
            };

        SelectPhoneAccountDialogFragment.showAccountDialog(
            getFragmentManager(),
            R.string.select_phone_account_for_calls,
            true,
            phoneAccountHandles,
            listener);
      } else {
        mCallCardFragment.setVisible(true);
      }

      return;
    }
  }
  /**
   * Handles the green CALL key while in-call.
   *
   * @return true if we consumed the event.
   */
  public boolean handleCallKey() {
    Log.v(this, "handleCallKey");

    // The green CALL button means either "Answer", "Unhold", or
    // "Swap calls", or can be a no-op, depending on the current state
    // of the Phone.

    /** INCOMING CALL */
    final CallList calls = CallList.getInstance();
    final Call incomingCall = calls.getIncomingCall();
    Log.v(this, "incomingCall: " + incomingCall);

    // (1) Attempt to answer a call
    if (incomingCall != null) {
      CallCommandClient.getInstance().answerCall(incomingCall.getCallId());
      if (mAccelerometerListener != null) {
        mAccelerometerListener.enableSensor(false);
      }
      return true;
    }

    /** ACTIVE CALL */
    final Call activeCall = calls.getActiveCall();
    if (activeCall != null) {
      // TODO: This logic is repeated from CallButtonPresenter.java. We should
      // consolidate this logic.
      final boolean isGeneric = activeCall.can(Capabilities.GENERIC_CONFERENCE);
      final boolean canMerge = activeCall.can(Capabilities.MERGE_CALLS);
      final boolean canSwap = activeCall.can(Capabilities.SWAP_CALLS);

      Log.v(
          this,
          "activeCall: "
              + activeCall
              + ", isGeneric: "
              + isGeneric
              + ", canMerge: "
              + canMerge
              + ", canSwap: "
              + canSwap);

      // (2) Attempt actions on Generic conference calls
      if (activeCall.isConferenceCall() && isGeneric) {
        if (canMerge) {
          CallCommandClient.getInstance().merge();
          return true;
        } else if (canSwap) {
          CallCommandClient.getInstance().swap();
          return true;
        }
      }

      // (3) Swap calls
      if (canSwap) {
        CallCommandClient.getInstance().swap();
        return true;
      }
    }

    /** BACKGROUND CALL */
    final Call heldCall = calls.getBackgroundCall();
    if (heldCall != null) {
      // We have a hold call so presumeable it will always support HOLD...but
      // there is no harm in double checking.
      final boolean canHold = heldCall.can(Capabilities.HOLD);

      Log.v(this, "heldCall: " + heldCall + ", canHold: " + canHold);

      // (4) unhold call
      if (heldCall.getState() == Call.State.ONHOLD && canHold) {
        CallCommandClient.getInstance().hold(heldCall.getCallId(), false);
        return true;
      }
    }

    // Always consume hard keys
    return true;
  }