/**
   * Called when there is a change to the call list. Sets the In-Call state for the entire in-call
   * app based on the information it gets from CallList. Dispatches the in-call state to all
   * listeners. Can trigger the creation or destruction of the UI based on the states that is
   * calculates.
   */
  @Override
  public void onCallListChange(CallList callList) {
    if (callList == null) {
      return;
    }
    InCallState newState = getPotentialStateFromCallList(callList);
    newState = startOrFinishUi(newState);

    // Renable notification shade and soft navigation buttons, if we are no longer in the
    // incoming call screen
    if (!newState.isIncoming()) {
      if (mAccelerometerListener != null) {
        mAccelerometerListener.enableSensor(false);
      }
      CallCommandClient.getInstance().setSystemBarNavigationEnabled(true);
    }

    // Set the new state before announcing it to the world
    Log.i(this, "Phone switching state: " + mInCallState + " -> " + newState);
    mInCallState = newState;

    // notify listeners of new state
    for (InCallStateListener listener : mListeners) {
      Log.d(this, "Notify " + listener + " of state " + mInCallState.toString());
      listener.onStateChange(mInCallState, callList);
    }

    if (isActivityStarted()) {
      final boolean hasCall =
          callList.getActiveOrBackgroundCall() != null || callList.getOutgoingCall() != null;
      mInCallActivity.dismissKeyguard(hasCall);
    }
  }
  /**
   * 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 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;
    }
  }