/** Utility function to bring up a generic "error" dialog. */
  private void showErrorDialog(CharSequence msg) {
    Log.i(this, "Show Dialog: " + msg);

    dismissPendingDialogs();

    mDialog =
        new AlertDialog.Builder(this)
            .setMessage(msg)
            .setPositiveButton(
                android.R.string.ok,
                new OnClickListener() {
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
                    onDialogDismissed();
                  }
                })
            .setOnCancelListener(
                new OnCancelListener() {
                  @Override
                  public void onCancel(DialogInterface dialog) {
                    onDialogDismissed();
                  }
                })
            .create();

    mDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    mDialog.show();
  }
  /**
   * When the state of in-call changes, this is the first method to get called. It determines if the
   * UI needs to be started or finished depending on the new state and does it.
   */
  private InCallState startOrFinishUi(InCallState newState) {
    Log.d(this, "startOrFinishUi: " + mInCallState + " -> " + newState);

    // TODO: Consider a proper state machine implementation

    // If the state isn't changing, we have already done any starting/stopping of
    // activities in a previous pass...so lets cut out early
    if (newState == mInCallState) {
      return newState;
    }

    // A new Incoming call means that the user needs to be notified of the the call (since
    // it wasn't them who initiated it).  We do this through full screen notifications and
    // happens indirectly through {@link StatusBarListener}.
    //
    // The process for incoming calls is as follows:
    //
    // 1) CallList          - Announces existence of new INCOMING call
    // 2) InCallPresenter   - Gets announcement and calculates that the new InCallState
    //                      - should be set to INCOMING.
    // 3) InCallPresenter   - This method is called to see if we need to start or finish
    //                        the app given the new state.
    // 4) StatusBarNotifier - Listens to InCallState changes. InCallPresenter calls
    //                        StatusBarNotifier explicitly to issue a FullScreen Notification
    //                        that will either start the InCallActivity or show the user a
    //                        top-level notification dialog if the user is in an immersive app.
    //                        That notification can also start the InCallActivity.
    // 5) InCallActivity    - Main activity starts up and at the end of its onCreate will
    //                        call InCallPresenter::setActivity() to let the presenter
    //                        know that start-up is complete.
    //
    //          [ AND NOW YOU'RE IN THE CALL. voila! ]
    //
    // Our app is started using a fullScreen notification.  We need to do this whenever
    // we get an incoming call.
    final boolean startStartupSequence = (InCallState.INCOMING == newState);

    // A new outgoing call indicates that the user just now dialed a number and when that
    // happens we need to display the screen immediateley.
    //
    // This is different from the incoming call sequence because we do not need to shock the
    // user with a top-level notification.  Just show the call UI normally.
    final boolean showCallUi = (InCallState.OUTGOING == newState);

    // TODO: Can we be suddenly in a call without it having been in the outgoing or incoming
    // state?  I havent seen that but if it can happen, the code below should be enabled.
    // showCallUi |= (InCallState.INCALL && !isActivityStarted());

    // The only time that we have an instance of mInCallActivity and it isn't started is
    // when it is being destroyed.  In that case, lets avoid bringing up another instance of
    // the activity.  When it is finally destroyed, we double check if we should bring it back
    // up so we aren't going to lose anything by avoiding a second startup here.
    boolean activityIsFinishing = mInCallActivity != null && !isActivityStarted();
    if (activityIsFinishing) {
      Log.i(this, "Undo the state change: " + newState + " -> " + mInCallState);
      return mInCallState;
    }

    if (showCallUi) {
      Log.i(this, "Start in call UI");
      showInCall(false);
    } else if (startStartupSequence) {
      Log.i(this, "Start Full Screen in call UI");

      // We're about the bring up the in-call UI for an incoming call. If we still have
      // dialogs up, we need to clear them out before showing incoming screen.
      if (isActivityStarted()) {
        mInCallActivity.dismissPendingDialogs();
      }
      startUi(newState);
    } else if (newState == InCallState.NO_CALLS) {
      // The new state is the no calls state.  Tear everything down.
      attemptFinishActivity();
      attemptCleanup();
    }

    return newState;
  }