@Override
  protected void onResume() {
    Log.i(this, "onResume()...");
    super.onResume();

    mIsForegroundActivity = true;

    InCallPresenter.getInstance().setThemeColors();
    InCallPresenter.getInstance().onUiShowing(true);

    if (mShowDialpadRequested) {
      mCallButtonFragment.displayDialpad(true /* show */, mAnimateDialpadOnShow /* animate */);
      mShowDialpadRequested = false;
      mAnimateDialpadOnShow = false;

      if (mDialpadFragment != null) {
        mDialpadFragment.setDtmfText(mDtmfText);
        mDtmfText = null;
      }
    }

    if (mShowPostCharWaitDialogOnResume) {
      showPostCharWaitDialog(mShowPostCharWaitDialogCallId, mShowPostCharWaitDialogChars);
    }
  }
  @Override
  public void onConfigurationChanged(Configuration config) {
    InCallPresenter.getInstance().getProximitySensor().onConfigurationChanged(config);
    Log.d(this, "onConfigurationChanged " + config.orientation);

    // Check to see if the orientation changed to prevent triggering orientation change events
    // for other configuration changes.
    if (config.orientation != mCurrentOrientation) {
      mCurrentOrientation = config.orientation;
      InCallPresenter.getInstance()
          .onDeviceRotationChange(getWindowManager().getDefaultDisplay().getRotation());
      InCallPresenter.getInstance().onDeviceOrientationChange(mCurrentOrientation);
    }
    super.onConfigurationChanged(config);
  }
  // onPause is guaranteed to be called when the InCallActivity goes
  // in the background.
  @Override
  protected void onPause() {
    Log.d(this, "onPause()...");
    super.onPause();

    mIsForegroundActivity = false;

    if (mDialpadFragment != null) {
      mDialpadFragment.onDialerKeyUp(null);
    }

    InCallPresenter.getInstance().onUiShowing(false);
    if (isFinishing()) {
      InCallPresenter.getInstance().unsetActivity(this);
    }
  }
  @Override
  protected void onStart() {
    Log.d(this, "onStart()...");
    super.onStart();

    // setting activity should be last thing in setup process
    InCallPresenter.getInstance().setActivity(this);
  }
  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {
      case KeyEvent.KEYCODE_CALL:
        boolean handled = InCallPresenter.getInstance().handleCallKey();
        if (!handled) {
          Log.w(this, "InCallActivity should always handle KEYCODE_CALL in onKeyDown");
        }
        // Always consume CALL to be sure the PhoneWindow won't do anything with it
        return true;

        // Note there's no KeyEvent.KEYCODE_ENDCALL case here.
        // The standard system-wide handling of the ENDCALL key
        // (see PhoneWindowManager's handling of KEYCODE_ENDCALL)
        // already implements exactly what the UI spec wants,
        // namely (1) "hang up" if there's a current active call,
        // or (2) "don't answer" if there's a current ringing call.

      case KeyEvent.KEYCODE_CAMERA:
        // Disable the CAMERA button while in-call since it's too
        // easy to press accidentally.
        return true;

      case KeyEvent.KEYCODE_VOLUME_UP:
      case KeyEvent.KEYCODE_VOLUME_DOWN:
      case KeyEvent.KEYCODE_VOLUME_MUTE:
        // Ringer silencing handled by PhoneWindowManager.
        break;

      case KeyEvent.KEYCODE_MUTE:
        // toggle mute
        TelecomAdapter.getInstance().mute(!AudioModeProvider.getInstance().getMute());
        return true;

        // Various testing/debugging features, enabled ONLY when VERBOSE == true.
      case KeyEvent.KEYCODE_SLASH:
        if (Log.VERBOSE) {
          Log.v(this, "----------- InCallActivity View dump --------------");
          // Dump starting from the top-level view of the entire activity:
          Window w = this.getWindow();
          View decorView = w.getDecorView();
          Log.d(this, "View dump:" + decorView);
          return true;
        }
        break;
      case KeyEvent.KEYCODE_EQUALS:
        // TODO: Dump phone state?
        break;
    }

    if (event.getRepeatCount() == 0 && handleDialerKeyDown(keyCode, event)) {
      return true;
    }

    return super.onKeyDown(keyCode, event);
  }
  public void displayDialpad(boolean showDialpad, boolean animate) {
    // If the dialpad is already visible, don't animate in. If it's gone, don't animate out.
    if ((showDialpad && isDialpadVisible()) || (!showDialpad && !isDialpadVisible())) {
      return;
    }
    // We don't do a FragmentTransaction on the hide case because it will be dealt with when
    // the listener is fired after an animation finishes.
    if (!animate) {
      showDialpad(showDialpad);
    } else {
      if (showDialpad) {
        showDialpad(true);
        mDialpadFragment.animateShowDialpad();
      }
      mCallCardFragment.onDialpadVisiblityChange(showDialpad);
      mDialpadFragment.getView().startAnimation(showDialpad ? mSlideIn : mSlideOut);
    }

    InCallPresenter.getInstance().getProximitySensor().onDialpadVisible(showDialpad);
  }
 private void onDialogDismissed() {
   mDialog = null;
   InCallPresenter.getInstance().onDismissDialog();
 }
  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;
    }
  }
 @Override
 protected void onDestroy() {
   Log.d(this, "onDestroy()...  this = " + this);
   InCallPresenter.getInstance().unsetActivity(this);
   super.onDestroy();
 }