/*
 * Copyright (C) 2013 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.dialer.app;

import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.KeyguardManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.Trace;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract.QuickContact;
import android.speech.RecognizerIntent;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.FloatingActionButton.OnVisibilityChangedListener;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.telecom.PhoneAccount;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.DragEvent;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView.OnScrollListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;
import com.android.contacts.common.dialog.ClearFrequentsDialog;
import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
import com.android.dialer.animation.AnimUtils;
import com.android.dialer.animation.AnimationListenerAdapter;
import com.android.dialer.app.calllog.CallLogActivity;
import com.android.dialer.app.calllog.CallLogAdapter;
import com.android.dialer.app.calllog.CallLogFragment;
import com.android.dialer.app.calllog.CallLogNotificationsService;
import com.android.dialer.app.calllog.IntentProvider;
import com.android.dialer.app.list.DialtactsPagerAdapter;
import com.android.dialer.app.list.DialtactsPagerAdapter.TabIndex;
import com.android.dialer.app.list.DragDropController;
import com.android.dialer.app.list.ListsFragment;
import com.android.dialer.app.list.OldSpeedDialFragment;
import com.android.dialer.app.list.OnDragDropListener;
import com.android.dialer.app.list.OnListFragmentScrolledListener;
import com.android.dialer.app.list.PhoneFavoriteSquareTileView;
import com.android.dialer.app.settings.DialerSettingsActivity;
import com.android.dialer.app.widget.ActionBarController;
import com.android.dialer.app.widget.SearchEditTextLayout;
import com.android.dialer.callcomposer.CallComposerActivity;
import com.android.dialer.calldetails.OldCallDetailsActivity;
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallIntentBuilder;
import com.android.dialer.callintent.CallSpecificAppData;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.UiUtil;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.common.concurrent.ThreadUtil;
import com.android.dialer.compat.CompatUtils;
import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.dialer.constants.ActivityRequestCodes;
import com.android.dialer.contactsfragment.ContactsFragment;
import com.android.dialer.contactsfragment.ContactsFragment.OnContactSelectedListener;
import com.android.dialer.database.Database;
import com.android.dialer.database.DialerDatabaseHelper;
import com.android.dialer.dialpadview.DialpadFragment;
import com.android.dialer.dialpadview.DialpadFragment.DialpadListener;
import com.android.dialer.dialpadview.DialpadFragment.LastOutgoingCallCallback;
import com.android.dialer.duo.DuoComponent;
import com.android.dialer.interactions.PhoneNumberInteraction;
import com.android.dialer.interactions.PhoneNumberInteraction.InteractionErrorCode;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.InteractionEvent;
import com.android.dialer.logging.Logger;
import com.android.dialer.logging.ScreenEvent;
import com.android.dialer.logging.UiAction;
import com.android.dialer.metrics.Metrics;
import com.android.dialer.metrics.MetricsComponent;
import com.android.dialer.performancereport.PerformanceReport;
import com.android.dialer.postcall.PostCall;
import com.android.dialer.precall.PreCall;
import com.android.dialer.proguard.UsedByReflection;
import com.android.dialer.searchfragment.list.NewSearchFragment;
import com.android.dialer.searchfragment.list.NewSearchFragment.SearchFragmentListener;
import com.android.dialer.simulator.Simulator;
import com.android.dialer.simulator.SimulatorComponent;
import com.android.dialer.smartdial.util.SmartDialNameMatcher;
import com.android.dialer.smartdial.util.SmartDialPrefix;
import com.android.dialer.storage.StorageComponent;
import com.android.dialer.telecom.TelecomUtil;
import com.android.dialer.util.DialerUtils;
import com.android.dialer.util.PermissionsUtil;
import com.android.dialer.util.TouchPointManager;
import com.android.dialer.util.TransactionSafeActivity;
import com.android.dialer.util.ViewUtil;
import com.android.dialer.widget.FloatingActionButtonController;
import com.google.common.base.Optional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/** The dialer tab's title is 'phone', a more common name (see strings.xml). */
@UsedByReflection(value = "AndroidManifest-app.xml")
public class DialtactsActivity extends TransactionSafeActivity
    implements View.OnClickListener,
        DialpadFragment.OnDialpadQueryChangedListener,
        OnListFragmentScrolledListener,
        CallLogFragment.HostInterface,
        CallLogAdapter.OnActionModeStateChangedListener,
        ContactsFragment.OnContactsListScrolledListener,
        DialpadFragment.HostInterface,
        OldSpeedDialFragment.HostInterface,
        OnDragDropListener,
        OnPhoneNumberPickerActionListener,
        PopupMenu.OnMenuItemClickListener,
        ViewPager.OnPageChangeListener,
        ActionBarController.ActivityUi,
        PhoneNumberInteraction.InteractionErrorListener,
        PhoneNumberInteraction.DisambigDialogDismissedListener,
        ActivityCompat.OnRequestPermissionsResultCallback,
        DialpadListener,
        SearchFragmentListener,
        OnContactSelectedListener {

  public static final boolean DEBUG = false;
  @VisibleForTesting public static final String TAG_DIALPAD_FRAGMENT = "dialpad";
  private static final String ACTION_SHOW_TAB = "ACTION_SHOW_TAB";
  @VisibleForTesting public static final String EXTRA_SHOW_TAB = "EXTRA_SHOW_TAB";
  public static final String EXTRA_CLEAR_NEW_VOICEMAILS = "EXTRA_CLEAR_NEW_VOICEMAILS";
  private static final String KEY_LAST_TAB = "last_tab";
  private static final String TAG = "DialtactsActivity";
  private static final String KEY_IN_REGULAR_SEARCH_UI = "in_regular_search_ui";
  private static final String KEY_IN_DIALPAD_SEARCH_UI = "in_dialpad_search_ui";
  private static final String KEY_IN_NEW_SEARCH_UI = "in_new_search_ui";
  private static final String KEY_SEARCH_QUERY = "search_query";
  private static final String KEY_DIALPAD_QUERY = "dialpad_query";
  private static final String KEY_FIRST_LAUNCH = "first_launch";
  private static final String KEY_SAVED_LANGUAGE_CODE = "saved_language_code";
  private static final String KEY_WAS_CONFIGURATION_CHANGE = "was_configuration_change";
  private static final String KEY_IS_DIALPAD_SHOWN = "is_dialpad_shown";
  private static final String KEY_FAB_VISIBLE = "fab_visible";
  private static final String TAG_NEW_SEARCH_FRAGMENT = "new_search";
  private static final String TAG_FAVORITES_FRAGMENT = "favorites";
  /** Just for backward compatibility. Should behave as same as {@link Intent#ACTION_DIAL}. */
  private static final String ACTION_TOUCH_DIALER = "com.android.phone.action.TOUCH_DIALER";

  private static final int FAB_SCALE_IN_DELAY_MS = 300;

  /**
   * Minimum time the history tab must have been selected for it to be marked as seen in onStop()
   */
  private static final long HISTORY_TAB_SEEN_TIMEOUT = TimeUnit.SECONDS.toMillis(3);

  private static Optional<Boolean> voiceSearchEnabledForTest = Optional.absent();

  /** Fragment containing the dialpad that slides into view */
  protected DialpadFragment dialpadFragment;

  /** Root layout of DialtactsActivity */
  private CoordinatorLayout parentLayout;

  /** new Fragment for search phone numbers using the keyboard and the dialpad. */
  private NewSearchFragment newSearchFragment;

  /** Animation that slides in. */
  private Animation slideIn;

  /** Animation that slides out. */
  private Animation slideOut;
  /** Fragment containing the speed dial list, call history list, and all contacts list. */
  private ListsFragment listsFragment;
  /**
   * Tracks whether onSaveInstanceState has been called. If true, no fragment transactions can be
   * commited.
   */
  private boolean stateSaved;

  private boolean isKeyboardOpen;
  private boolean inNewSearch;
  private boolean isRestarting;
  private boolean inDialpadSearch;
  private boolean inRegularSearch;
  private boolean clearSearchOnPause;
  private boolean isDialpadShown;
  /** Whether or not the device is in landscape orientation. */
  private boolean isLandscape;
  /** True if the dialpad is only temporarily showing due to being in call */
  private boolean inCallDialpadUp;
  /** True when this activity has been launched for the first time. */
  private boolean firstLaunch;
  /**
   * Search query to be applied to the SearchView in the ActionBar once onCreateOptionsMenu has been
   * called.
   */
  private String pendingSearchViewQuery;

  private PopupMenu overflowMenu;
  private EditText searchView;
  private SearchEditTextLayout searchEditTextLayout;
  private View voiceSearchButton;
  private String searchQuery;
  private String dialpadQuery;
  private DialerDatabaseHelper dialerDatabaseHelper;
  private DragDropController dragDropController;
  private ActionBarController actionBarController;
  private FloatingActionButtonController floatingActionButtonController;
  private String savedLanguageCode;
  private boolean wasConfigurationChange;
  private long timeTabSelected;

  public boolean isMultiSelectModeEnabled;

  private boolean isLastTabEnabled;

  AnimationListenerAdapter slideInListener =
      new AnimationListenerAdapter() {
        @Override
        public void onAnimationEnd(Animation animation) {
          maybeEnterSearchUi();
        }
      };
  /** Listener for after slide out animation completes on dialer fragment. */
  AnimationListenerAdapter slideOutListener =
      new AnimationListenerAdapter() {
        @Override
        public void onAnimationEnd(Animation animation) {
          commitDialpadFragmentHide();
        }
      };
  /** Listener used to send search queries to the phone search fragment. */
  private final TextWatcher phoneSearchQueryTextListener =
      new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
          final String newText = s.toString();
          if (newText.equals(searchQuery)) {
            // If the query hasn't changed (perhaps due to activity being destroyed
            // and restored, or user launching the same DIAL intent twice), then there is
            // no need to do anything here.
            return;
          }

          if (count != 0) {
            PerformanceReport.recordClick(UiAction.Type.TEXT_CHANGE_WITH_INPUT);
          }

          LogUtil.v("DialtactsActivity.onTextChanged", "called with new query: " + newText);
          LogUtil.v("DialtactsActivity.onTextChanged", "previous query: " + searchQuery);
          searchQuery = newText;

          // Show search fragment only when the query string is changed to non-empty text.
          if (!TextUtils.isEmpty(newText)) {
            // Call enterSearchUi only if we are switching search modes, or showing a search
            // fragment for the first time.
            final boolean sameSearchMode =
                (isDialpadShown && inDialpadSearch) || (!isDialpadShown && inRegularSearch);
            if (!sameSearchMode) {
              enterSearchUi(isDialpadShown, searchQuery, true /* animate */);
            }
          }

          if (newSearchFragment != null && newSearchFragment.isVisible()) {
            newSearchFragment.setQuery(searchQuery, getCallInitiationType());
          }
        }

        @Override
        public void afterTextChanged(Editable s) {}
      };
  /** Open the search UI when the user clicks on the search box. */
  private final View.OnClickListener searchViewOnClickListener =
      new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          if (!isInSearchUi()) {
            PerformanceReport.recordClick(UiAction.Type.OPEN_SEARCH);
            actionBarController.onSearchBoxTapped();
            enterSearchUi(
                false /* smartDialSearch */, searchView.getText().toString(), true /* animate */);
          }
        }
      };

  private int actionBarHeight;
  private int previouslySelectedTabIndex;

  /**
   * The text returned from a voice search query. Set in {@link #onActivityResult} and used in
   * {@link #onResume()} to populate the search box.
   */
  private String voiceSearchQuery;

  /**
   * @param tab the TAB_INDEX_* constant in {@link ListsFragment}
   * @return A intent that will open the DialtactsActivity into the specified tab. The intent for
   *     each tab will be unique.
   */
  public static Intent getShowTabIntent(Context context, int tab) {
    Intent intent = new Intent(context, DialtactsActivity.class);
    intent.setAction(ACTION_SHOW_TAB);
    intent.putExtra(DialtactsActivity.EXTRA_SHOW_TAB, tab);
    intent.setData(
        new Uri.Builder()
            .scheme("intent")
            .authority(context.getPackageName())
            .appendPath(TAG)
            .appendQueryParameter(DialtactsActivity.EXTRA_SHOW_TAB, String.valueOf(tab))
            .build());

    return intent;
  }

  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
      TouchPointManager.getInstance().setPoint((int) ev.getRawX(), (int) ev.getRawY());
    }
    return super.dispatchTouchEvent(ev);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    Trace.beginSection(TAG + " onCreate");
    LogUtil.enterBlock("DialtactsActivity.onCreate");
    super.onCreate(savedInstanceState);

    firstLaunch = true;
    isLastTabEnabled = ConfigProviderBindings.get(this).getBoolean("last_tab_enabled", false);

    final Resources resources = getResources();
    actionBarHeight = resources.getDimensionPixelSize(R.dimen.action_bar_height_large);

    Trace.beginSection(TAG + " setContentView");
    setContentView(R.layout.dialtacts_activity);
    Trace.endSection();
    getWindow().setBackgroundDrawable(null);

    Trace.beginSection(TAG + " setup Views");
    final ActionBar actionBar = getActionBarSafely();
    actionBar.setCustomView(R.layout.search_edittext);
    actionBar.setDisplayShowCustomEnabled(true);
    actionBar.setBackgroundDrawable(null);

    searchEditTextLayout = actionBar.getCustomView().findViewById(R.id.search_view_container);

    actionBarController = new ActionBarController(this, searchEditTextLayout);

    searchView = searchEditTextLayout.findViewById(R.id.search_view);
    searchView.addTextChangedListener(phoneSearchQueryTextListener);
    searchView.setHint(getSearchBoxHint());

    voiceSearchButton = searchEditTextLayout.findViewById(R.id.voice_search_button);
    searchEditTextLayout
        .findViewById(R.id.search_box_collapsed)
        .setOnClickListener(searchViewOnClickListener);
    searchEditTextLayout
        .findViewById(R.id.search_back_button)
        .setOnClickListener(v -> exitSearchUi());

    isLandscape =
        getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
    previouslySelectedTabIndex = DialtactsPagerAdapter.TAB_INDEX_SPEED_DIAL;
    FloatingActionButton floatingActionButton = findViewById(R.id.floating_action_button);
    floatingActionButton.setOnClickListener(this);
    floatingActionButtonController = new FloatingActionButtonController(this, floatingActionButton);

    ImageButton optionsMenuButton =
        searchEditTextLayout.findViewById(R.id.dialtacts_options_menu_button);
    optionsMenuButton.setOnClickListener(this);
    overflowMenu = buildOptionsMenu(optionsMenuButton);
    optionsMenuButton.setOnTouchListener(overflowMenu.getDragToOpenListener());

    // Add the favorites fragment but only if savedInstanceState is null. Otherwise the
    // fragment manager is responsible for recreating it.
    if (savedInstanceState == null) {
      getFragmentManager()
          .beginTransaction()
          .add(R.id.dialtacts_frame, new ListsFragment(), TAG_FAVORITES_FRAGMENT)
          .commit();
    } else {
      searchQuery = savedInstanceState.getString(KEY_SEARCH_QUERY);
      dialpadQuery = savedInstanceState.getString(KEY_DIALPAD_QUERY);
      inRegularSearch = savedInstanceState.getBoolean(KEY_IN_REGULAR_SEARCH_UI);
      inDialpadSearch = savedInstanceState.getBoolean(KEY_IN_DIALPAD_SEARCH_UI);
      inNewSearch = savedInstanceState.getBoolean(KEY_IN_NEW_SEARCH_UI);
      firstLaunch = savedInstanceState.getBoolean(KEY_FIRST_LAUNCH);
      savedLanguageCode = savedInstanceState.getString(KEY_SAVED_LANGUAGE_CODE);
      wasConfigurationChange = savedInstanceState.getBoolean(KEY_WAS_CONFIGURATION_CHANGE);
      isDialpadShown = savedInstanceState.getBoolean(KEY_IS_DIALPAD_SHOWN);
      floatingActionButtonController.setVisible(savedInstanceState.getBoolean(KEY_FAB_VISIBLE));
      actionBarController.restoreInstanceState(savedInstanceState);
    }

    final boolean isLayoutRtl = ViewUtil.isRtl();
    if (isLandscape) {
      slideIn =
          AnimationUtils.loadAnimation(
              this, isLayoutRtl ? R.anim.dialpad_slide_in_left : R.anim.dialpad_slide_in_right);
      slideOut =
          AnimationUtils.loadAnimation(
              this, isLayoutRtl ? R.anim.dialpad_slide_out_left : R.anim.dialpad_slide_out_right);
    } else {
      slideIn = AnimationUtils.loadAnimation(this, R.anim.dialpad_slide_in_bottom);
      slideOut = AnimationUtils.loadAnimation(this, R.anim.dialpad_slide_out_bottom);
    }

    slideIn.setInterpolator(AnimUtils.EASE_IN);
    slideOut.setInterpolator(AnimUtils.EASE_OUT);

    slideIn.setAnimationListener(slideInListener);
    slideOut.setAnimationListener(slideOutListener);

    parentLayout = (CoordinatorLayout) findViewById(R.id.dialtacts_mainlayout);
    parentLayout.setOnDragListener(new LayoutOnDragListener());
    ViewUtil.doOnGlobalLayout(
        floatingActionButton,
        view -> {
          int screenWidth = parentLayout.getWidth();
          floatingActionButtonController.setScreenWidth(screenWidth);
          floatingActionButtonController.align(getFabAlignment(), false /* animate */);
        });

    Trace.endSection();

    Trace.beginSection(TAG + " initialize smart dialing");
    dialerDatabaseHelper = Database.get(this).getDatabaseHelper(this);
    SmartDialPrefix.initializeNanpSettings(this);
    Trace.endSection();

    Trace.endSection();

    updateSearchFragmentPosition();
  }

  @NonNull
  private ActionBar getActionBarSafely() {
    return Assert.isNotNull(getSupportActionBar());
  }

  @Override
  protected void onResume() {
    LogUtil.enterBlock("DialtactsActivity.onResume");
    Trace.beginSection(TAG + " onResume");
    super.onResume();

    // Some calls may not be recorded (eg. from quick contact),
    // so we should restart recording after these calls. (Recorded call is stopped)
    PostCall.restartPerformanceRecordingIfARecentCallExist(this);
    if (!PerformanceReport.isRecording()) {
      PerformanceReport.startRecording();
    }

    stateSaved = false;
    if (firstLaunch) {
      LogUtil.i("DialtactsActivity.onResume", "mFirstLaunch true, displaying fragment");
      displayFragment(getIntent());
    } else if (!phoneIsInUse() && inCallDialpadUp) {
      LogUtil.i("DialtactsActivity.onResume", "phone not in use, hiding dialpad fragment");
      hideDialpadFragment(false, true);
      inCallDialpadUp = false;
    } else if (isDialpadShown) {
      LogUtil.i("DialtactsActivity.onResume", "showing dialpad on resume");
      showDialpadFragment(false);
    } else {
      PostCall.promptUserForMessageIfNecessary(this, parentLayout);
    }

    // On M the fragment manager does not restore the hidden state of a fragment from
    // savedInstanceState so it must be hidden again.
    if (!isDialpadShown && dialpadFragment != null && !dialpadFragment.isHidden()) {
      LogUtil.i(
          "DialtactsActivity.onResume", "mDialpadFragment attached but not hidden, forcing hide");
      getFragmentManager().beginTransaction().hide(dialpadFragment).commit();
    }

    // If there was a voice query result returned in the {@link #onActivityResult} callback, it
    // will have been stashed in mVoiceSearchQuery since the search results fragment cannot be
    // shown until onResume has completed.  Active the search UI and set the search term now.
    if (!TextUtils.isEmpty(voiceSearchQuery)) {
      actionBarController.onSearchBoxTapped();
      searchView.setText(voiceSearchQuery);
      voiceSearchQuery = null;
    }

    if (isRestarting) {
      // This is only called when the activity goes from resumed -> paused -> resumed, so it
      // will not cause an extra view to be sent out on rotation
      if (isDialpadShown) {
        Logger.get(this).logScreenView(ScreenEvent.Type.DIALPAD, this);
      }
      isRestarting = false;
    }

    prepareVoiceSearchButton();

    // Start the thread that updates the smart dial database if
    // (1) the activity is not recreated with a new configuration, or
    // (2) the activity is recreated with a new configuration but the change is a language change.
    boolean isLanguageChanged =
        !CompatUtils.getLocale(this).getISO3Language().equals(savedLanguageCode);
    if (!wasConfigurationChange || isLanguageChanged) {
      dialerDatabaseHelper.startSmartDialUpdateThread(/* forceUpdate = */ isLanguageChanged);
    }

    if (isDialpadShown) {
      floatingActionButtonController.scaleOut();
    } else {
      floatingActionButtonController.align(getFabAlignment(), false /* animate */);
    }

    if (firstLaunch) {
      // Only process the Intent the first time onResume() is called after receiving it
      if (Calls.CONTENT_TYPE.equals(getIntent().getType())) {
        // Externally specified extras take precedence to EXTRA_SHOW_TAB, which is only
        // used internally.
        final Bundle extras = getIntent().getExtras();
        if (extras != null && extras.getInt(Calls.EXTRA_CALL_TYPE_FILTER) == Calls.VOICEMAIL_TYPE) {
          listsFragment.showTab(DialtactsPagerAdapter.TAB_INDEX_VOICEMAIL);
          Logger.get(this).logImpression(DialerImpression.Type.VVM_NOTIFICATION_CLICKED);
        } else {
          listsFragment.showTab(DialtactsPagerAdapter.TAB_INDEX_HISTORY);
        }
      } else if (getIntent().hasExtra(EXTRA_SHOW_TAB)) {
        int index =
            getIntent().getIntExtra(EXTRA_SHOW_TAB, DialtactsPagerAdapter.TAB_INDEX_SPEED_DIAL);
        if (index < listsFragment.getTabCount()) {
          // Hide dialpad since this is an explicit intent to show a specific tab, which is coming
          // from missed call or voicemail notification.
          hideDialpadFragment(false, false);
          exitSearchUi();
          listsFragment.showTab(index);
        }
      }

      if (getIntent().getBooleanExtra(EXTRA_CLEAR_NEW_VOICEMAILS, false)) {
        LogUtil.i("DialtactsActivity.onResume", "clearing all new voicemails");
        CallLogNotificationsService.markAllNewVoicemailsAsOld(this);
      }
      // add 1 sec delay to get memory snapshot so that dialer wont react slowly on resume.
      ThreadUtil.postDelayedOnUiThread(
          () ->
              MetricsComponent.get(this)
                  .metrics()
                  .recordMemory(Metrics.DIALTACTS_ON_RESUME_MEMORY_EVENT_NAME),
          1000);
    }

    firstLaunch = false;

    setSearchBoxHint();
    timeTabSelected = SystemClock.elapsedRealtime();

    Trace.endSection();
  }

  @Override
  protected void onRestart() {
    super.onRestart();
    isRestarting = true;
  }

  @Override
  protected void onPause() {
    if (clearSearchOnPause) {
      hideDialpadAndSearchUi();
      clearSearchOnPause = false;
    }
    if (slideOut.hasStarted() && !slideOut.hasEnded()) {
      commitDialpadFragmentHide();
    }
    super.onPause();
  }

  @Override
  protected void onStop() {
    super.onStop();
    boolean timeoutElapsed =
        SystemClock.elapsedRealtime() - timeTabSelected >= HISTORY_TAB_SEEN_TIMEOUT;
    boolean isOnHistoryTab =
        listsFragment.getCurrentTabIndex() == DialtactsPagerAdapter.TAB_INDEX_HISTORY;
    if (isOnHistoryTab
        && timeoutElapsed
        && !isChangingConfigurations()
        && !getSystemService(KeyguardManager.class).isKeyguardLocked()) {
      listsFragment.markMissedCallsAsReadAndRemoveNotifications();
    }
    StorageComponent.get(this)
        .unencryptedSharedPrefs()
        .edit()
        .putInt(KEY_LAST_TAB, listsFragment.getCurrentTabIndex())
        .apply();
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    LogUtil.enterBlock("DialtactsActivity.onSaveInstanceState");
    super.onSaveInstanceState(outState);
    outState.putString(KEY_SEARCH_QUERY, searchQuery);
    outState.putString(KEY_DIALPAD_QUERY, dialpadQuery);
    outState.putString(KEY_SAVED_LANGUAGE_CODE, CompatUtils.getLocale(this).getISO3Language());
    outState.putBoolean(KEY_IN_REGULAR_SEARCH_UI, inRegularSearch);
    outState.putBoolean(KEY_IN_DIALPAD_SEARCH_UI, inDialpadSearch);
    outState.putBoolean(KEY_IN_NEW_SEARCH_UI, inNewSearch);
    outState.putBoolean(KEY_FIRST_LAUNCH, firstLaunch);
    outState.putBoolean(KEY_IS_DIALPAD_SHOWN, isDialpadShown);
    outState.putBoolean(KEY_FAB_VISIBLE, floatingActionButtonController.isVisible());
    outState.putBoolean(KEY_WAS_CONFIGURATION_CHANGE, isChangingConfigurations());
    actionBarController.saveInstanceState(outState);
    stateSaved = true;
  }

  @Override
  public void onAttachFragment(final Fragment fragment) {
    LogUtil.i("DialtactsActivity.onAttachFragment", "fragment: %s", fragment);
    if (fragment instanceof DialpadFragment) {
      dialpadFragment = (DialpadFragment) fragment;
    } else if (fragment instanceof ListsFragment) {
      listsFragment = (ListsFragment) fragment;
      listsFragment.addOnPageChangeListener(this);
    } else if (fragment instanceof NewSearchFragment) {
      newSearchFragment = (NewSearchFragment) fragment;
      updateSearchFragmentPosition();
    }
  }

  protected void handleMenuSettings() {
    final Intent intent = new Intent(this, DialerSettingsActivity.class);
    startActivity(intent);
  }

  public boolean isListsFragmentVisible() {
    return listsFragment.getUserVisibleHint();
  }

  @Override
  public void onClick(View view) {
    int resId = view.getId();
    if (resId == R.id.floating_action_button) {
      if (!isDialpadShown) {
        LogUtil.i(
            "DialtactsActivity.onClick", "floating action button clicked, going to show dialpad");
        PerformanceReport.recordClick(UiAction.Type.OPEN_DIALPAD);
        inCallDialpadUp = false;
        showDialpadFragment(true);
        PostCall.closePrompt();
      } else {
        LogUtil.i(
            "DialtactsActivity.onClick",
            "floating action button clicked, but dialpad is already showing");
      }
    } else if (resId == R.id.voice_search_button) {
      try {
        startActivityForResult(
            new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH),
            ActivityRequestCodes.DIALTACTS_VOICE_SEARCH);
      } catch (ActivityNotFoundException e) {
        Toast.makeText(
                DialtactsActivity.this, R.string.voice_search_not_available, Toast.LENGTH_SHORT)
            .show();
      }
    } else if (resId == R.id.dialtacts_options_menu_button) {
      overflowMenu.show();
    } else {
      Assert.fail("Unexpected onClick event from " + view);
    }
  }

  @Override
  public boolean onMenuItemClick(MenuItem item) {
    if (!isSafeToCommitTransactions()) {
      return true;
    }

    int resId = item.getItemId();
    if (resId == R.id.menu_history) {
      PerformanceReport.recordClick(UiAction.Type.OPEN_CALL_HISTORY);
      final Intent intent = new Intent(this, CallLogActivity.class);
      startActivity(intent);
    } else if (resId == R.id.menu_clear_frequents) {
      ClearFrequentsDialog.show(getFragmentManager());
      Logger.get(this).logScreenView(ScreenEvent.Type.CLEAR_FREQUENTS, this);
      return true;
    } else if (resId == R.id.menu_call_settings) {
      handleMenuSettings();
      Logger.get(this).logScreenView(ScreenEvent.Type.SETTINGS, this);
      return true;
    }
    return false;
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    LogUtil.i(
        "DialtactsActivity.onActivityResult",
        "requestCode:%d, resultCode:%d",
        requestCode,
        resultCode);
    if (requestCode == ActivityRequestCodes.DIALTACTS_VOICE_SEARCH) {
      if (resultCode == RESULT_OK) {
        final ArrayList<String> matches =
            data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
        if (matches.size() > 0) {
          voiceSearchQuery = matches.get(0);
        } else {
          LogUtil.i("DialtactsActivity.onActivityResult", "voice search - nothing heard");
        }
      } else {
        LogUtil.e("DialtactsActivity.onActivityResult", "voice search failed");
      }
    } else if (requestCode == ActivityRequestCodes.DIALTACTS_CALL_COMPOSER) {
      if (resultCode == RESULT_FIRST_USER) {
        LogUtil.i(
            "DialtactsActivity.onActivityResult", "returned from call composer, error occurred");
        String message =
            getString(
                R.string.call_composer_connection_failed,
                data.getStringExtra(CallComposerActivity.KEY_CONTACT_NAME));
        Snackbar.make(parentLayout, message, Snackbar.LENGTH_LONG).show();
      } else {
        LogUtil.i("DialtactsActivity.onActivityResult", "returned from call composer, no error");
      }
    } else if (requestCode == ActivityRequestCodes.DIALTACTS_CALL_DETAILS) {
      if (resultCode == RESULT_OK
          && data != null
          && data.getBooleanExtra(OldCallDetailsActivity.EXTRA_HAS_ENRICHED_CALL_DATA, false)) {
        String number = data.getStringExtra(OldCallDetailsActivity.EXTRA_PHONE_NUMBER);
        int snackbarDurationMillis = 5_000;
        Snackbar.make(parentLayout, getString(R.string.ec_data_deleted), snackbarDurationMillis)
            .setAction(
                R.string.view_conversation,
                v -> startActivity(IntentProvider.getSendSmsIntentProvider(number).getIntent(this)))
            .setActionTextColor(getResources().getColor(R.color.dialer_snackbar_action_text_color))
            .show();
      }
    } else if (requestCode == ActivityRequestCodes.DIALTACTS_DUO) {
      // We just returned from starting Duo for a task. Reload our reachability data since it
      // may have changed after a user finished activating Duo.
      DuoComponent.get(this).getDuo().reloadReachability(this);
    }
    super.onActivityResult(requestCode, resultCode, data);
  }

  /**
   * Update the number of unread voicemails (potentially other tabs) displayed next to the tab icon.
   */
  public void updateTabUnreadCounts() {
    listsFragment.updateTabUnreadCounts();
  }

  /**
   * Initiates a fragment transaction to show the dialpad fragment. Animations and other visual
   * updates are handled by a callback which is invoked after the dialpad fragment is shown.
   *
   * @see #onDialpadShown
   */
  private void showDialpadFragment(boolean animate) {
    LogUtil.i("DialtactActivity.showDialpadFragment", "animate: %b", animate);
    if (isDialpadShown) {
      LogUtil.i("DialtactsActivity.showDialpadFragment", "dialpad already shown");
      return;
    }
    if (stateSaved) {
      LogUtil.i("DialtactsActivity.showDialpadFragment", "state already saved");
      return;
    }
    isDialpadShown = true;

    listsFragment.setUserVisibleHint(false);

    final FragmentTransaction ft = getFragmentManager().beginTransaction();
    if (dialpadFragment == null) {
      dialpadFragment = new DialpadFragment();
      ft.add(R.id.dialtacts_container, dialpadFragment, TAG_DIALPAD_FRAGMENT);
    } else {
      ft.show(dialpadFragment);
    }

    dialpadFragment.setAnimate(animate);
    Logger.get(this).logScreenView(ScreenEvent.Type.DIALPAD, this);
    ft.commit();

    if (animate) {
      floatingActionButtonController.scaleOut();
      maybeEnterSearchUi();
    } else {
      floatingActionButtonController.scaleOut();
      maybeEnterSearchUi();
    }
    actionBarController.onDialpadUp();

    Assert.isNotNull(listsFragment.getView()).animate().alpha(0).withLayer();

    // adjust the title, so the user will know where we're at when the activity start/resumes.
    setTitle(R.string.launcherDialpadActivityLabel);
  }

  @Override
  public void getLastOutgoingCall(LastOutgoingCallCallback callback) {
    DialerExecutorComponent.get(this)
        .dialerExecutorFactory()
        .createUiTaskBuilder(
            getFragmentManager(), "Query last phone number", Calls::getLastOutgoingCall)
        .onSuccess(output -> callback.lastOutgoingCall(output))
        .build()
        .executeParallel(this);
  }

  /** Callback from child DialpadFragment when the dialpad is shown. */
  @Override
  public void onDialpadShown() {
    LogUtil.enterBlock("DialtactsActivity.onDialpadShown");
    Assert.isNotNull(dialpadFragment);
    if (dialpadFragment.getAnimate()) {
      Assert.isNotNull(dialpadFragment.getView()).startAnimation(slideIn);
    } else {
      dialpadFragment.setYFraction(0);
    }

    updateSearchFragmentPosition();
  }

  @Override
  public void onCallPlacedFromDialpad() {
    clearSearchOnPause = true;
  }

  @Override
  public void onContactsListScrolled(boolean isDragging) {
    // intentionally empty.
  }

  /**
   * Initiates animations and other visual updates to hide the dialpad. The fragment is hidden in a
   * callback after the hide animation ends.
   *
   * @see #commitDialpadFragmentHide
   */
  private void hideDialpadFragment(boolean animate, boolean clearDialpad) {
    LogUtil.enterBlock("DialtactsActivity.hideDialpadFragment");
    if (dialpadFragment == null || dialpadFragment.getView() == null) {
      return;
    }
    if (clearDialpad) {
      // Temporarily disable accessibility when we clear the dialpad, since it should be
      // invisible and should not announce anything.
      dialpadFragment
          .getDigitsWidget()
          .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
      dialpadFragment.clearDialpad();
      dialpadFragment
          .getDigitsWidget()
          .setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
    }
    if (!isDialpadShown) {
      return;
    }
    isDialpadShown = false;
    dialpadFragment.setAnimate(animate);
    listsFragment.setUserVisibleHint(true);
    listsFragment.sendScreenViewForCurrentPosition();

    updateSearchFragmentPosition();

    floatingActionButtonController.align(getFabAlignment(), animate);
    if (animate) {
      dialpadFragment.getView().startAnimation(slideOut);
    } else {
      commitDialpadFragmentHide();
    }

    actionBarController.onDialpadDown();

    // reset the title to normal.
    setTitle(R.string.launcherActivityLabel);
  }

  /** Finishes hiding the dialpad fragment after any animations are completed. */
  private void commitDialpadFragmentHide() {
    if (!stateSaved && dialpadFragment != null && !dialpadFragment.isHidden() && !isDestroyed()) {
      final FragmentTransaction ft = getFragmentManager().beginTransaction();
      ft.hide(dialpadFragment);
      ft.commit();
    }
    floatingActionButtonController.scaleIn();
  }

  private void updateSearchFragmentPosition() {
    if (newSearchFragment != null) {
      int animationDuration = getResources().getInteger(R.integer.dialpad_slide_in_duration);
      int actionbarHeight = getResources().getDimensionPixelSize(R.dimen.action_bar_height_large);
      int shadowHeight = getResources().getDrawable(R.drawable.search_shadow).getIntrinsicHeight();
      int start = isDialpadShown() ? actionbarHeight - shadowHeight : 0;
      int end = isDialpadShown() ? 0 : actionbarHeight - shadowHeight;
      newSearchFragment.animatePosition(start, end, animationDuration);
    }
  }

  @Override
  public boolean isInSearchUi() {
    return inDialpadSearch || inRegularSearch || inNewSearch;
  }

  @Override
  public boolean hasSearchQuery() {
    return !TextUtils.isEmpty(searchQuery);
  }

  private void setNotInSearchUi() {
    inDialpadSearch = false;
    inRegularSearch = false;
    inNewSearch = false;
  }

  private void hideDialpadAndSearchUi() {
    if (isDialpadShown) {
      hideDialpadFragment(false, true);
    }
    exitSearchUi();
  }

  private void prepareVoiceSearchButton() {
    searchEditTextLayout.setVoiceSearchEnabled(isVoiceSearchEnabled());
    voiceSearchButton.setOnClickListener(this);
  }

  private boolean isVoiceSearchEnabled() {
    if (voiceSearchEnabledForTest.isPresent()) {
      return voiceSearchEnabledForTest.get();
    }
    return canIntentBeHandled(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH));
  }

  public boolean isNearbyPlacesSearchEnabled() {
    return false;
  }

  protected int getSearchBoxHint() {
    return R.string.dialer_hint_find_contact;
  }

  /** Sets the hint text for the contacts search box */
  private void setSearchBoxHint() {
    ((TextView) searchEditTextLayout.findViewById(R.id.search_box_start_search))
        .setHint(getSearchBoxHint());
  }

  protected OptionsPopupMenu buildOptionsMenu(View invoker) {
    final OptionsPopupMenu popupMenu = new OptionsPopupMenu(this, invoker);
    popupMenu.inflate(R.menu.dialtacts_options);
    popupMenu.setOnMenuItemClickListener(this);
    return popupMenu;
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    if (pendingSearchViewQuery != null) {
      searchView.setText(pendingSearchViewQuery);
      pendingSearchViewQuery = null;
    }
    if (actionBarController != null) {
      actionBarController.restoreActionBarOffset();
    }
    return false;
  }

  /**
   * Returns true if the intent is due to hitting the green send key (hardware call button:
   * KEYCODE_CALL) while in a call.
   *
   * @param intent the intent that launched this activity
   * @return true if the intent is due to hitting the green send key while in a call
   */
  private boolean isSendKeyWhileInCall(Intent intent) {
    // If there is a call in progress and the user launched the dialer by hitting the call
    // button, go straight to the in-call screen.
    final boolean callKey = Intent.ACTION_CALL_BUTTON.equals(intent.getAction());

    // When KEYCODE_CALL event is handled it dispatches an intent with the ACTION_CALL_BUTTON.
    // Besides of checking the intent action, we must check if the phone is really during a
    // call in order to decide whether to ignore the event or continue to display the activity.
    if (callKey && phoneIsInUse()) {
      TelecomUtil.showInCallScreen(this, false);
      return true;
    }

    return false;
  }

  /**
   * Sets the current tab based on the intent's request type
   *
   * @param intent Intent that contains information about which tab should be selected
   */
  private void displayFragment(Intent intent) {
    // If we got here by hitting send and we're in call forward along to the in-call activity
    if (isSendKeyWhileInCall(intent)) {
      finish();
      return;
    }

    boolean showDialpadChooser =
        !ACTION_SHOW_TAB.equals(intent.getAction())
            && phoneIsInUse()
            && !DialpadFragment.isAddCallMode(intent);
    boolean isDialIntent = intent.getData() != null && isDialIntent(intent);
    boolean isAddCallIntent = DialpadFragment.isAddCallMode(intent);
    if (showDialpadChooser || isDialIntent || isAddCallIntent) {
      LogUtil.i(
          "DialtactsActivity.displayFragment",
          "show dialpad fragment (showDialpadChooser: %b, isDialIntent: %b, isAddCallIntent: %b)",
          showDialpadChooser,
          isDialIntent,
          isAddCallIntent);
      showDialpadFragment(false);
      dialpadFragment.setStartedFromNewIntent(true);
      if (showDialpadChooser && !dialpadFragment.isVisible()) {
        inCallDialpadUp = true;
      }
    } else if (isLastTabEnabled) {
      @TabIndex
      int tabIndex =
          StorageComponent.get(this)
              .unencryptedSharedPrefs()
              .getInt(KEY_LAST_TAB, DialtactsPagerAdapter.TAB_INDEX_SPEED_DIAL);
      // If voicemail tab is saved and its availability changes, we still move to the voicemail tab
      // but it is quickly removed and shown the contacts tab.
      if (listsFragment != null) {
        listsFragment.showTab(tabIndex);
        PerformanceReport.setStartingTabIndex(tabIndex);
      } else {
        PerformanceReport.setStartingTabIndex(DialtactsPagerAdapter.TAB_INDEX_SPEED_DIAL);
      }
    }
  }

  @Override
  public void onNewIntent(Intent newIntent) {
    LogUtil.enterBlock("DialtactsActivity.onNewIntent");
    setIntent(newIntent);
    firstLaunch = true;

    stateSaved = false;
    displayFragment(newIntent);

    invalidateOptionsMenu();
  }

  /** Returns true if the given intent contains a phone number to populate the dialer with */
  private boolean isDialIntent(Intent intent) {
    final String action = intent.getAction();
    if (Intent.ACTION_DIAL.equals(action) || ACTION_TOUCH_DIALER.equals(action)) {
      return true;
    }
    if (Intent.ACTION_VIEW.equals(action)) {
      final Uri data = intent.getData();
      if (data != null && PhoneAccount.SCHEME_TEL.equals(data.getScheme())) {
        return true;
      }
    }
    return false;
  }

  /** Shows the search fragment */
  private void enterSearchUi(boolean smartDialSearch, String query, boolean animate) {
    LogUtil.i("DialtactsActivity.enterSearchUi", "smart dial: %b", smartDialSearch);
    if (stateSaved || getFragmentManager().isDestroyed()) {
      // Weird race condition where fragment is doing work after the activity is destroyed
      // due to talkback being on (a bug). Just return since we can't do any
      // constructive here.
      LogUtil.i(
          "DialtactsActivity.enterSearchUi",
          "not entering search UI (mStateSaved: %b, isDestroyed: %b)",
          stateSaved,
          getFragmentManager().isDestroyed());
      return;
    }

    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    String tag = TAG_NEW_SEARCH_FRAGMENT;
    inNewSearch = true;

    floatingActionButtonController.scaleOut();

    if (animate) {
      transaction.setCustomAnimations(android.R.animator.fade_in, 0);
    } else {
      transaction.setTransition(FragmentTransaction.TRANSIT_NONE);
    }

    NewSearchFragment fragment = (NewSearchFragment) getFragmentManager().findFragmentByTag(tag);
    if (fragment == null) {
      fragment = NewSearchFragment.newInstance(!isDialpadShown());
      transaction.add(R.id.dialtacts_frame, fragment, tag);
    } else {
      transaction.show(fragment);
    }

    // DialtactsActivity will provide the options menu
    fragment.setHasOptionsMenu(false);
    fragment.setQuery(query, getCallInitiationType());
    transaction.commit();

    if (animate) {
      Assert.isNotNull(listsFragment.getView()).animate().alpha(0).withLayer();
    }
    listsFragment.setUserVisibleHint(false);
  }

  /** Hides the search fragment */
  private void exitSearchUi() {
    LogUtil.enterBlock("DialtactsActivity.exitSearchUi");

    // See related bug in enterSearchUI();
    if (getFragmentManager().isDestroyed() || stateSaved) {
      return;
    }

    searchView.setText(null);

    if (dialpadFragment != null) {
      dialpadFragment.clearDialpad();
    }

    setNotInSearchUi();

    // There are four states the fab can be in:
    //   - Not visible and should remain not visible (do nothing)
    //   - Not visible (move then show the fab)
    //   - Visible, in the correct position (do nothing)
    //   - Visible, in the wrong position (hide, move, then show the fab)
    if (floatingActionButtonController.isVisible()
        && getFabAlignment() != FloatingActionButtonController.ALIGN_END) {
      floatingActionButtonController.scaleOut(
          new OnVisibilityChangedListener() {
            @Override
            public void onHidden(FloatingActionButton floatingActionButton) {
              super.onHidden(floatingActionButton);
              onPageScrolled(
                  listsFragment.getCurrentTabIndex(), 0 /* offset */, 0 /* pixelOffset */);
              floatingActionButtonController.scaleIn();
            }
          });
    } else if (!floatingActionButtonController.isVisible() && listsFragment.shouldShowFab()) {
      onPageScrolled(listsFragment.getCurrentTabIndex(), 0 /* offset */, 0 /* pixelOffset */);
      ThreadUtil.getUiThreadHandler()
          .postDelayed(() -> floatingActionButtonController.scaleIn(), FAB_SCALE_IN_DELAY_MS);
    }

    final FragmentTransaction transaction = getFragmentManager().beginTransaction();
    if (newSearchFragment != null) {
      transaction.remove(newSearchFragment);
    }
    transaction.commit();

    Assert.isNotNull(listsFragment.getView()).animate().alpha(1).withLayer();

    if (dialpadFragment == null || !dialpadFragment.isVisible()) {
      // If the dialpad fragment wasn't previously visible, then send a screen view because
      // we are exiting regular search. Otherwise, the screen view will be sent by
      // {@link #hideDialpadFragment}.
      listsFragment.sendScreenViewForCurrentPosition();
      listsFragment.setUserVisibleHint(true);
    }
    onPageSelected(listsFragment.getCurrentTabIndex());

    actionBarController.onSearchUiExited();
  }

  @Override
  public void onBackPressed() {
    PerformanceReport.recordClick(UiAction.Type.PRESS_ANDROID_BACK_BUTTON);

    if (stateSaved) {
      return;
    }
    if (isDialpadShown) {
      hideDialpadFragment(true, false);
      if (TextUtils.isEmpty(dialpadQuery)) {
        exitSearchUi();
      }
    } else if (isInSearchUi()) {
      if (isKeyboardOpen) {
        DialerUtils.hideInputMethod(parentLayout);
        PerformanceReport.recordClick(UiAction.Type.HIDE_KEYBOARD_IN_SEARCH);
      } else {
        exitSearchUi();
      }
    } else {
      super.onBackPressed();
    }
  }

  @Override
  public void onConfigurationChanged(Configuration configuration) {
    super.onConfigurationChanged(configuration);
    // Checks whether a hardware keyboard is available
    if (configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
      isKeyboardOpen = true;
    } else if (configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
      isKeyboardOpen = false;
    }
  }

  private void maybeEnterSearchUi() {
    if (!isInSearchUi()) {
      enterSearchUi(true /* isSmartDial */, searchQuery, false);
    }
  }

  @Override
  public void onDialpadQueryChanged(String query) {
    dialpadQuery = query;
    if (newSearchFragment != null) {
      newSearchFragment.setRawNumber(query);
    }
    final String normalizedQuery =
        SmartDialNameMatcher.normalizeNumber(/* context = */ this, query);

    if (!TextUtils.equals(searchView.getText(), normalizedQuery)) {
      if (DEBUG) {
        LogUtil.v("DialtactsActivity.onDialpadQueryChanged", "new query: " + query);
      }
      if (dialpadFragment == null || !dialpadFragment.isVisible()) {
        // This callback can happen if the dialpad fragment is recreated because of
        // activity destruction. In that case, don't update the search view because
        // that would bring the user back to the search fragment regardless of the
        // previous state of the application. Instead, just return here and let the
        // fragment manager correctly figure out whatever fragment was last displayed.
        if (!TextUtils.isEmpty(normalizedQuery)) {
          pendingSearchViewQuery = normalizedQuery;
        }
        return;
      }
      searchView.setText(normalizedQuery);
    }

    try {
      if (dialpadFragment != null && dialpadFragment.isVisible()) {
        dialpadFragment.process_quote_emergency_unquote(normalizedQuery);
      }
    } catch (Exception ignored) {
      // Skip any exceptions for this piece of code
    }
  }

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

  @Override
  public boolean shouldShowDialpadChooser() {
    // Show the dialpad chooser if we're in a call
    return true;
  }

  @Override
  public void onSearchListTouch() {
    if (isDialpadShown) {
      PerformanceReport.recordClick(UiAction.Type.CLOSE_DIALPAD);
      hideDialpadFragment(true, false);
      if (TextUtils.isEmpty(dialpadQuery)) {
        exitSearchUi();
      }
    } else {
      UiUtil.hideKeyboardFrom(this, searchEditTextLayout);
    }
  }

  @Override
  public void onListFragmentScrollStateChange(int scrollState) {
    PerformanceReport.recordScrollStateChange(scrollState);
    if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
      hideDialpadFragment(true, false);
      DialerUtils.hideInputMethod(parentLayout);
    }
  }

  @Override
  public void onListFragmentScroll(int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    // TODO: No-op for now. This should eventually show/hide the actionBar based on
    // interactions with the ListsFragments.
  }

  private boolean phoneIsInUse() {
    return TelecomUtil.isInManagedCall(this);
  }

  private boolean canIntentBeHandled(Intent intent) {
    final PackageManager packageManager = getPackageManager();
    final List<ResolveInfo> resolveInfo =
        packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    return resolveInfo != null && resolveInfo.size() > 0;
  }

  /** Called when the user has long-pressed a contact tile to start a drag operation. */
  @Override
  public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) {
    listsFragment.showRemoveView(true);
  }

  @Override
  public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view) {}

  /** Called when the user has released a contact tile after long-pressing it. */
  @Override
  public void onDragFinished(int x, int y) {
    listsFragment.showRemoveView(false);
  }

  @Override
  public void onDroppedOnRemove() {}

  @Override
  public ImageView getDragShadowOverlay() {
    return findViewById(R.id.contact_tile_drag_shadow_overlay);
  }

  @Override
  public void setHasFrequents(boolean hasFrequents) {
    // No-op
  }

  /**
   * Allows the SpeedDialFragment to attach the drag controller to mRemoveViewContainer once it has
   * been attached to the activity.
   */
  @Override
  public void setDragDropController(DragDropController dragController) {
    dragDropController = dragController;
    listsFragment.getRemoveView().setDragDropController(dragController);
  }

  /** Implemented to satisfy {@link OldSpeedDialFragment.HostInterface} */
  @Override
  public void showAllContactsTab() {
    if (listsFragment != null) {
      listsFragment.showTab(DialtactsPagerAdapter.TAB_INDEX_ALL_CONTACTS);
    }
  }

  /** Implemented to satisfy {@link CallLogFragment.HostInterface} */
  @Override
  public void showDialpad() {
    showDialpadFragment(true);
  }

  @Override
  public void enableFloatingButton(boolean enabled) {
    LogUtil.d("DialtactsActivity.enableFloatingButton", "enable: %b", enabled);
    // Floating button shouldn't be enabled when dialpad is shown.
    if (!isDialpadShown() || !enabled) {
      floatingActionButtonController.setVisible(enabled);
    }
  }

  @Override
  public void onPickDataUri(
      Uri dataUri, boolean isVideoCall, CallSpecificAppData callSpecificAppData) {
    clearSearchOnPause = true;
    PhoneNumberInteraction.startInteractionForPhoneCall(
        DialtactsActivity.this, dataUri, isVideoCall, callSpecificAppData);
  }

  @Override
  public void onPickPhoneNumber(
      String phoneNumber, boolean isVideoCall, CallSpecificAppData callSpecificAppData) {
    if (phoneNumber == null) {
      // Invalid phone number, but let the call go through so that InCallUI can show
      // an error message.
      phoneNumber = "";
    }
    PreCall.start(
        this,
        new CallIntentBuilder(phoneNumber, callSpecificAppData)
            .setIsVideoCall(isVideoCall)
            .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing()));

    clearSearchOnPause = true;
  }

  @Override
  public void onHomeInActionBarSelected() {
    exitSearchUi();
  }

  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    // FAB does not move with the new favorites UI
    if (newFavoritesIsEnabled()) {
      return;
    }
    int tabIndex = listsFragment.getCurrentTabIndex();

    // Scroll the button from center to end when moving from the Speed Dial to Call History tab.
    // In RTL, scroll when the current tab is Call History instead, since the order of the tabs
    // is reversed and the ViewPager returns the left tab position during scroll.
    boolean isRtl = ViewUtil.isRtl();
    if (!isRtl && tabIndex == DialtactsPagerAdapter.TAB_INDEX_SPEED_DIAL && !isLandscape) {
      floatingActionButtonController.onPageScrolled(positionOffset);
    } else if (isRtl && tabIndex == DialtactsPagerAdapter.TAB_INDEX_HISTORY && !isLandscape) {
      floatingActionButtonController.onPageScrolled(1 - positionOffset);
    } else if (tabIndex != DialtactsPagerAdapter.TAB_INDEX_SPEED_DIAL) {
      floatingActionButtonController.onPageScrolled(1);
    }
  }

  @Override
  public void onPageSelected(int position) {
    updateMissedCalls();
    int tabIndex = listsFragment.getCurrentTabIndex();
    if (tabIndex != previouslySelectedTabIndex) {
      floatingActionButtonController.scaleIn();
    }
    LogUtil.i("DialtactsActivity.onPageSelected", "tabIndex: %d", tabIndex);
    previouslySelectedTabIndex = tabIndex;
    timeTabSelected = SystemClock.elapsedRealtime();
  }

  @Override
  public void onPageScrollStateChanged(int state) {}

  public boolean isActionBarShowing() {
    return actionBarController.isActionBarShowing();
  }

  public boolean isDialpadShown() {
    return isDialpadShown;
  }

  @Override
  public void setActionBarHideOffset(int offset) {
    getActionBarSafely().setHideOffset(offset);
  }

  @Override
  public int getActionBarHeight() {
    return actionBarHeight;
  }

  @VisibleForTesting
  public int getFabAlignment() {
    if (!newFavoritesIsEnabled()
        && !isLandscape
        && !isInSearchUi()
        && listsFragment.getCurrentTabIndex() == DialtactsPagerAdapter.TAB_INDEX_SPEED_DIAL) {
      return FloatingActionButtonController.ALIGN_MIDDLE;
    }
    return FloatingActionButtonController.ALIGN_END;
  }

  private void updateMissedCalls() {
    if (previouslySelectedTabIndex == DialtactsPagerAdapter.TAB_INDEX_HISTORY) {
      listsFragment.markMissedCallsAsReadAndRemoveNotifications();
    }
  }

  @Override
  public void onDisambigDialogDismissed() {
    // Don't do anything; the app will remain open with favorites tiles displayed.
  }

  @Override
  public void interactionError(@InteractionErrorCode int interactionErrorCode) {
    switch (interactionErrorCode) {
      case InteractionErrorCode.USER_LEAVING_ACTIVITY:
        // This is expected to happen if the user exits the activity before the interaction occurs.
        return;
      case InteractionErrorCode.CONTACT_NOT_FOUND:
      case InteractionErrorCode.CONTACT_HAS_NO_NUMBER:
      case InteractionErrorCode.OTHER_ERROR:
      default:
        // All other error codes are unexpected. For example, it should be impossible to start an
        // interaction with an invalid contact from the Dialtacts activity.
        Assert.fail("PhoneNumberInteraction error: " + interactionErrorCode);
    }
  }

  @Override
  public void onRequestPermissionsResult(
      int requestCode, String[] permissions, int[] grantResults) {
    // This should never happen; it should be impossible to start an interaction without the
    // contacts permission from the Dialtacts activity.
    Assert.fail(
        String.format(
            Locale.US,
            "Permissions requested unexpectedly: %d/%s/%s",
            requestCode,
            Arrays.toString(permissions),
            Arrays.toString(grantResults)));
  }

  @Override
  public void onActionModeStateChanged(boolean isEnabled) {
    isMultiSelectModeEnabled = isEnabled;
  }

  @Override
  public boolean isActionModeStateEnabled() {
    return isMultiSelectModeEnabled;
  }

  private CallInitiationType.Type getCallInitiationType() {
    return isDialpadShown
        ? CallInitiationType.Type.DIALPAD
        : CallInitiationType.Type.REGULAR_SEARCH;
  }

  @Override
  public void onCallPlacedFromSearch() {
    DialerUtils.hideInputMethod(parentLayout);
    clearSearchOnPause = true;
  }

  @Override
  public void requestingPermission() {}

  protected int getPreviouslySelectedTabIndex() {
    return previouslySelectedTabIndex;
  }

  @Override
  public void onContactSelected(ImageView photo, Uri contactUri, long contactId) {
    Logger.get(this)
        .logInteraction(InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_CONTACTS_FRAGMENT_ITEM);
    QuickContact.showQuickContact(
        this, photo, contactUri, QuickContact.MODE_LARGE, null /* excludeMimes */);
  }

  /** Popup menu accessible from the search bar */
  protected class OptionsPopupMenu extends PopupMenu {

    public OptionsPopupMenu(Context context, View anchor) {
      super(context, anchor, Gravity.END);
    }

    @Override
    public void show() {
      Menu menu = getMenu();
      MenuItem clearFrequents = menu.findItem(R.id.menu_clear_frequents);
      clearFrequents.setVisible(
          PermissionsUtil.hasContactsReadPermissions(DialtactsActivity.this)
              && listsFragment != null
              && listsFragment.hasFrequents());

      menu.findItem(R.id.menu_history)
          .setVisible(PermissionsUtil.hasPhonePermissions(DialtactsActivity.this));

      Context context = DialtactsActivity.this.getApplicationContext();
      MenuItem simulatorMenuItem = menu.findItem(R.id.menu_simulator_submenu);
      Simulator simulator = SimulatorComponent.get(context).getSimulator();
      if (simulator.shouldShow()) {
        simulatorMenuItem.setVisible(true);
        simulatorMenuItem.setActionProvider(simulator.getActionProvider(DialtactsActivity.this));
      } else {
        simulatorMenuItem.setVisible(false);
      }
      super.show();
    }
  }

  /**
   * Listener that listens to drag events and sends their x and y coordinates to a {@link
   * DragDropController}.
   */
  private class LayoutOnDragListener implements OnDragListener {

    @Override
    public boolean onDrag(View v, DragEvent event) {
      if (event.getAction() == DragEvent.ACTION_DRAG_LOCATION) {
        dragDropController.handleDragHovered(v, (int) event.getX(), (int) event.getY());
      }
      return true;
    }
  }

  @VisibleForTesting
  static void setVoiceSearchEnabledForTest(Optional<Boolean> enabled) {
    voiceSearchEnabledForTest = enabled;
  }

  private boolean newFavoritesIsEnabled() {
    return ConfigProviderBindings.get(this).getBoolean("enable_new_favorites_tab", false);
  }
}
