/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.incallui.answer.impl;

import android.Manifest.permission;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Trace;
import android.support.annotation.DrawableRes;
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.annotation.VisibleForTesting;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.transition.TransitionManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.dialer.common.Assert;
import com.android.dialer.common.FragmentUtils;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.MathUtil;
import com.android.dialer.logging.DialerImpression.Type;
import com.android.dialer.logging.Logger;
import com.android.dialer.multimedia.MultimediaData;
import com.android.dialer.telecom.TelecomUtil;
import com.android.dialer.util.ViewUtil;
import com.android.incallui.answer.impl.CreateCustomSmsDialogFragment.CreateCustomSmsHolder;
import com.android.incallui.answer.impl.SmsBottomSheetFragment.SmsSheetHolder;
import com.android.incallui.answer.impl.affordance.SwipeButtonHelper.Callback;
import com.android.incallui.answer.impl.affordance.SwipeButtonView;
import com.android.incallui.answer.impl.answermethod.AnswerMethod;
import com.android.incallui.answer.impl.answermethod.AnswerMethodFactory;
import com.android.incallui.answer.impl.answermethod.AnswerMethodHolder;
import com.android.incallui.answer.impl.utils.Interpolators;
import com.android.incallui.answer.protocol.AnswerScreen;
import com.android.incallui.answer.protocol.AnswerScreenDelegate;
import com.android.incallui.answer.protocol.AnswerScreenDelegateFactory;
import com.android.incallui.call.state.DialerCallState;
import com.android.incallui.contactgrid.ContactGridManager;
import com.android.incallui.incall.protocol.ContactPhotoType;
import com.android.incallui.incall.protocol.InCallScreen;
import com.android.incallui.incall.protocol.InCallScreenDelegate;
import com.android.incallui.incall.protocol.InCallScreenDelegateFactory;
import com.android.incallui.incall.protocol.PrimaryCallState;
import com.android.incallui.incall.protocol.PrimaryInfo;
import com.android.incallui.incall.protocol.SecondaryInfo;
import com.android.incallui.incalluilock.InCallUiLock;
import com.android.incallui.maps.MapsComponent;
import com.android.incallui.sessiondata.AvatarPresenter;
import com.android.incallui.sessiondata.MultimediaFragment;
import com.android.incallui.sessiondata.MultimediaFragment.Holder;
import com.android.incallui.speakeasy.SpeakEasyComponent;
import com.android.incallui.util.AccessibilityUtil;
import com.android.incallui.video.protocol.VideoCallScreen;
import com.android.incallui.videotech.utils.VideoUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/** The new version of the incoming call screen. */
@SuppressLint("ClickableViewAccessibility")
public class AnswerFragment extends Fragment
    implements AnswerScreen,
        InCallScreen,
        SmsSheetHolder,
        CreateCustomSmsHolder,
        AnswerMethodHolder,
        Holder {

  @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
  static final String ARG_CALL_ID = "call_id";

  static final String ARG_IS_RTT_CALL = "is_rtt_call";

  @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
  static final String ARG_IS_VIDEO_CALL = "is_video_call";

  static final String ARG_ALLOW_ANSWER_AND_RELEASE = "allow_answer_and_release";

  static final String ARG_HAS_CALL_ON_HOLD = "has_call_on_hold";

  @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
  static final String ARG_IS_VIDEO_UPGRADE_REQUEST = "is_video_upgrade_request";

  @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
  static final String ARG_IS_SELF_MANAGED_CAMERA = "is_self_managed_camera";

  static final String ARG_ALLOW_SPEAK_EASY = "allow_speak_easy";

  private static final String STATE_HAS_ANIMATED_ENTRY = "hasAnimated";

  private static final int HINT_SECONDARY_SHOW_DURATION_MILLIS = 5000;
  private static final float ANIMATE_LERP_PROGRESS = 0.5f;
  private static final int STATUS_BAR_DISABLE_RECENT = 0x01000000;
  private static final int STATUS_BAR_DISABLE_HOME = 0x00200000;
  private static final int STATUS_BAR_DISABLE_BACK = 0x00400000;

  private static void fadeToward(View view, float newAlpha) {
    view.setAlpha(MathUtil.lerp(view.getAlpha(), newAlpha, ANIMATE_LERP_PROGRESS));
  }

  private static void scaleToward(View view, float newScale) {
    view.setScaleX(MathUtil.lerp(view.getScaleX(), newScale, ANIMATE_LERP_PROGRESS));
    view.setScaleY(MathUtil.lerp(view.getScaleY(), newScale, ANIMATE_LERP_PROGRESS));
  }

  private AnswerScreenDelegate answerScreenDelegate;
  private InCallScreenDelegate inCallScreenDelegate;

  private View importanceBadge;
  private SwipeButtonView secondaryButton;
  private SwipeButtonView answerAndReleaseButton;
  private AffordanceHolderLayout affordanceHolderLayout;
  private LinearLayout chipContainer;
  // Use these flags to prevent user from clicking accept/reject buttons multiple times.
  // We use separate flags because in some rare cases accepting a call may fail to join the room,
  // and then user is stuck in the incoming call view until it times out. Two flags at least give
  // the user a chance to get out of the CallActivity.
  private boolean buttonAcceptClicked;
  private boolean buttonRejectClicked;
  private boolean hasAnimatedEntry;
  private PrimaryInfo primaryInfo = PrimaryInfo.empty();
  private PrimaryCallState primaryCallState;
  private ArrayList<CharSequence> textResponses;
  private SmsBottomSheetFragment textResponsesFragment;
  private CreateCustomSmsDialogFragment createCustomSmsDialogFragment;
  private SecondaryBehavior secondaryBehavior = SecondaryBehavior.REJECT_WITH_SMS;
  private SecondaryBehavior answerAndReleaseBehavior;
  private ContactGridManager contactGridManager;
  private VideoCallScreen answerVideoCallScreen;
  private Handler handler = new Handler(Looper.getMainLooper());

  private enum SecondaryBehavior {
    REJECT_WITH_SMS(
        R.drawable.quantum_ic_message_white_24,
        R.string.a11y_description_incoming_call_reject_with_sms,
        R.string.a11y_incoming_call_reject_with_sms,
        R.string.call_incoming_swipe_to_decline_with_message) {
      @Override
      public void performAction(AnswerFragment fragment) {
        fragment.showMessageMenu();
      }
    },

    ANSWER_VIDEO_AS_AUDIO(
        R.drawable.quantum_ic_videocam_off_vd_theme_24,
        R.string.a11y_description_incoming_call_answer_video_as_audio,
        R.string.a11y_incoming_call_answer_video_as_audio,
        R.string.call_incoming_swipe_to_answer_video_as_audio) {
      @Override
      public void performAction(AnswerFragment fragment) {
        fragment.acceptCallByUser(true /* answerVideoAsAudio */);
      }
    },

    ANSWER_AND_RELEASE(
        R.drawable.ic_end_answer_32,
        R.string.a11y_description_incoming_call_answer_and_release,
        R.string.a11y_incoming_call_answer_and_release,
        R.string.call_incoming_swipe_to_answer_and_release) {
      @Override
      public void performAction(AnswerFragment fragment) {
        fragment.performAnswerAndRelease();
      }
    };

    @DrawableRes public int icon;
    @StringRes public final int contentDescription;
    @StringRes public final int accessibilityLabel;
    @StringRes public final int hintText;

    SecondaryBehavior(
        @DrawableRes int icon,
        @StringRes int contentDescription,
        @StringRes int accessibilityLabel,
        @StringRes int hintText) {
      this.icon = icon;
      this.contentDescription = contentDescription;
      this.accessibilityLabel = accessibilityLabel;
      this.hintText = hintText;
    }

    public abstract void performAction(AnswerFragment fragment);

    public void applyToView(ImageView view) {
      view.setImageResource(icon);
      view.setContentDescription(view.getContext().getText(contentDescription));
    }
  }

  private void performSpeakEasy(View unused) {
    answerScreenDelegate.onSpeakEasyCall();
    buttonAcceptClicked = true;
  }

  private void performAnswerAndRelease() {
    restoreAnswerAndReleaseButtonAnimation();
    answerScreenDelegate.onAnswerAndReleaseCall();
    buttonAcceptClicked = true;
  }

  private void restoreAnswerAndReleaseButtonAnimation() {
    answerAndReleaseButton
        .animate()
        .alpha(0)
        .withEndAction(
            new Runnable() {
              @Override
              public void run() {
                affordanceHolderLayout.reset(false);
                secondaryButton.animate().alpha(1);
              }
            });
  }

  private final AccessibilityDelegate accessibilityDelegate =
      new AccessibilityDelegate() {
        @Override
        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
          super.onInitializeAccessibilityNodeInfo(host, info);
          if (host == secondaryButton) {
            CharSequence label = getText(secondaryBehavior.accessibilityLabel);
            info.addAction(new AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, label));
          } else if (host == answerAndReleaseButton) {
            CharSequence label = getText(answerAndReleaseBehavior.accessibilityLabel);
            info.addAction(new AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, label));
          }
        }

        @Override
        public boolean performAccessibilityAction(View host, int action, Bundle args) {
          if (action == AccessibilityNodeInfo.ACTION_CLICK) {
            if (host == secondaryButton) {
              performSecondaryButtonAction();
              return true;
            } else if (host == answerAndReleaseButton) {
              performAnswerAndReleaseButtonAction();
              return true;
            }
          }
          return super.performAccessibilityAction(host, action, args);
        }
      };

  private final Callback affordanceCallback =
      new Callback() {
        @Override
        public void onAnimationToSideStarted(boolean rightPage, float translation, float vel) {}

        @Override
        public void onAnimationToSideEnded(boolean rightPage) {
          if (rightPage) {
            performAnswerAndReleaseButtonAction();
          } else {
            performSecondaryButtonAction();
          }
        }

        @Override
        public float getMaxTranslationDistance() {
          View view = getView();
          if (view == null) {
            return 0;
          }
          return (float) Math.hypot(view.getWidth(), view.getHeight());
        }

        @Override
        public void onSwipingStarted(boolean rightIcon) {}

        @Override
        public void onSwipingAborted() {}

        @Override
        public void onIconClicked(boolean rightIcon) {
          affordanceHolderLayout.startHintAnimation(rightIcon, null);
          getAnswerMethod()
              .setHintText(
                  rightIcon
                      ? getText(answerAndReleaseBehavior.hintText)
                      : getText(secondaryBehavior.hintText));
          handler.removeCallbacks(swipeHintRestoreTimer);
          handler.postDelayed(swipeHintRestoreTimer, HINT_SECONDARY_SHOW_DURATION_MILLIS);
        }

        @Override
        public SwipeButtonView getLeftIcon() {
          return secondaryButton;
        }

        @Override
        public SwipeButtonView getRightIcon() {
          return answerAndReleaseButton;
        }

        @Override
        public View getLeftPreview() {
          return null;
        }

        @Override
        public View getRightPreview() {
          return null;
        }

        @Override
        public float getAffordanceFalsingFactor() {
          return 1.0f;
        }
      };

  private Runnable swipeHintRestoreTimer = this::restoreSwipeHintTexts;

  private void performSecondaryButtonAction() {
    secondaryBehavior.performAction(this);
  }

  private void performAnswerAndReleaseButtonAction() {
    answerAndReleaseBehavior.performAction(this);
  }

  public static AnswerFragment newInstance(
      String callId,
      boolean isRttCall,
      boolean isVideoCall,
      boolean isVideoUpgradeRequest,
      boolean isSelfManagedCamera,
      boolean allowAnswerAndRelease,
      boolean hasCallOnHold,
      boolean allowSpeakEasy) {
    Bundle bundle = new Bundle();
    bundle.putString(ARG_CALL_ID, Assert.isNotNull(callId));
    bundle.putBoolean(ARG_IS_RTT_CALL, isRttCall);
    bundle.putBoolean(ARG_IS_VIDEO_CALL, isVideoCall);
    bundle.putBoolean(ARG_IS_VIDEO_UPGRADE_REQUEST, isVideoUpgradeRequest);
    bundle.putBoolean(ARG_IS_SELF_MANAGED_CAMERA, isSelfManagedCamera);
    bundle.putBoolean(ARG_ALLOW_ANSWER_AND_RELEASE, allowAnswerAndRelease);
    bundle.putBoolean(ARG_HAS_CALL_ON_HOLD, hasCallOnHold);
    bundle.putBoolean(ARG_ALLOW_SPEAK_EASY, allowSpeakEasy);

    AnswerFragment instance = new AnswerFragment();
    instance.setArguments(bundle);
    return instance;
  }

  @Override
  public boolean isActionTimeout() {
    return (buttonAcceptClicked || buttonRejectClicked) && answerScreenDelegate.isActionTimeout();
  }

  @Override
  @NonNull
  public String getCallId() {
    return Assert.isNotNull(getArguments().getString(ARG_CALL_ID));
  }

  @Override
  public boolean isVideoUpgradeRequest() {
    return getArguments().getBoolean(ARG_IS_VIDEO_UPGRADE_REQUEST);
  }

  @Override
  public void setTextResponses(List<String> textResponses) {
    if (isVideoCall() || isVideoUpgradeRequest()) {
      LogUtil.i("AnswerFragment.setTextResponses", "no-op for video calls");
    } else if (textResponses == null) {
      LogUtil.i("AnswerFragment.setTextResponses", "no text responses, hiding secondary button");
      this.textResponses = null;
      secondaryButton.setVisibility(View.INVISIBLE);
    } else if (getActivity().isInMultiWindowMode()) {
      LogUtil.i("AnswerFragment.setTextResponses", "in multiwindow, hiding secondary button");
      this.textResponses = null;
      secondaryButton.setVisibility(View.INVISIBLE);
    } else {
      LogUtil.i("AnswerFragment.setTextResponses", "textResponses.size: " + textResponses.size());
      this.textResponses = new ArrayList<>(textResponses);
      secondaryButton.setVisibility(View.VISIBLE);
    }
  }

  private void initSecondaryButton() {
    secondaryBehavior =
        isVideoCall() || isVideoUpgradeRequest()
            ? SecondaryBehavior.ANSWER_VIDEO_AS_AUDIO
            : SecondaryBehavior.REJECT_WITH_SMS;
    secondaryBehavior.applyToView(secondaryButton);

    secondaryButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            performSecondaryButtonAction();
          }
        });
    secondaryButton.setClickable(AccessibilityUtil.isAccessibilityEnabled(getContext()));
    secondaryButton.setFocusable(AccessibilityUtil.isAccessibilityEnabled(getContext()));
    secondaryButton.setAccessibilityDelegate(accessibilityDelegate);

    // TODO(wangqi): Remove this when all secondary behavior is migrated to chip button.
    if (secondaryBehavior.equals(SecondaryBehavior.REJECT_WITH_SMS)) {
      secondaryButton.setVisibility(View.INVISIBLE);
    }

    if (isVideoUpgradeRequest()) {
      secondaryButton.setVisibility(View.INVISIBLE);
    } else if (isVideoCall()) {
      secondaryButton.setVisibility(View.VISIBLE);
    }

    answerAndReleaseBehavior = SecondaryBehavior.ANSWER_AND_RELEASE;
    answerAndReleaseBehavior.applyToView(answerAndReleaseButton);

    answerAndReleaseButton.setClickable(AccessibilityUtil.isAccessibilityEnabled(getContext()));
    answerAndReleaseButton.setFocusable(AccessibilityUtil.isAccessibilityEnabled(getContext()));
    answerAndReleaseButton.setAccessibilityDelegate(accessibilityDelegate);

    if (allowAnswerAndRelease()) {
      answerAndReleaseButton.setVisibility(View.VISIBLE);
      answerScreenDelegate.onAnswerAndReleaseButtonEnabled();
    } else {
      answerAndReleaseButton.setVisibility(View.INVISIBLE);
      answerScreenDelegate.onAnswerAndReleaseButtonDisabled();
    }
    answerAndReleaseButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            performAnswerAndReleaseButtonAction();
          }
        });
  }

  private void addSecondaryActionChip(
      @DrawableRes int iconRes, @StringRes int textRes, OnClickListener onClickListener) {
    LinearLayout button =
        (LinearLayout)
            getLayoutInflater().inflate(R.layout.secondary_action_chip, chipContainer, false);

    ImageView icon = button.findViewById(R.id.secondary_action_icon);
    icon.setImageResource(iconRes);
    TextView text = button.findViewById(R.id.secondary_action_text);
    text.setText(textRes);
    button.setOnClickListener(onClickListener);
    chipContainer.addView(button);
  }

  /** Initialize chip buttons */
  private void initChips() {
    if (allowSpeakEasy()) {
      Optional<Integer> speakEasyIconOptional =
          SpeakEasyComponent.get(getContext()).speakEasyIconResource();
      Optional<Integer> speakEasyTextOptional =
          SpeakEasyComponent.get(getContext()).speakEasyTextResource();
      if (speakEasyIconOptional.isPresent() && speakEasyTextOptional.isPresent()) {
        addSecondaryActionChip(
            speakEasyIconOptional.get(), speakEasyTextOptional.get(), this::performSpeakEasy);
      }
    }
    if (!isVideoCall() && !isVideoUpgradeRequest()) {
      addSecondaryActionChip(
          R.drawable.quantum_ic_message_white_24,
          R.string.call_incoming_reply_with_sms,
          v -> performSecondaryButtonAction());
    }
    chipContainer.setVisibility(chipContainer.getChildCount() > 0 ? View.VISIBLE : View.GONE);
  }

  @Override
  public boolean allowAnswerAndRelease() {
    return getArguments().getBoolean(ARG_ALLOW_ANSWER_AND_RELEASE);
  }

  @Override
  public boolean allowSpeakEasy() {
    return getArguments().getBoolean(ARG_ALLOW_SPEAK_EASY);
  }

  private boolean hasCallOnHold() {
    return getArguments().getBoolean(ARG_HAS_CALL_ON_HOLD);
  }

  @Override
  public boolean hasPendingDialogs() {
    boolean hasPendingDialogs =
        textResponsesFragment != null || createCustomSmsDialogFragment != null;
    LogUtil.i("AnswerFragment.hasPendingDialogs", "" + hasPendingDialogs);
    return hasPendingDialogs;
  }

  @Override
  public void dismissPendingDialogs() {
    LogUtil.i("AnswerFragment.dismissPendingDialogs", null);
    if (textResponsesFragment != null) {
      textResponsesFragment.dismiss();
      textResponsesFragment = null;
    }

    if (createCustomSmsDialogFragment != null) {
      createCustomSmsDialogFragment.dismiss();
      createCustomSmsDialogFragment = null;
    }
  }

  @Override
  public boolean isShowingLocationUi() {
    Fragment fragment = getChildFragmentManager().findFragmentById(R.id.incall_location_holder);
    return fragment != null && fragment.isVisible();
  }

  @Override
  public void showLocationUi(@Nullable Fragment locationUi) {
    boolean isShowing = isShowingLocationUi();
    if (!isShowing && locationUi != null) {
      // Show the location fragment.
      getChildFragmentManager()
          .beginTransaction()
          .replace(R.id.incall_location_holder, locationUi)
          .commitAllowingStateLoss();
    } else if (isShowing && locationUi == null) {
      // Hide the location fragment
      Fragment fragment = getChildFragmentManager().findFragmentById(R.id.incall_location_holder);
      getChildFragmentManager().beginTransaction().remove(fragment).commitAllowingStateLoss();
    }
  }

  @Override
  public Fragment getAnswerScreenFragment() {
    return this;
  }

  private AnswerMethod getAnswerMethod() {
    return ((AnswerMethod)
        getChildFragmentManager().findFragmentById(R.id.answer_method_container));
  }

  @Override
  public void setPrimary(PrimaryInfo primaryInfo) {
    LogUtil.i("AnswerFragment.setPrimary", primaryInfo.toString());
    this.primaryInfo = primaryInfo;
    updatePrimaryUI();
    updateImportanceBadgeVisibility();
  }

  private void updatePrimaryUI() {
    if (getView() == null) {
      return;
    }
    contactGridManager.setPrimary(primaryInfo);
    getAnswerMethod().setShowIncomingWillDisconnect(primaryInfo.answeringDisconnectsOngoingCall());
    getAnswerMethod()
        .setContactPhoto(
            primaryInfo.photoType() == ContactPhotoType.CONTACT ? primaryInfo.photo() : null);
    updateDataFragment();

    if (primaryInfo.shouldShowLocation()) {
      // Hide the avatar to make room for location
      contactGridManager.setAvatarHidden(true);
    }
  }

  private void updateDataFragment() {
    if (!isAdded()) {
      return;
    }
    LogUtil.enterBlock("AnswerFragment.updateDataFragment");
    Fragment current = getChildFragmentManager().findFragmentById(R.id.incall_data_container);
    Fragment newFragment = null;

    MultimediaData multimediaData = getSessionData();
    if (multimediaData != null
        && (!TextUtils.isEmpty(multimediaData.getText())
            || (multimediaData.getImageUri() != null)
            || (multimediaData.getLocation() != null && canShowMap()))) {
      // Need message fragment
      String subject = multimediaData.getText();
      Uri imageUri = multimediaData.getImageUri();
      Location location = multimediaData.getLocation();
      if (!(current instanceof MultimediaFragment)
          || !Objects.equals(((MultimediaFragment) current).getSubject(), subject)
          || !Objects.equals(((MultimediaFragment) current).getImageUri(), imageUri)
          || !Objects.equals(((MultimediaFragment) current).getLocation(), location)) {
        LogUtil.i("AnswerFragment.updateDataFragment", "Replacing multimedia fragment");
        // Needs replacement
        newFragment =
            MultimediaFragment.newInstance(
                multimediaData,
                false /* isInteractive */,
                !primaryInfo.isSpam() /* showAvatar */,
                primaryInfo.isSpam());
      }
    } else if (shouldShowAvatar()) {
      // Needs Avatar
      if (!(current instanceof AvatarFragment)) {
        LogUtil.i("AnswerFragment.updateDataFragment", "Replacing avatar fragment");
        // Needs replacement
        newFragment = new AvatarFragment();
      }
    } else {
      // Needs empty
      if (current != null) {
        LogUtil.i("AnswerFragment.updateDataFragment", "Removing current fragment");
        getChildFragmentManager().beginTransaction().remove(current).commitNow();
      }
      contactGridManager.setAvatarImageView(null, 0, false);
    }

    if (newFragment != null) {
      getChildFragmentManager()
          .beginTransaction()
          .replace(R.id.incall_data_container, newFragment)
          .commitNow();
    }
  }

  private boolean shouldShowAvatar() {
    return !isVideoCall() && !isVideoUpgradeRequest();
  }

  private boolean canShowMap() {
    return MapsComponent.get(getContext()).getMaps().isAvailable();
  }

  @Override
  public void updateAvatar(AvatarPresenter avatarContainer) {
    contactGridManager.setAvatarImageView(
        avatarContainer.getAvatarImageView(),
        avatarContainer.getAvatarSize(),
        avatarContainer.shouldShowAnonymousAvatar());
  }

  @Override
  public void setSecondary(@NonNull SecondaryInfo secondaryInfo) {}

  @Override
  public void setCallState(@NonNull PrimaryCallState primaryCallState) {
    LogUtil.i("AnswerFragment.setCallState", primaryCallState.toString());
    this.primaryCallState = primaryCallState;
    contactGridManager.setCallState(primaryCallState);
  }

  @Override
  public void setEndCallButtonEnabled(boolean enabled, boolean animate) {}

  @Override
  public void showManageConferenceCallButton(boolean visible) {}

  @Override
  public boolean isManageConferenceVisible() {
    return false;
  }

  @Override
  public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
    contactGridManager.dispatchPopulateAccessibilityEvent(event);
    // Add prompt of how to accept/decline call with swipe gesture.
    if (AccessibilityUtil.isTouchExplorationEnabled(getContext())) {
      event
          .getText()
          .add(getResources().getString(R.string.a11y_incoming_call_swipe_gesture_prompt));
    }
  }

  @Override
  public void showNoteSentToast() {}

  @Override
  public void updateInCallScreenColors() {}

  @Override
  public void onInCallScreenDialpadVisibilityChange(boolean isShowing) {}

  @Override
  public int getAnswerAndDialpadContainerResourceId() {
    throw Assert.createUnsupportedOperationFailException();
  }

  @Override
  public Fragment getInCallScreenFragment() {
    return this;
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
  }

  @Override
  public View onCreateView(
      LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Trace.beginSection("AnswerFragment.onCreateView");
    Bundle arguments = getArguments();
    Assert.checkState(arguments.containsKey(ARG_CALL_ID));
    Assert.checkState(arguments.containsKey(ARG_IS_RTT_CALL));
    Assert.checkState(arguments.containsKey(ARG_IS_VIDEO_CALL));
    Assert.checkState(arguments.containsKey(ARG_IS_VIDEO_UPGRADE_REQUEST));

    buttonAcceptClicked = false;
    buttonRejectClicked = false;

    View view = inflater.inflate(R.layout.fragment_incoming_call, container, false);
    secondaryButton = (SwipeButtonView) view.findViewById(R.id.incoming_secondary_button);
    answerAndReleaseButton = (SwipeButtonView) view.findViewById(R.id.incoming_secondary_button2);

    affordanceHolderLayout = (AffordanceHolderLayout) view.findViewById(R.id.incoming_container);
    affordanceHolderLayout.setAffordanceCallback(affordanceCallback);

    chipContainer = view.findViewById(R.id.incall_data_container_chip_container);

    importanceBadge = view.findViewById(R.id.incall_important_call_badge);
    importanceBadge
        .getViewTreeObserver()
        .addOnGlobalLayoutListener(
            new OnGlobalLayoutListener() {
              @Override
              public void onGlobalLayout() {
                int leftRightPadding = importanceBadge.getHeight() / 2;
                importanceBadge.setPadding(
                    leftRightPadding,
                    importanceBadge.getPaddingTop(),
                    leftRightPadding,
                    importanceBadge.getPaddingBottom());
              }
            });
    updateImportanceBadgeVisibility();

    contactGridManager = new ContactGridManager(view, null, 0, false /* showAnonymousAvatar */);
    boolean isInMultiWindowMode = getActivity().isInMultiWindowMode();
    contactGridManager.onMultiWindowModeChanged(isInMultiWindowMode);

    Fragment answerMethod =
        getChildFragmentManager().findFragmentById(R.id.answer_method_container);
    if (AnswerMethodFactory.needsReplacement(answerMethod)) {
      getChildFragmentManager()
          .beginTransaction()
          .replace(
              R.id.answer_method_container, AnswerMethodFactory.createAnswerMethod(getActivity()))
          .commitNow();
    }

    answerScreenDelegate =
        FragmentUtils.getParentUnsafe(this, AnswerScreenDelegateFactory.class)
            .newAnswerScreenDelegate(this);

    initSecondaryButton();
    initChips();

    int flags = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
    if (!isInMultiWindowMode
        && (getActivity().checkSelfPermission(permission.STATUS_BAR)
            == PackageManager.PERMISSION_GRANTED)) {
      LogUtil.i("AnswerFragment.onCreateView", "STATUS_BAR permission granted, disabling nav bar");
      // These flags will suppress the alert that the activity is in full view mode
      // during an incoming call on a fresh system/factory reset of the app
      flags |= STATUS_BAR_DISABLE_BACK | STATUS_BAR_DISABLE_HOME | STATUS_BAR_DISABLE_RECENT;
    }
    view.setSystemUiVisibility(flags);
    if (isVideoCall() || isVideoUpgradeRequest()) {
      if (VideoUtils.hasCameraPermissionAndShownPrivacyToast(getContext())) {
        if (isSelfManagedCamera()) {
          answerVideoCallScreen = new SelfManagedAnswerVideoCallScreen(getCallId(), this, view);
        } else {
          answerVideoCallScreen = new AnswerVideoCallScreen(getCallId(), this, view);
        }
      } else {
        view.findViewById(R.id.videocall_video_off).setVisibility(View.VISIBLE);
      }
    }

    Trace.endSection();
    return view;
  }

  @Override
  public void onAttach(Context context) {
    super.onAttach(context);
    FragmentUtils.checkParent(this, InCallScreenDelegateFactory.class);
  }

  @Override
  public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
    Trace.beginSection("AnswerFragment.onViewCreated");
    super.onViewCreated(view, savedInstanceState);
    createInCallScreenDelegate();
    updateUI();

    if (savedInstanceState == null || !savedInstanceState.getBoolean(STATE_HAS_ANIMATED_ENTRY)) {
      ViewUtil.doOnGlobalLayout(view, this::animateEntry);
    }
    Trace.endSection();
  }

  @Override
  public void onResume() {
    Trace.beginSection("AnswerFragment.onResume");
    super.onResume();
    LogUtil.i("AnswerFragment.onResume", null);
    restoreSwipeHintTexts();
    inCallScreenDelegate.onInCallScreenResumed();
    Trace.endSection();
  }

  @Override
  public void onStart() {
    Trace.beginSection("AnswerFragment.onStart");
    super.onStart();
    LogUtil.i("AnswerFragment.onStart", null);

    updateUI();
    if (answerVideoCallScreen != null) {
      answerVideoCallScreen.onVideoScreenStart();
    }
    Trace.endSection();
  }

  @Override
  public void onStop() {
    Trace.beginSection("AnswerFragment.onStop");
    super.onStop();
    LogUtil.i("AnswerFragment.onStop", null);

    handler.removeCallbacks(swipeHintRestoreTimer);
    if (answerVideoCallScreen != null) {
      answerVideoCallScreen.onVideoScreenStop();
    }
    Trace.endSection();
  }

  @Override
  public void onPause() {
    Trace.beginSection("AnswerFragment.onPause");
    super.onPause();
    LogUtil.i("AnswerFragment.onPause", null);
    inCallScreenDelegate.onInCallScreenPaused();
    Trace.endSection();
  }

  @Override
  public void onDestroyView() {
    LogUtil.i("AnswerFragment.onDestroyView", null);
    if (answerVideoCallScreen != null) {
      answerVideoCallScreen = null;
    }
    super.onDestroyView();
    inCallScreenDelegate.onInCallScreenUnready();
    answerScreenDelegate.onAnswerScreenUnready();
  }

  @Override
  public void onSaveInstanceState(Bundle bundle) {
    super.onSaveInstanceState(bundle);
    bundle.putBoolean(STATE_HAS_ANIMATED_ENTRY, hasAnimatedEntry);
  }

  private void updateUI() {
    if (getView() == null) {
      return;
    }

    if (primaryInfo != null) {
      updatePrimaryUI();
    }
    if (primaryCallState != null) {
      contactGridManager.setCallState(primaryCallState);
    }
  }

  @Override
  public boolean isRttCall() {
    return getArguments().getBoolean(ARG_IS_RTT_CALL);
  }

  @Override
  public boolean isVideoCall() {
    return getArguments().getBoolean(ARG_IS_VIDEO_CALL);
  }

  public boolean isSelfManagedCamera() {
    return getArguments().getBoolean(ARG_IS_SELF_MANAGED_CAMERA);
  }

  @Override
  public void onAnswerProgressUpdate(@FloatRange(from = -1f, to = 1f) float answerProgress) {
    // Fade and scale contact name and video call text
    float startDelay = .25f;
    // Header progress is zero over positiveAdjustedProgress = [0, startDelay],
    // linearly increases over (startDelay, 1] until reaching 1 when positiveAdjustedProgress = 1
    float headerProgress = Math.max(0, (Math.abs(answerProgress) - 1) / (1 - startDelay) + 1);
    fadeToward(contactGridManager.getContainerView(), 1 - headerProgress);
    scaleToward(contactGridManager.getContainerView(), MathUtil.lerp(1f, .75f, headerProgress));

    if (Math.abs(answerProgress) >= .0001) {
      affordanceHolderLayout.animateHideLeftRightIcon();
      handler.removeCallbacks(swipeHintRestoreTimer);
      restoreSwipeHintTexts();
    }
  }

  @Override
  public void answerFromMethod() {
    acceptCallByUser(false /* answerVideoAsAudio */);
  }

  @Override
  public void rejectFromMethod() {
    rejectCall();
  }

  @Override
  public void resetAnswerProgress() {
    affordanceHolderLayout.reset(true);
  }

  private void animateEntry(@NonNull View rootView) {
    if (!isAdded()) {
      LogUtil.i(
          "AnswerFragment.animateEntry",
          "Not currently added to Activity. Will not start entry animation.");
      return;
    }
    contactGridManager.getContainerView().setAlpha(0f);
    Animator alpha =
        ObjectAnimator.ofFloat(contactGridManager.getContainerView(), View.ALPHA, 0, 1);
    Animator topRow = createTranslation(rootView.findViewById(R.id.contactgrid_top_row));
    Animator contactName = createTranslation(rootView.findViewById(R.id.contactgrid_contact_name));
    Animator bottomRow = createTranslation(rootView.findViewById(R.id.contactgrid_bottom_row));
    Animator important = createTranslation(importanceBadge);
    Animator dataContainer = createTranslation(rootView.findViewById(R.id.incall_data_container));

    AnimatorSet animatorSet = new AnimatorSet();
    AnimatorSet.Builder builder = animatorSet.play(alpha);
    builder.with(topRow).with(contactName).with(bottomRow).with(important).with(dataContainer);
    if (isShowingLocationUi()) {
      builder.with(createTranslation(rootView.findViewById(R.id.incall_location_holder)));
    }
    animatorSet.setDuration(
        rootView.getResources().getInteger(R.integer.answer_animate_entry_millis));
    animatorSet.addListener(
        new AnimatorListenerAdapter() {
          @Override
          public void onAnimationEnd(Animator animation) {
            hasAnimatedEntry = true;
          }
        });
    animatorSet.start();
  }

  private ObjectAnimator createTranslation(View view) {
    float translationY = view.getTop() * 0.5f;
    ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, translationY, 0);
    animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
    return animator;
  }

  private void acceptCallByUser(boolean answerVideoAsAudio) {
    LogUtil.i("AnswerFragment.acceptCallByUser", answerVideoAsAudio ? " answerVideoAsAudio" : "");
    if (!buttonAcceptClicked) {
      answerScreenDelegate.onAnswer(answerVideoAsAudio);
      buttonAcceptClicked = true;
    }
  }

  private void rejectCall() {
    LogUtil.i("AnswerFragment.rejectCall", null);
    if (!buttonRejectClicked) {
      Context context = getContext();
      if (context == null) {
        LogUtil.w(
            "AnswerFragment.rejectCall",
            "Null context when rejecting call. Logger call was skipped");
      } else {
        Logger.get(context).logImpression(Type.REJECT_INCOMING_CALL_FROM_ANSWER_SCREEN);
      }
      buttonRejectClicked = true;
      answerScreenDelegate.onReject();
    }
  }

  private void restoreSwipeHintTexts() {
    if (getAnswerMethod() != null) {
      if (allowAnswerAndRelease()) {
        if (hasCallOnHold()) {
          getAnswerMethod()
              .setHintText(getText(R.string.call_incoming_default_label_answer_and_release_third));
        } else if (primaryCallState.supportsCallOnHold()) {
          getAnswerMethod()
              .setHintText(getText(R.string.call_incoming_default_label_answer_and_release_second));
        }
      } else {
        getAnswerMethod().setHintText(null);
      }
    }
  }

  private void showMessageMenu() {
    LogUtil.i("AnswerFragment.showMessageMenu", "Show sms menu.");
    if (getContext() == null || isDetached() || getChildFragmentManager().isDestroyed()) {
      return;
    }

    textResponsesFragment = SmsBottomSheetFragment.newInstance(textResponses);
    textResponsesFragment.show(getChildFragmentManager(), null);
    secondaryButton
        .animate()
        .alpha(0)
        .withEndAction(
            new Runnable() {
              @Override
              public void run() {
                affordanceHolderLayout.reset(false);
                secondaryButton.animate().alpha(1);
              }
            });

    TelecomUtil.silenceRinger(getContext());
  }

  @Override
  public InCallUiLock acquireInCallUiLock(String tag) {
    return answerScreenDelegate.acquireInCallUiLock(tag);
  }

  @Override
  public void smsSelected(@Nullable CharSequence text) {
    LogUtil.i("AnswerFragment.smsSelected", null);
    textResponsesFragment = null;

    if (text == null) {
      createCustomSmsDialogFragment = CreateCustomSmsDialogFragment.newInstance();
      createCustomSmsDialogFragment.show(getChildFragmentManager(), null);
      return;
    }

    if (primaryCallState != null && canRejectCallWithSms()) {
      rejectCall();
      answerScreenDelegate.onRejectCallWithMessage(text.toString());
    }
  }

  @Override
  public void smsDismissed() {
    LogUtil.i("AnswerFragment.smsDismissed", null);
    textResponsesFragment = null;
  }

  @Override
  public void customSmsCreated(@NonNull CharSequence text) {
    LogUtil.i("AnswerFragment.customSmsCreated", null);
    createCustomSmsDialogFragment = null;
    if (primaryCallState != null && canRejectCallWithSms()) {
      rejectCall();
      answerScreenDelegate.onRejectCallWithMessage(text.toString());
    }
  }

  @Override
  public void customSmsDismissed() {
    LogUtil.i("AnswerFragment.customSmsDismissed", null);
    createCustomSmsDialogFragment = null;
  }

  private boolean canRejectCallWithSms() {
    return primaryCallState != null
        && !(primaryCallState.state() == DialerCallState.DISCONNECTED
            || primaryCallState.state() == DialerCallState.DISCONNECTING
            || primaryCallState.state() == DialerCallState.IDLE);
  }

  private void createInCallScreenDelegate() {
    inCallScreenDelegate =
        FragmentUtils.getParentUnsafe(this, InCallScreenDelegateFactory.class)
            .newInCallScreenDelegate();
    Assert.isNotNull(inCallScreenDelegate);
    inCallScreenDelegate.onInCallScreenDelegateInit(this);
    inCallScreenDelegate.onInCallScreenReady();
  }

  private void updateImportanceBadgeVisibility() {
    if (!isAdded() || getView() == null) {
      return;
    }

    if (!getResources().getBoolean(R.bool.answer_important_call_allowed) || primaryInfo.isSpam()) {
      importanceBadge.setVisibility(View.GONE);
      return;
    }

    MultimediaData multimediaData = getSessionData();
    boolean showImportant = multimediaData != null && multimediaData.isImportant();
    TransitionManager.beginDelayedTransition((ViewGroup) importanceBadge.getParent());
    // TODO (keyboardr): Change this back to being View.INVISIBLE once mocks are available to
    // properly handle smaller screens
    importanceBadge.setVisibility(showImportant ? View.VISIBLE : View.GONE);
  }

  @Nullable
  private MultimediaData getSessionData() {
    if (primaryInfo == null) {
      return null;
    }
    if (isVideoUpgradeRequest()) {
      return null;
    }
    return primaryInfo.multimediaData();
  }

  /** Shows the Avatar image if available. */
  public static class AvatarFragment extends Fragment implements AvatarPresenter {

    private ImageView avatarImageView;

    @Nullable
    @Override
    public View onCreateView(
        LayoutInflater layoutInflater, @Nullable ViewGroup viewGroup, @Nullable Bundle bundle) {
      return layoutInflater.inflate(R.layout.fragment_avatar, viewGroup, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle bundle) {
      super.onViewCreated(view, bundle);
      avatarImageView = ((ImageView) view.findViewById(R.id.contactgrid_avatar));
      FragmentUtils.getParentUnsafe(this, Holder.class).updateAvatar(this);
    }

    @NonNull
    @Override
    public ImageView getAvatarImageView() {
      return avatarImageView;
    }

    @Override
    public int getAvatarSize() {
      return getResources().getDimensionPixelSize(R.dimen.answer_avatar_size);
    }

    @Override
    public boolean shouldShowAnonymousAvatar() {
      return false;
    }
  }
}
