/*
 * Copyright (C) 2011 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.calllog;

import android.app.Activity;
import android.content.ContentUris;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Trace;
import android.provider.CallLog;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.android.contacts.common.ContactsUtils;
import com.android.dialer.app.R;
import com.android.dialer.app.calllog.CallLogFragment.CallLogFragmentListener;
import com.android.dialer.app.calllog.CallLogGroupBuilder.GroupCreator;
import com.android.dialer.app.calllog.calllogcache.CallLogCache;
import com.android.dialer.app.contactinfo.ContactInfoCache;
import com.android.dialer.app.voicemail.VoicemailPlaybackPresenter;
import com.android.dialer.app.voicemail.VoicemailPlaybackPresenter.OnVoicemailDeletedListener;
import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
import com.android.dialer.calldetails.CallDetailsEntries;
import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry;
import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction;
import com.android.dialer.calllogutils.PhoneCallDetails;
import com.android.dialer.common.Assert;
import com.android.dialer.common.FragmentUtils.FragmentUtilListener;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.AsyncTaskExecutor;
import com.android.dialer.common.concurrent.AsyncTaskExecutors;
import com.android.dialer.compat.android.provider.VoicemailCompat;
import com.android.dialer.configprovider.ConfigProviderComponent;
import com.android.dialer.contacts.ContactsComponent;
import com.android.dialer.duo.Duo;
import com.android.dialer.duo.DuoComponent;
import com.android.dialer.duo.DuoListener;
import com.android.dialer.enrichedcall.EnrichedCallCapabilities;
import com.android.dialer.enrichedcall.EnrichedCallComponent;
import com.android.dialer.enrichedcall.EnrichedCallManager;
import com.android.dialer.logging.ContactSource;
import com.android.dialer.logging.ContactSource.Type;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import com.android.dialer.logging.LoggingBindings.ContactsProviderMatchInfo;
import com.android.dialer.logging.UiAction;
import com.android.dialer.main.MainActivityPeer;
import com.android.dialer.performancereport.PerformanceReport;
import com.android.dialer.phonenumbercache.CallLogQuery;
import com.android.dialer.phonenumbercache.ContactInfo;
import com.android.dialer.phonenumbercache.ContactInfoHelper;
import com.android.dialer.phonenumberutil.PhoneNumberHelper;
import com.android.dialer.spam.SpamComponent;
import com.android.dialer.telecom.TelecomUtil;
import com.android.dialer.util.PermissionsUtil;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;

/** Adapter class to fill in data for the Call Log. */
public class CallLogAdapter extends GroupingListAdapter
    implements GroupCreator, OnVoicemailDeletedListener, DuoListener {

  // Types of activities the call log adapter is used for
  public static final int ACTIVITY_TYPE_CALL_LOG = 1;
  public static final int ACTIVITY_TYPE_DIALTACTS = 2;
  private static final int NO_EXPANDED_LIST_ITEM = -1;
  public static final int ALERT_POSITION = 0;
  private static final int VIEW_TYPE_ALERT = 1;
  private static final int VIEW_TYPE_CALLLOG = 2;

  private static final String KEY_EXPANDED_POSITION = "expanded_position";
  private static final String KEY_EXPANDED_ROW_ID = "expanded_row_id";
  private static final String KEY_ACTION_MODE = "action_mode_selected_items";

  public static final String LOAD_DATA_TASK_IDENTIFIER = "load_data";

  public static final String ENABLE_CALL_LOG_MULTI_SELECT = "enable_call_log_multiselect";
  public static final boolean ENABLE_CALL_LOG_MULTI_SELECT_FLAG = true;

  @VisibleForTesting static final String FILTER_EMERGENCY_CALLS_FLAG = "filter_emergency_calls";

  protected final Activity activity;
  protected final VoicemailPlaybackPresenter voicemailPlaybackPresenter;
  /** Cache for repeated requests to Telecom/Telephony. */
  protected final CallLogCache callLogCache;

  private final CallFetcher callFetcher;
  private final OnActionModeStateChangedListener actionModeStateChangedListener;
  private final MultiSelectRemoveView multiSelectRemoveView;
  @NonNull private final FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler;
  private final int activityType;

  /** Instance of helper class for managing views. */
  private final CallLogListItemHelper callLogListItemHelper;
  /** Helper to group call log entries. */
  private final CallLogGroupBuilder callLogGroupBuilder;

  private final AsyncTaskExecutor asyncTaskExecutor = AsyncTaskExecutors.createAsyncTaskExecutor();
  private ContactInfoCache contactInfoCache;
  // Tracks the position of the currently expanded list item.
  private int currentlyExpandedPosition = RecyclerView.NO_POSITION;
  // Tracks the rowId of the currently expanded list item, so the position can be updated if there
  // are any changes to the call log entries, such as additions or removals.
  private long currentlyExpandedRowId = NO_EXPANDED_LIST_ITEM;

  private final CallLogAlertManager callLogAlertManager;

  public ActionMode actionMode = null;
  public boolean selectAllMode = false;
  public boolean deselectAllMode = false;
  private final SparseArray<String> selectedItems = new SparseArray<>();

  /**
   * Maps a raw input number to match info. We only log one MatchInfo per raw input number to reduce
   * the amount of data logged.
   */
  private final Map<String, ContactsProviderMatchInfo> contactsProviderMatchInfos =
      new ArrayMap<>();

  private final ActionMode.Callback actionModeCallback =
      new ActionMode.Callback() {

        // Called when the action mode is created; startActionMode() was called
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
          if (activity != null) {
            announceforAccessibility(
                activity.getCurrentFocus(),
                activity.getString(R.string.description_entering_bulk_action_mode));
          }
          actionMode = mode;
          // Inflate a menu resource providing context menu items
          MenuInflater inflater = mode.getMenuInflater();
          inflater.inflate(R.menu.actionbar_delete, menu);
          multiSelectRemoveView.showMultiSelectRemoveView(true);
          actionModeStateChangedListener.onActionModeStateChanged(mode, true);
          return true;
        }

        // Called each time the action mode is shown. Always called after onCreateActionMode, but
        // may be called multiple times if the mode is invalidated.
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
          return false; // Return false if nothing is done
        }

        // Called when the user selects a contextual menu item
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
          if (item.getItemId() == R.id.action_bar_delete_menu_item) {
            Logger.get(activity).logImpression(DialerImpression.Type.MULTISELECT_TAP_DELETE_ICON);
            if (selectedItems.size() > 0) {
              showDeleteSelectedItemsDialog();
            }
            return true;
          } else {
            return false;
          }
        }

        // Called when the user exits the action mode
        @Override
        public void onDestroyActionMode(ActionMode mode) {
          if (activity != null) {
            announceforAccessibility(
                activity.getCurrentFocus(),
                activity.getString(R.string.description_leaving_bulk_action_mode));
          }
          selectedItems.clear();
          actionMode = null;
          selectAllMode = false;
          deselectAllMode = false;
          multiSelectRemoveView.showMultiSelectRemoveView(false);
          actionModeStateChangedListener.onActionModeStateChanged(null, false);
          notifyDataSetChanged();
        }
      };

  private void showDeleteSelectedItemsDialog() {
    SparseArray<String> voicemailsToDeleteOnConfirmation = selectedItems.clone();
    new AlertDialog.Builder(activity)
        .setCancelable(true)
        .setTitle(
            activity
                .getResources()
                .getQuantityString(
                    R.plurals.delete_voicemails_confirmation_dialog_title, selectedItems.size()))
        .setPositiveButton(
            R.string.voicemailMultiSelectDeleteConfirm,
            new DialogInterface.OnClickListener() {
              @Override
              public void onClick(final DialogInterface dialog, final int button) {
                LogUtil.i(
                    "CallLogAdapter.showDeleteSelectedItemsDialog",
                    "onClick, these items to delete " + voicemailsToDeleteOnConfirmation);
                deleteSelectedItems(voicemailsToDeleteOnConfirmation);
                actionMode.finish();
                dialog.cancel();
                Logger.get(activity)
                    .logImpression(
                        DialerImpression.Type.MULTISELECT_DELETE_ENTRY_VIA_CONFIRMATION_DIALOG);
              }
            })
        .setOnCancelListener(
            new OnCancelListener() {
              @Override
              public void onCancel(DialogInterface dialogInterface) {
                Logger.get(activity)
                    .logImpression(
                        DialerImpression.Type
                            .MULTISELECT_CANCEL_CONFIRMATION_DIALOG_VIA_CANCEL_TOUCH);
                dialogInterface.cancel();
              }
            })
        .setNegativeButton(
            R.string.voicemailMultiSelectDeleteCancel,
            new DialogInterface.OnClickListener() {
              @Override
              public void onClick(final DialogInterface dialog, final int button) {
                Logger.get(activity)
                    .logImpression(
                        DialerImpression.Type
                            .MULTISELECT_CANCEL_CONFIRMATION_DIALOG_VIA_CANCEL_BUTTON);
                dialog.cancel();
              }
            })
        .show();
    Logger.get(activity)
        .logImpression(DialerImpression.Type.MULTISELECT_DISPLAY_DELETE_CONFIRMATION_DIALOG);
  }

  private void deleteSelectedItems(SparseArray<String> voicemailsToDelete) {
    for (int i = 0; i < voicemailsToDelete.size(); i++) {
      String voicemailUri = voicemailsToDelete.get(voicemailsToDelete.keyAt(i));
      LogUtil.i("CallLogAdapter.deleteSelectedItems", "deleting uri:" + voicemailUri);
      CallLogAsyncTaskUtil.deleteVoicemail(activity, Uri.parse(voicemailUri), null);
    }
  }

  private final View.OnLongClickListener longPressListener =
      new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
          if (ConfigProviderComponent.get(v.getContext())
                  .getConfigProvider()
                  .getBoolean(ENABLE_CALL_LOG_MULTI_SELECT, ENABLE_CALL_LOG_MULTI_SELECT_FLAG)
              && voicemailPlaybackPresenter != null) {
            if (v.getId() == R.id.primary_action_view || v.getId() == R.id.quick_contact_photo) {
              if (actionMode == null) {
                Logger.get(activity)
                    .logImpression(
                        DialerImpression.Type.MULTISELECT_LONG_PRESS_ENTER_MULTI_SELECT_MODE);
                actionMode = v.startActionMode(actionModeCallback);
              }
              Logger.get(activity)
                  .logImpression(DialerImpression.Type.MULTISELECT_LONG_PRESS_TAP_ENTRY);
              CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder) v.getTag();
              viewHolder.quickContactView.setVisibility(View.GONE);
              viewHolder.checkBoxView.setVisibility(View.VISIBLE);
              expandCollapseListener.onClick(v);
              return true;
            }
          }
          return true;
        }
      };

  @VisibleForTesting
  public View.OnClickListener getExpandCollapseListener() {
    return expandCollapseListener;
  }

  /** The OnClickListener used to expand or collapse the action buttons of a call log entry. */
  private final View.OnClickListener expandCollapseListener =
      new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          PerformanceReport.recordClick(UiAction.Type.CLICK_CALL_LOG_ITEM);

          CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder) v.getTag();
          if (viewHolder == null) {
            return;
          }
          if (actionMode != null && viewHolder.voicemailUri != null) {
            selectAllMode = false;
            deselectAllMode = false;
            multiSelectRemoveView.setSelectAllModeToFalse();
            int id = getVoicemailId(viewHolder.voicemailUri);
            if (selectedItems.get(id) != null) {
              Logger.get(activity)
                  .logImpression(DialerImpression.Type.MULTISELECT_SINGLE_PRESS_UNSELECT_ENTRY);
              uncheckMarkCallLogEntry(viewHolder, id);
            } else {
              Logger.get(activity)
                  .logImpression(DialerImpression.Type.MULTISELECT_SINGLE_PRESS_SELECT_ENTRY);
              checkMarkCallLogEntry(viewHolder);
              // select all check box logic
              if (getItemCount() == selectedItems.size()) {
                LogUtil.i(
                    "mExpandCollapseListener.onClick",
                    "getitem count %d is equal to items select count %d, check select all box",
                    getItemCount(),
                    selectedItems.size());
                multiSelectRemoveView.tapSelectAll();
              }
            }
            return;
          }

          if (voicemailPlaybackPresenter != null) {
            // Always reset the voicemail playback state on expand or collapse.
            voicemailPlaybackPresenter.resetAll();
          }

          // If enriched call capabilities were unknown on the initial load,
          // viewHolder.isCallComposerCapable may be unset. Check here if we have the capabilities
          // as a last attempt at getting them before showing the expanded view to the user
          EnrichedCallCapabilities capabilities = null;

          if (viewHolder.number != null) {
            capabilities = getEnrichedCallManager().getCapabilities(viewHolder.number);
          }

          if (capabilities == null) {
            capabilities = EnrichedCallCapabilities.NO_CAPABILITIES;
          }

          viewHolder.isCallComposerCapable = capabilities.isCallComposerCapable();

          if (capabilities.isTemporarilyUnavailable()) {
            LogUtil.i(
                "mExpandCollapseListener.onClick",
                "%s is temporarily unavailable, requesting capabilities",
                LogUtil.sanitizePhoneNumber(viewHolder.number));
            // Refresh the capabilities when temporarily unavailable.
            // Similarly to when we request capabilities the first time, the 'Share and call' button
            // won't pop in with the new capabilities. Instead the row needs to be collapsed and
            // expanded again.
            getEnrichedCallManager().requestCapabilities(viewHolder.number);
          }

          if (viewHolder.rowId == currentlyExpandedRowId) {
            // Hide actions, if the clicked item is the expanded item.
            viewHolder.showActions(false);

            currentlyExpandedPosition = RecyclerView.NO_POSITION;
            currentlyExpandedRowId = NO_EXPANDED_LIST_ITEM;
          } else {
            if (viewHolder.callType == CallLog.Calls.MISSED_TYPE) {
              CallLogAsyncTaskUtil.markCallAsRead(activity, viewHolder.callIds);
              if (activityType == ACTIVITY_TYPE_DIALTACTS) {
                Assert.checkState(
                    v.getContext() instanceof MainActivityPeer.PeerSupplier,
                    "%s is not a PeerSupplier",
                    v.getContext().getClass());
                // This is really bad, but we must do this to prevent a dependency cycle, enforce
                // best practices in new code, and avoid refactoring DialtactsActivity.
                ((FragmentUtilListener) ((MainActivityPeer.PeerSupplier) v.getContext()).getPeer())
                    .getImpl(CallLogFragmentListener.class)
                    .updateTabUnreadCounts();
              }
            }
            expandViewHolderActions(viewHolder);
          }
        }
      };

  @Nullable
  public RecyclerView.OnScrollListener getOnScrollListener() {
    return null;
  }

  private void checkMarkCallLogEntry(CallLogListItemViewHolder viewHolder) {
    announceforAccessibility(
        activity.getCurrentFocus(),
        activity.getString(
            R.string.description_selecting_bulk_action_mode, viewHolder.nameOrNumber));
    viewHolder.quickContactView.setVisibility(View.GONE);
    viewHolder.checkBoxView.setVisibility(View.VISIBLE);
    selectedItems.put(getVoicemailId(viewHolder.voicemailUri), viewHolder.voicemailUri);
    updateActionBar();
  }

  private void announceforAccessibility(View view, String announcement) {
    if (view != null) {
      view.announceForAccessibility(announcement);
    }
  }

  private void updateActionBar() {
    if (actionMode == null && selectedItems.size() > 0) {
      Logger.get(activity)
          .logImpression(DialerImpression.Type.MULTISELECT_ROTATE_AND_SHOW_ACTION_MODE);
      activity.startActionMode(actionModeCallback);
    }
    if (actionMode != null) {
      actionMode.setTitle(
          activity
              .getResources()
              .getString(
                  R.string.voicemailMultiSelectActionBarTitle,
                  Integer.toString(selectedItems.size())));
    }
  }

  private void uncheckMarkCallLogEntry(CallLogListItemViewHolder viewHolder, int id) {
    announceforAccessibility(
        activity.getCurrentFocus(),
        activity.getString(
            R.string.description_unselecting_bulk_action_mode, viewHolder.nameOrNumber));
    selectedItems.delete(id);
    viewHolder.checkBoxView.setVisibility(View.GONE);
    viewHolder.quickContactView.setVisibility(View.VISIBLE);
    updateActionBar();
  }

  private static int getVoicemailId(String voicemailUri) {
    Assert.checkArgument(voicemailUri != null);
    Assert.checkArgument(voicemailUri.length() > 0);
    return (int) ContentUris.parseId(Uri.parse(voicemailUri));
  }

  /**
   * A list of {@link CallLogQuery#ID} that will be hidden. The hide might be temporary so instead
   * if removing an item, it will be shown as an invisible view. This simplifies the calculation of
   * item position.
   */
  @NonNull private Set<Long> hiddenRowIds = new ArraySet<>();
  /**
   * Holds a list of URIs that are pending deletion or undo. If the activity ends before the undo
   * timeout, all of the pending URIs will be deleted.
   *
   * <p>TODO(twyen): move this and OnVoicemailDeletedListener to somewhere like {@link
   * VisualVoicemailCallLogFragment}. The CallLogAdapter does not need to know about what to do with
   * hidden item or what to hide.
   */
  @NonNull private final Set<Uri> hiddenItemUris = new ArraySet<>();

  private CallLogListItemViewHolder.OnClickListener blockReportSpamListener;

  /**
   * Map, keyed by call ID, used to track the callback action for a call. Calls associated with the
   * same callback action will be put into the same primary call group in {@link
   * com.android.dialer.app.calllog.CallLogGroupBuilder}. This information is used to set the
   * callback icon and trigger the corresponding action.
   */
  private final Map<Long, Integer> callbackActions = new ArrayMap<>();

  /**
   * Map, keyed by call ID, used to track the day group for a call. As call log entries are put into
   * the primary call groups in {@link com.android.dialer.app.calllog.CallLogGroupBuilder}, they are
   * also assigned a secondary "day group". This map tracks the day group assigned to all calls in
   * the call log. This information is used to trigger the display of a day group header above the
   * call log entry at the start of a day group. Note: Multiple calls are grouped into a single
   * primary "call group" in the call log, and the cursor used to bind rows includes all of these
   * calls. When determining if a day group change has occurred it is necessary to look at the last
   * entry in the call log to determine its day group. This map provides a means of determining the
   * previous day group without having to reverse the cursor to the start of the previous day call
   * log entry.
   */
  private final Map<Long, Integer> dayGroups = new ArrayMap<>();

  private boolean loading = true;

  private boolean isSpamEnabled;

  public CallLogAdapter(
      Activity activity,
      ViewGroup alertContainer,
      CallFetcher callFetcher,
      MultiSelectRemoveView multiSelectRemoveView,
      OnActionModeStateChangedListener actionModeStateChangedListener,
      CallLogCache callLogCache,
      ContactInfoCache contactInfoCache,
      VoicemailPlaybackPresenter voicemailPlaybackPresenter,
      @NonNull FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler,
      int activityType) {
    super();

    this.activity = activity;
    this.callFetcher = callFetcher;
    this.actionModeStateChangedListener = actionModeStateChangedListener;
    this.multiSelectRemoveView = multiSelectRemoveView;
    this.voicemailPlaybackPresenter = voicemailPlaybackPresenter;
    if (this.voicemailPlaybackPresenter != null) {
      this.voicemailPlaybackPresenter.setOnVoicemailDeletedListener(this);
    }

    this.activityType = activityType;

    this.contactInfoCache = contactInfoCache;

    if (!PermissionsUtil.hasContactsReadPermissions(activity)) {
      this.contactInfoCache.disableRequestProcessing();
    }

    Resources resources = this.activity.getResources();

    this.callLogCache = callLogCache;

    PhoneCallDetailsHelper phoneCallDetailsHelper =
        new PhoneCallDetailsHelper(this.activity, resources, this.callLogCache);
    callLogListItemHelper =
        new CallLogListItemHelper(phoneCallDetailsHelper, resources, this.callLogCache);
    callLogGroupBuilder = new CallLogGroupBuilder(activity.getApplicationContext(), this);
    this.filteredNumberAsyncQueryHandler = Assert.isNotNull(filteredNumberAsyncQueryHandler);

    blockReportSpamListener =
        new BlockReportSpamListener(
            this.activity,
            this.activity.findViewById(R.id.call_log_fragment_root),
            ((AppCompatActivity) this.activity).getSupportFragmentManager(),
            this,
            this.filteredNumberAsyncQueryHandler);
    setHasStableIds(true);

    callLogAlertManager =
        new CallLogAlertManager(this, LayoutInflater.from(this.activity), alertContainer);
  }

  private void expandViewHolderActions(CallLogListItemViewHolder viewHolder) {
    if (!TextUtils.isEmpty(viewHolder.voicemailUri)) {
      Logger.get(activity).logImpression(DialerImpression.Type.VOICEMAIL_EXPAND_ENTRY);
    }

    int lastExpandedPosition = currentlyExpandedPosition;
    // Show the actions for the clicked list item.
    viewHolder.showActions(true);
    currentlyExpandedPosition = viewHolder.getAdapterPosition();
    currentlyExpandedRowId = viewHolder.rowId;

    // If another item is expanded, notify it that it has changed. Its actions will be
    // hidden when it is re-binded because we change mCurrentlyExpandedRowId above.
    if (lastExpandedPosition != RecyclerView.NO_POSITION) {
      notifyItemChanged(lastExpandedPosition);
    }
  }

  public void onSaveInstanceState(Bundle outState) {
    outState.putInt(KEY_EXPANDED_POSITION, currentlyExpandedPosition);
    outState.putLong(KEY_EXPANDED_ROW_ID, currentlyExpandedRowId);

    ArrayList<String> listOfSelectedItems = new ArrayList<>();

    if (selectedItems.size() > 0) {
      for (int i = 0; i < selectedItems.size(); i++) {
        int id = selectedItems.keyAt(i);
        String voicemailUri = selectedItems.valueAt(i);
        LogUtil.i(
            "CallLogAdapter.onSaveInstanceState", "index %d, id=%d, uri=%s ", i, id, voicemailUri);
        listOfSelectedItems.add(voicemailUri);
      }
    }
    outState.putStringArrayList(KEY_ACTION_MODE, listOfSelectedItems);

    LogUtil.i(
        "CallLogAdapter.onSaveInstanceState",
        "saved: %d, selectedItemsSize:%d",
        listOfSelectedItems.size(),
        selectedItems.size());
  }

  public void onRestoreInstanceState(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
      currentlyExpandedPosition =
          savedInstanceState.getInt(KEY_EXPANDED_POSITION, RecyclerView.NO_POSITION);
      currentlyExpandedRowId =
          savedInstanceState.getLong(KEY_EXPANDED_ROW_ID, NO_EXPANDED_LIST_ITEM);
      // Restoring multi selected entries
      ArrayList<String> listOfSelectedItems =
          savedInstanceState.getStringArrayList(KEY_ACTION_MODE);
      if (listOfSelectedItems != null) {
        LogUtil.i(
            "CallLogAdapter.onRestoreInstanceState",
            "restored selectedItemsList:%d",
            listOfSelectedItems.size());

        if (!listOfSelectedItems.isEmpty()) {
          for (int i = 0; i < listOfSelectedItems.size(); i++) {
            String voicemailUri = listOfSelectedItems.get(i);
            int id = getVoicemailId(voicemailUri);
            LogUtil.i(
                "CallLogAdapter.onRestoreInstanceState",
                "restoring selected index %d, id=%d, uri=%s ",
                i,
                id,
                voicemailUri);
            selectedItems.put(id, voicemailUri);
          }

          LogUtil.i(
              "CallLogAdapter.onRestoreInstance",
              "restored selectedItems %s",
              selectedItems.toString());
          updateActionBar();
        }
      }
    }
  }

  /** Requery on background thread when {@link Cursor} changes. */
  @Override
  protected void onContentChanged() {
    callFetcher.fetchCalls();
  }

  public void setLoading(boolean loading) {
    this.loading = loading;
  }

  public boolean isEmpty() {
    if (loading) {
      // We don't want the empty state to show when loading.
      return false;
    } else {
      return getItemCount() == 0;
    }
  }

  public void clearFilteredNumbersCache() {
    filteredNumberAsyncQueryHandler.clearCache();
  }

  public void onResume() {
    contactsProviderMatchInfos.clear();
    if (PermissionsUtil.hasPermission(activity, android.Manifest.permission.READ_CONTACTS)) {
      contactInfoCache.start();
    }
    isSpamEnabled = SpamComponent.get(activity).spamSettings().isSpamEnabled();
    getDuo().registerListener(this);
    notifyDataSetChanged();
  }

  public void onPause() {
    // The call log can be resumed/paused without loading any contacts. Don't log these events.
    if (!contactsProviderMatchInfos.isEmpty()) {
      Logger.get(activity).logContactsProviderMetrics(contactsProviderMatchInfos.values());
    }

    getDuo().unregisterListener(this);
    pauseCache();
    for (Uri uri : hiddenItemUris) {
      CallLogAsyncTaskUtil.deleteVoicemail(activity, uri, null);
    }
  }

  public void onStop() {
    getEnrichedCallManager().clearCachedData();
  }

  public CallLogAlertManager getAlertManager() {
    return callLogAlertManager;
  }

  @VisibleForTesting
  /* package */ void pauseCache() {
    contactInfoCache.stop();
    callLogCache.reset();
  }

  @Override
  protected void addGroups(Cursor cursor) {
    callLogGroupBuilder.addGroups(cursor);
  }

  @Override
  public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == VIEW_TYPE_ALERT) {
      return callLogAlertManager.createViewHolder(parent);
    }
    return createCallLogEntryViewHolder(parent);
  }

  /**
   * Creates a new call log entry {@link ViewHolder}.
   *
   * @param parent the parent view.
   * @return The {@link ViewHolder}.
   */
  private ViewHolder createCallLogEntryViewHolder(ViewGroup parent) {
    LayoutInflater inflater = LayoutInflater.from(activity);
    View view = inflater.inflate(R.layout.call_log_list_item, parent, false);
    CallLogListItemViewHolder viewHolder =
        CallLogListItemViewHolder.create(
            view,
            activity,
            blockReportSpamListener,
            expandCollapseListener,
            longPressListener,
            actionModeStateChangedListener,
            callLogCache,
            callLogListItemHelper,
            voicemailPlaybackPresenter);

    viewHolder.callLogEntryView.setTag(viewHolder);

    viewHolder.primaryActionView.setTag(viewHolder);
    viewHolder.quickContactView.setTag(viewHolder);

    return viewHolder;
  }

  /**
   * Binds the views in the entry to the data in the call log. TODO: This gets called 20-30 times
   * when Dialer starts up for a single call log entry and should not. It invokes cross-process
   * methods and the repeat execution can get costly.
   *
   * @param viewHolder The view corresponding to this entry.
   * @param position The position of the entry.
   */
  @Override
  public void onBindViewHolder(ViewHolder viewHolder, int position) {
    Trace.beginSection("onBindViewHolder: " + position);
    switch (getItemViewType(position)) {
      case VIEW_TYPE_ALERT:
        // Do nothing
        break;
      default:
        bindCallLogListViewHolder(viewHolder, position);
        break;
    }
    Trace.endSection();
  }

  @Override
  public void onViewRecycled(ViewHolder viewHolder) {
    if (viewHolder.getItemViewType() == VIEW_TYPE_CALLLOG) {
      CallLogListItemViewHolder views = (CallLogListItemViewHolder) viewHolder;
      updateCheckMarkedStatusOfEntry(views);

      if (views.asyncTask != null) {
        views.asyncTask.cancel(true);
      }
    }
  }

  @Override
  public void onViewAttachedToWindow(ViewHolder viewHolder) {
    if (viewHolder.getItemViewType() == VIEW_TYPE_CALLLOG) {
      ((CallLogListItemViewHolder) viewHolder).isAttachedToWindow = true;
    }
  }

  @Override
  public void onViewDetachedFromWindow(ViewHolder viewHolder) {
    if (viewHolder.getItemViewType() == VIEW_TYPE_CALLLOG) {
      ((CallLogListItemViewHolder) viewHolder).isAttachedToWindow = false;
    }
  }

  /**
   * Binds the view holder for the call log list item view.
   *
   * @param viewHolder The call log list item view holder.
   * @param position The position of the list item.
   */
  private void bindCallLogListViewHolder(final ViewHolder viewHolder, final int position) {
    Cursor c = (Cursor) getItem(position);
    if (c == null) {
      return;
    }
    CallLogListItemViewHolder views = (CallLogListItemViewHolder) viewHolder;
    updateCheckMarkedStatusOfEntry(views);

    views.isLoaded = false;
    int groupSize = getGroupSize(position);
    CallDetailsEntries callDetailsEntries = createCallDetailsEntries(c, groupSize);
    PhoneCallDetails details = createPhoneCallDetails(c, groupSize, views);
    if (isHiddenRow(views.number, c.getLong(CallLogQuery.ID))) {
      views.callLogEntryView.setVisibility(View.GONE);
      views.dayGroupHeader.setVisibility(View.GONE);
      return;
    } else {
      views.callLogEntryView.setVisibility(View.VISIBLE);
      // dayGroupHeader will be restored after loadAndRender() if it is needed.
    }
    if (currentlyExpandedRowId == views.rowId) {
      views.inflateActionViewStub();
    }
    loadAndRender(views, views.rowId, details, callDetailsEntries);
  }

  private void updateCheckMarkedStatusOfEntry(CallLogListItemViewHolder views) {
    if (selectedItems.size() > 0 && views.voicemailUri != null) {
      int id = getVoicemailId(views.voicemailUri);
      if (selectedItems.get(id) != null) {
        checkMarkCallLogEntry(views);
      } else {
        uncheckMarkCallLogEntry(views, id);
      }
    }
  }

  private boolean isHiddenRow(@Nullable String number, long rowId) {
    if (isHideableEmergencyNumberRow(number)) {
      return true;
    }
    if (hiddenRowIds.contains(rowId)) {
      return true;
    }
    return false;
  }

  private boolean isHideableEmergencyNumberRow(@Nullable String number) {
    if (!ConfigProviderComponent.get(activity)
        .getConfigProvider()
        .getBoolean(FILTER_EMERGENCY_CALLS_FLAG, false)) {
      return false;
    }
    return number != null && PhoneNumberUtils.isEmergencyNumber(number);
  }

  private void loadAndRender(
      final CallLogListItemViewHolder viewHolder,
      final long rowId,
      final PhoneCallDetails details,
      final CallDetailsEntries callDetailsEntries) {
    LogUtil.d("CallLogAdapter.loadAndRender", "position: %d", viewHolder.getAdapterPosition());
    // Reset block and spam information since this view could be reused which may contain
    // outdated data.
    viewHolder.isSpam = false;
    viewHolder.blockId = null;
    viewHolder.isSpamFeatureEnabled = false;

    // Attempt to set the isCallComposerCapable field. If capabilities are unknown for this number,
    // the value will be false while capabilities are requested. mExpandCollapseListener will
    // attempt to set the field properly in that case
    viewHolder.isCallComposerCapable = isCallComposerCapable(viewHolder.number);
    viewHolder.setDetailedPhoneDetails(callDetailsEntries);
    final AsyncTask<Void, Void, Boolean> loadDataTask =
        new AsyncTask<Void, Void, Boolean>() {
          @Override
          protected Boolean doInBackground(Void... params) {
            viewHolder.blockId =
                filteredNumberAsyncQueryHandler.getBlockedIdSynchronous(
                    viewHolder.number, viewHolder.countryIso);
            details.isBlocked = viewHolder.blockId != null;
            if (isCancelled()) {
              return false;
            }
            if (isSpamEnabled) {
              viewHolder.isSpamFeatureEnabled = true;
              // Only display the call as a spam call if there are incoming calls in the list.
              // Call log cards with only outgoing calls should never be displayed as spam.
              viewHolder.isSpam =
                  details.hasIncomingCalls()
                      && SpamComponent.get(activity)
                          .spam()
                          .checkSpamStatusSynchronous(viewHolder.number, viewHolder.countryIso);
              details.isSpam = viewHolder.isSpam;
            }
            return !isCancelled() && loadData(viewHolder, rowId, details);
          }

          @Override
          protected void onPostExecute(Boolean success) {
            viewHolder.isLoaded = true;
            if (success) {
              viewHolder.callbackAction = getCallbackAction(viewHolder.rowId);
              int currentDayGroup = getDayGroup(viewHolder.rowId);
              if (currentDayGroup != details.previousGroup) {
                viewHolder.dayGroupHeaderVisibility = View.VISIBLE;
                viewHolder.dayGroupHeaderText = getGroupDescription(currentDayGroup);
              } else {
                viewHolder.dayGroupHeaderVisibility = View.GONE;
              }
              render(viewHolder, details, rowId);
            }
          }
        };

    viewHolder.asyncTask = loadDataTask;
    asyncTaskExecutor.submit(LOAD_DATA_TASK_IDENTIFIER, loadDataTask);
  }

  @MainThread
  private boolean isCallComposerCapable(@Nullable String number) {
    if (number == null) {
      return false;
    }

    EnrichedCallCapabilities capabilities = getEnrichedCallManager().getCapabilities(number);
    if (capabilities == null) {
      getEnrichedCallManager().requestCapabilities(number);
      return false;
    }
    return capabilities.isCallComposerCapable();
  }

  /**
   * Initialize PhoneCallDetails by reading all data from cursor. This method must be run on main
   * thread since cursor is not thread safe.
   */
  @MainThread
  private PhoneCallDetails createPhoneCallDetails(
      Cursor cursor, int count, final CallLogListItemViewHolder views) {
    Assert.isMainThread();
    final String number = cursor.getString(CallLogQuery.NUMBER);
    final String postDialDigits = cursor.getString(CallLogQuery.POST_DIAL_DIGITS);
    final String viaNumber = cursor.getString(CallLogQuery.VIA_NUMBER);
    final int numberPresentation = cursor.getInt(CallLogQuery.NUMBER_PRESENTATION);
    final ContactInfo cachedContactInfo = ContactInfoHelper.getContactInfo(cursor);
    final int transcriptionState =
        (VERSION.SDK_INT >= VERSION_CODES.O)
            ? cursor.getInt(CallLogQuery.TRANSCRIPTION_STATE)
            : VoicemailCompat.TRANSCRIPTION_NOT_STARTED;
    final PhoneCallDetails details =
        new PhoneCallDetails(number, numberPresentation, postDialDigits);
    details.viaNumber = viaNumber;
    details.countryIso = cursor.getString(CallLogQuery.COUNTRY_ISO);
    details.date = cursor.getLong(CallLogQuery.DATE);
    details.duration = cursor.getLong(CallLogQuery.DURATION);
    details.features = getCallFeatures(cursor, count);
    details.geocode = cursor.getString(CallLogQuery.GEOCODED_LOCATION);
    details.transcription = cursor.getString(CallLogQuery.TRANSCRIPTION);
    details.transcriptionState = transcriptionState;
    details.callTypes = getCallTypes(cursor, count);

    details.accountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
    details.accountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
    details.cachedContactInfo = cachedContactInfo;

    if (!cursor.isNull(CallLogQuery.DATA_USAGE)) {
      details.dataUsage = cursor.getLong(CallLogQuery.DATA_USAGE);
    }

    views.rowId = cursor.getLong(CallLogQuery.ID);
    // Stash away the Ids of the calls so that we can support deleting a row in the call log.
    views.callIds = getCallIds(cursor, count);
    details.previousGroup = getPreviousDayGroup(cursor);

    // Store values used when the actions ViewStub is inflated on expansion.
    views.number = number;
    views.countryIso = details.countryIso;
    views.postDialDigits = details.postDialDigits;
    views.numberPresentation = numberPresentation;

    if (details.callTypes[0] == CallLog.Calls.VOICEMAIL_TYPE
        || details.callTypes[0] == CallLog.Calls.MISSED_TYPE) {
      details.isRead = cursor.getInt(CallLogQuery.IS_READ) == 1;
    }
    views.callType = cursor.getInt(CallLogQuery.CALL_TYPE);
    views.voicemailUri = cursor.getString(CallLogQuery.VOICEMAIL_URI);
    details.voicemailUri = views.voicemailUri;

    return details;
  }

  @MainThread
  private CallDetailsEntries createCallDetailsEntries(Cursor cursor, int count) {
    Assert.isMainThread();
    int position = cursor.getPosition();
    CallDetailsEntries.Builder entries = CallDetailsEntries.newBuilder();
    for (int i = 0; i < count; i++) {
      CallDetailsEntry.Builder entry =
          CallDetailsEntry.newBuilder()
              .setCallId(cursor.getLong(CallLogQuery.ID))
              .setCallType(cursor.getInt(CallLogQuery.CALL_TYPE))
              .setDataUsage(cursor.getLong(CallLogQuery.DATA_USAGE))
              .setDate(cursor.getLong(CallLogQuery.DATE))
              .setDuration(cursor.getLong(CallLogQuery.DURATION))
              .setFeatures(cursor.getInt(CallLogQuery.FEATURES))

              .setCallMappingId(String.valueOf(cursor.getLong(CallLogQuery.DATE)));


      String phoneAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
      if (DuoComponent.get(activity).getDuo().isDuoAccount(phoneAccountComponentName)) {
        entry.setIsDuoCall(true);
      }

      entries.addEntries(entry.build());
      cursor.moveToNext();
    }
    cursor.moveToPosition(position);
    return entries.build();
  }

  /**
   * Load data for call log. Any expensive operation should be put here to avoid blocking main
   * thread. Do NOT put any cursor operation here since it's not thread safe.
   */
  @WorkerThread
  private boolean loadData(CallLogListItemViewHolder views, long rowId, PhoneCallDetails details) {
    Assert.isWorkerThread();
    if (rowId != views.rowId) {
      LogUtil.i(
          "CallLogAdapter.loadData",
          "rowId of viewHolder changed after load task is issued, aborting load");
      return false;
    }

    final PhoneAccountHandle accountHandle =
        TelecomUtil.composePhoneAccountHandle(details.accountComponentName, details.accountId);

    final boolean isVoicemailNumber = callLogCache.isVoicemailNumber(accountHandle, details.number);

    // Note: Binding of the action buttons is done as required in configureActionViews when the
    // user expands the actions ViewStub.

    ContactInfo info = ContactInfo.EMPTY;
    if (PhoneNumberHelper.canPlaceCallsTo(details.number, details.numberPresentation)
        && !isVoicemailNumber) {
      // Lookup contacts with this number
      // Only do remote lookup in first 5 rows.
      int position = views.getAdapterPosition();
      info =
          contactInfoCache.getValue(
              details.number + details.postDialDigits,
              details.countryIso,
              details.cachedContactInfo,
              position
                  < ConfigProviderComponent.get(activity)
                      .getConfigProvider()
                      .getLong("number_of_call_to_do_remote_lookup", 5L));
      logCp2Metrics(details, info);
    }
    CharSequence formattedNumber =
        info.formattedNumber == null
            ? null
            : PhoneNumberUtils.createTtsSpannable(info.formattedNumber);
    details.updateDisplayNumber(activity, formattedNumber, isVoicemailNumber);

    views.displayNumber = details.displayNumber;
    views.accountHandle = accountHandle;
    details.accountHandle = accountHandle;

    if (!TextUtils.isEmpty(info.name) || !TextUtils.isEmpty(info.nameAlternative)) {
      details.contactUri = info.lookupUri;
      details.namePrimary = info.name;
      details.nameAlternative = info.nameAlternative;
      details.nameDisplayOrder =
          ContactsComponent.get(activity).contactDisplayPreferences().getDisplayOrder();
      details.numberType = info.type;
      details.numberLabel = info.label;
      details.photoUri = info.photoUri;
      details.sourceType = info.sourceType;
      details.objectId = info.objectId;
      details.contactUserType = info.userType;
    }
    LogUtil.d(
        "CallLogAdapter.loadData",
        "position:%d, update geo info: %s, cequint caller id geo: %s, photo uri: %s <- %s",
        views.getAdapterPosition(),
        details.geocode,
        info.geoDescription,
        details.photoUri,
        info.photoUri);
    if (!TextUtils.isEmpty(info.geoDescription)) {
      details.geocode = info.geoDescription;
    }

    views.info = info;
    views.numberType = getNumberType(activity.getResources(), details);

    callLogListItemHelper.updatePhoneCallDetails(details);
    return true;
  }

  private static String getNumberType(Resources res, PhoneCallDetails details) {
    // Label doesn't make much sense if the information is coming from CNAP or Cequint Caller ID.
    if (details.sourceType == ContactSource.Type.SOURCE_TYPE_CNAP
        || details.sourceType == ContactSource.Type.SOURCE_TYPE_CEQUINT_CALLER_ID) {
      return "";
    }
    // Returns empty label instead of "custom" if the custom label is empty.
    if (details.numberType == Phone.TYPE_CUSTOM && TextUtils.isEmpty(details.numberLabel)) {
      return "";
    }
    return (String) Phone.getTypeLabel(res, details.numberType, details.numberLabel);
  }

  /**
   * Render item view given position. This is running on UI thread so DO NOT put any expensive
   * operation into it.
   */
  @MainThread
  private void render(CallLogListItemViewHolder views, PhoneCallDetails details, long rowId) {
    Assert.isMainThread();
    if (rowId != views.rowId) {
      LogUtil.i(
          "CallLogAdapter.render",
          "rowId of viewHolder changed after load task is issued, aborting render");
      return;
    }

    // Default case: an item in the call log.
    views.primaryActionView.setVisibility(View.VISIBLE);
    views.workIconView.setVisibility(
        details.contactUserType == ContactsUtils.USER_TYPE_WORK ? View.VISIBLE : View.GONE);

    if (selectAllMode && views.voicemailUri != null) {
      selectedItems.put(getVoicemailId(views.voicemailUri), views.voicemailUri);
    }
    if (deselectAllMode && views.voicemailUri != null) {
      selectedItems.delete(getVoicemailId(views.voicemailUri));
    }
    if (views.voicemailUri != null
        && selectedItems.get(getVoicemailId(views.voicemailUri)) != null) {
      views.checkBoxView.setVisibility(View.VISIBLE);
      views.quickContactView.setVisibility(View.GONE);
    } else if (views.voicemailUri != null) {
      views.checkBoxView.setVisibility(View.GONE);
      views.quickContactView.setVisibility(View.VISIBLE);
    }
    callLogListItemHelper.setPhoneCallDetails(views, details);
    if (currentlyExpandedRowId == views.rowId) {
      // In case ViewHolders were added/removed, update the expanded position if the rowIds
      // match so that we can restore the correct expanded state on rebind.
      currentlyExpandedPosition = views.getAdapterPosition();
      views.showActions(true);
    } else {
      views.showActions(false);
    }
    views.dayGroupHeader.setVisibility(views.dayGroupHeaderVisibility);
    views.dayGroupHeader.setText(views.dayGroupHeaderText);
  }

  @Override
  public int getItemCount() {
    return super.getItemCount() + (callLogAlertManager.isEmpty() ? 0 : 1);
  }

  @Override
  public int getItemViewType(int position) {
    if (position == ALERT_POSITION && !callLogAlertManager.isEmpty()) {
      return VIEW_TYPE_ALERT;
    }
    return VIEW_TYPE_CALLLOG;
  }

  /**
   * Retrieves an item at the specified position, taking into account the presence of a promo card.
   *
   * @param position The position to retrieve.
   * @return The item at that position.
   */
  @Override
  public Object getItem(int position) {
    return super.getItem(position - (callLogAlertManager.isEmpty() ? 0 : 1));
  }

  @Override
  public long getItemId(int position) {
    Cursor cursor = (Cursor) getItem(position);
    if (cursor != null) {
      return cursor.getLong(CallLogQuery.ID);
    } else {
      return 0;
    }
  }

  @Override
  public int getGroupSize(int position) {
    return super.getGroupSize(position - (callLogAlertManager.isEmpty() ? 0 : 1));
  }

  protected boolean isCallLogActivity() {
    return activityType == ACTIVITY_TYPE_CALL_LOG;
  }

  /**
   * In order to implement the "undo" function, when a voicemail is "deleted" i.e. when the user
   * clicks the delete button, the deleted item is temporarily hidden from the list. If a user
   * clicks delete on a second item before the first item's undo option has expired, the first item
   * is immediately deleted so that only one item can be "undoed" at a time.
   */
  @Override
  public void onVoicemailDeleted(CallLogListItemViewHolder viewHolder, Uri uri) {
    hiddenRowIds.add(viewHolder.rowId);
    // Save the new hidden item uri in case the activity is suspend before the undo has timed out.
    hiddenItemUris.add(uri);

    collapseExpandedCard();
    notifyItemChanged(viewHolder.getAdapterPosition());
    // The next item might have to update its day group label
    notifyItemChanged(viewHolder.getAdapterPosition() + 1);
  }

  private void collapseExpandedCard() {
    currentlyExpandedRowId = NO_EXPANDED_LIST_ITEM;
    currentlyExpandedPosition = RecyclerView.NO_POSITION;
  }

  /** When the list is changing all stored position is no longer valid. */
  public void invalidatePositions() {
    currentlyExpandedPosition = RecyclerView.NO_POSITION;
  }

  /** When the user clicks "undo", the hidden item is unhidden. */
  @Override
  public void onVoicemailDeleteUndo(long rowId, int adapterPosition, Uri uri) {
    hiddenItemUris.remove(uri);
    hiddenRowIds.remove(rowId);
    notifyItemChanged(adapterPosition);
    // The next item might have to update its day group label
    notifyItemChanged(adapterPosition + 1);
  }

  /** This callback signifies that a database deletion has completed. */
  @Override
  public void onVoicemailDeletedInDatabase(long rowId, Uri uri) {
    hiddenItemUris.remove(uri);
  }

  /**
   * Retrieves the day group of the previous call in the call log. Used to determine if the day
   * group has changed and to trigger display of the day group text.
   *
   * @param cursor The call log cursor.
   * @return The previous day group, or DAY_GROUP_NONE if this is the first call.
   */
  private int getPreviousDayGroup(Cursor cursor) {
    // We want to restore the position in the cursor at the end.
    int startingPosition = cursor.getPosition();
    moveToPreviousNonHiddenRow(cursor);
    if (cursor.isBeforeFirst()) {
      cursor.moveToPosition(startingPosition);
      return CallLogGroupBuilder.DAY_GROUP_NONE;
    }
    int result = getDayGroup(cursor.getLong(CallLogQuery.ID));
    cursor.moveToPosition(startingPosition);
    return result;
  }

  private void moveToPreviousNonHiddenRow(Cursor cursor) {
    while (cursor.moveToPrevious() && hiddenRowIds.contains(cursor.getLong(CallLogQuery.ID))) {}
  }

  /**
   * Given a call ID, look up its callback action. Callback action data are populated in {@link
   * com.android.dialer.app.calllog.CallLogGroupBuilder}.
   *
   * @param callId The call ID to retrieve the callback action.
   * @return The callback action for the call.
   */
  @MainThread
  private int getCallbackAction(long callId) {
    Integer result = callbackActions.get(callId);
    if (result != null) {
      return result;
    }
    return CallbackAction.NONE;
  }

  /**
   * Given a call ID, look up the day group the call belongs to. Day group data are populated in
   * {@link com.android.dialer.app.calllog.CallLogGroupBuilder}.
   *
   * @param callId The call ID to retrieve the day group.
   * @return The day group for the call.
   */
  @MainThread
  private int getDayGroup(long callId) {
    Integer result = dayGroups.get(callId);
    if (result != null) {
      return result;
    }
    return CallLogGroupBuilder.DAY_GROUP_NONE;
  }

  /**
   * Returns the call types for the given number of items in the cursor.
   *
   * <p>It uses the next {@code count} rows in the cursor to extract the types.
   *
   * <p>It position in the cursor is unchanged by this function.
   */
  private static int[] getCallTypes(Cursor cursor, int count) {
    int position = cursor.getPosition();
    int[] callTypes = new int[count];
    for (int index = 0; index < count; ++index) {
      callTypes[index] = cursor.getInt(CallLogQuery.CALL_TYPE);
      cursor.moveToNext();
    }
    cursor.moveToPosition(position);
    return callTypes;
  }

  /**
   * Determine the features which were enabled for any of the calls that make up a call log entry.
   *
   * @param cursor The cursor.
   * @param count The number of calls for the current call log entry.
   * @return The features.
   */
  private int getCallFeatures(Cursor cursor, int count) {
    int features = 0;
    int position = cursor.getPosition();
    for (int index = 0; index < count; ++index) {
      features |= cursor.getInt(CallLogQuery.FEATURES);
      cursor.moveToNext();
    }
    cursor.moveToPosition(position);
    return features;
  }

  /**
   * Sets whether processing of requests for contact details should be enabled.
   *
   * <p>This method should be called in tests to disable such processing of requests when not
   * needed.
   */
  @VisibleForTesting
  void disableRequestProcessingForTest() {
    // TODO: Remove this and test the cache directly.
    contactInfoCache.disableRequestProcessing();
  }

  @VisibleForTesting
  void injectContactInfoForTest(String number, String countryIso, ContactInfo contactInfo) {
    // TODO: Remove this and test the cache directly.
    contactInfoCache.injectContactInfoForTest(number, countryIso, contactInfo);
  }

  /**
   * Stores the callback action associated with a call in the call log.
   *
   * @param rowId The row ID of the current call.
   * @param callbackAction The current call's callback action.
   */
  @Override
  @MainThread
  public void setCallbackAction(long rowId, @CallbackAction int callbackAction) {
    callbackActions.put(rowId, callbackAction);
  }

  /**
   * Stores the day group associated with a call in the call log.
   *
   * @param rowId The row ID of the current call.
   * @param dayGroup The day group the call belongs in.
   */
  @Override
  @MainThread
  public void setDayGroup(long rowId, int dayGroup) {
    dayGroups.put(rowId, dayGroup);
  }

  /** Clears the day group associations on re-bind of the call log. */
  @Override
  @MainThread
  public void clearDayGroups() {
    dayGroups.clear();
  }

  /**
   * Retrieves the call Ids represented by the current call log row.
   *
   * @param cursor Call log cursor to retrieve call Ids from.
   * @param groupSize Number of calls associated with the current call log row.
   * @return Array of call Ids.
   */
  private long[] getCallIds(final Cursor cursor, final int groupSize) {
    // We want to restore the position in the cursor at the end.
    int startingPosition = cursor.getPosition();
    long[] ids = new long[groupSize];
    // Copy the ids of the rows in the group.
    for (int index = 0; index < groupSize; ++index) {
      ids[index] = cursor.getLong(CallLogQuery.ID);
      cursor.moveToNext();
    }
    cursor.moveToPosition(startingPosition);
    return ids;
  }

  /**
   * Determines the description for a day group.
   *
   * @param group The day group to retrieve the description for.
   * @return The day group description.
   */
  private CharSequence getGroupDescription(int group) {
    if (group == CallLogGroupBuilder.DAY_GROUP_TODAY) {
      return activity.getResources().getString(R.string.call_log_header_today);
    } else if (group == CallLogGroupBuilder.DAY_GROUP_YESTERDAY) {
      return activity.getResources().getString(R.string.call_log_header_yesterday);
    } else {
      return activity.getResources().getString(R.string.call_log_header_other);
    }
  }

  @NonNull
  private EnrichedCallManager getEnrichedCallManager() {
    return EnrichedCallComponent.get(activity).getEnrichedCallManager();
  }

  @NonNull
  private Duo getDuo() {
    return DuoComponent.get(activity).getDuo();
  }

  @Override
  public void onDuoStateChanged() {
    notifyDataSetChanged();
  }

  public void onAllSelected() {
    selectAllMode = true;
    deselectAllMode = false;
    selectedItems.clear();
    for (int i = 0; i < getItemCount(); i++) {
      Cursor c = (Cursor) getItem(i);
      if (c != null) {
        Assert.checkArgument(CallLogQuery.VOICEMAIL_URI == c.getColumnIndex("voicemail_uri"));
        String voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI);
        selectedItems.put(getVoicemailId(voicemailUri), voicemailUri);
      }
    }
    updateActionBar();
    notifyDataSetChanged();
  }

  public void onAllDeselected() {
    selectAllMode = false;
    deselectAllMode = true;
    selectedItems.clear();
    updateActionBar();
    notifyDataSetChanged();
  }

  private void logCp2Metrics(PhoneCallDetails details, ContactInfo contactInfo) {
    if (details == null) {
      return;
    }
    CharSequence inputNumber = details.number;
    if (inputNumber == null) {
      return;
    }

    ContactsProviderMatchInfo.Builder matchInfo =
        ContactsProviderMatchInfo.builder()
            .setInputNumberLength(PhoneNumberUtils.normalizeNumber(inputNumber.toString()).length())
            .setInputNumberHasPostdialDigits(
                !PhoneNumberUtils.extractPostDialPortion(inputNumber.toString()).isEmpty()
                    || (details.postDialDigits != null && !details.postDialDigits.isEmpty()));

    PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
    try {
      PhoneNumber phoneNumber = phoneNumberUtil.parse(inputNumber, details.countryIso);
      matchInfo.setInputNumberValid(phoneNumberUtil.isValidNumber(phoneNumber));
    } catch (NumberParseException e) {
      // Do nothing
      matchInfo.setInputNumberValid(false);
    }

    if (contactInfo != null
        && contactInfo.number != null
        && contactInfo.sourceType == Type.SOURCE_TYPE_DIRECTORY) {
      matchInfo
          .setMatchedContact(true)
          .setMatchedNumberLength(PhoneNumberUtils.normalizeNumber(contactInfo.number).length())
          .setMatchedNumberHasPostdialDigits(
              !PhoneNumberUtils.extractPostDialPortion(contactInfo.number).isEmpty());
    }

    contactsProviderMatchInfos.put(inputNumber.toString(), matchInfo.build());
  }

  /** Interface used to initiate a refresh of the content. */
  public interface CallFetcher {

    void fetchCalls();
  }

  /** Interface used to allow single tap multi select for contact photos. */
  public interface OnActionModeStateChangedListener {

    void onActionModeStateChanged(ActionMode mode, boolean isEnabled);

    boolean isActionModeStateEnabled();
  }

  /** Interface used to hide the fragments. */
  public interface MultiSelectRemoveView {

    void showMultiSelectRemoveView(boolean show);

    void setSelectAllModeToFalse();

    void tapSelectAll();
  }
}
