Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 976c9542 authored by calderwoodra's avatar calderwoodra Committed by android-build-merger
Browse files

Merge "Implemented adding a new favorites contact flow NUI." am: aab6dc9f am: b1b02122

am: 9d6eccbb

Change-Id: I2f5eccf26e061c7ad683f43c150afb790ee93ba7
parents f7b6d08b 9d6eccbb
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ 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.MainThread;
import android.support.annotation.NonNull;
@@ -59,6 +60,7 @@ 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;
@@ -101,6 +103,7 @@ import com.android.dialer.common.concurrent.ThreadUtil;
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;
@@ -109,6 +112,7 @@ import com.android.dialer.dialpadview.DialpadFragment.LastOutgoingCallCallback;
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.LoggingBindings;
import com.android.dialer.logging.ScreenEvent;
@@ -166,7 +170,8 @@ public class DialtactsActivity extends TransactionSafeActivity
        PhoneNumberInteraction.DisambigDialogDismissedListener,
        ActivityCompat.OnRequestPermissionsResultCallback,
        DialpadListener,
        SearchFragmentListener {
        SearchFragmentListener,
        OnContactSelectedListener {

  public static final boolean DEBUG = false;
  @VisibleForTesting public static final String TAG_DIALPAD_FRAGMENT = "dialpad";
@@ -1695,6 +1700,14 @@ public class DialtactsActivity extends TransactionSafeActivity
    return mPreviouslySelectedTabIndex;
  }

  @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 {

+1 −3
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.dialer.contactsfragment.ContactsFragment;
import com.android.dialer.contactsfragment.ContactsFragment.ClickAction;
import com.android.dialer.contactsfragment.ContactsFragment.Header;
import com.android.dialer.database.CallLogQueryHandler;
import com.android.dialer.speeddial.SpeedDialFragment;
@@ -108,8 +107,7 @@ public class DialtactsPagerAdapter extends FragmentPagerAdapter {
      case TAB_INDEX_ALL_CONTACTS:
        if (useNewContactsTab) {
          if (contactsFragment == null) {
            contactsFragment =
                ContactsFragment.newInstance(Header.ADD_CONTACT, ClickAction.OPEN_CONTACT_CARD);
            contactsFragment = ContactsFragment.newInstance(Header.ADD_CONTACT);
          }
          return contactsFragment;
        } else {
+9 −22
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.dialer.contactsfragment;

import android.content.Context;
import android.net.Uri;
import android.provider.ContactsContract.QuickContact;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
@@ -26,7 +25,7 @@ import android.view.View.OnClickListener;
import android.widget.QuickContactBadge;
import android.widget.TextView;
import com.android.dialer.common.Assert;
import com.android.dialer.contactsfragment.ContactsFragment.ClickAction;
import com.android.dialer.contactsfragment.ContactsFragment.OnContactSelectedListener;
import com.android.dialer.logging.InteractionEvent;
import com.android.dialer.logging.Logger;

@@ -37,20 +36,20 @@ final class ContactViewHolder extends RecyclerView.ViewHolder implements OnClick
  private final TextView name;
  private final QuickContactBadge photo;
  private final Context context;
  private final @ClickAction int clickAction;
  private final OnContactSelectedListener onContactSelectedListener;

  private String headerText;
  private Uri contactUri;
  private long contactId;

  ContactViewHolder(View itemView, @ClickAction int clickAction) {
  ContactViewHolder(View itemView, OnContactSelectedListener onContactSelectedListener) {
    super(itemView);
    Assert.checkArgument(clickAction != ClickAction.INVALID, "Invalid click action.");
    this.onContactSelectedListener = Assert.isNotNull(onContactSelectedListener);
    context = itemView.getContext();
    itemView.findViewById(R.id.click_target).setOnClickListener(this);
    header = itemView.findViewById(R.id.header);
    name = itemView.findViewById(R.id.contact_name);
    photo = itemView.findViewById(R.id.photo);
    this.clickAction = clickAction;
  }

  /**
@@ -61,9 +60,11 @@ final class ContactViewHolder extends RecyclerView.ViewHolder implements OnClick
   * @param contactUri to be shown by the contact card on photo click.
   * @param showHeader if header view should be shown {@code True}, {@code False} otherwise.
   */
  public void bind(String headerText, String displayName, Uri contactUri, boolean showHeader) {
  public void bind(
      String headerText, String displayName, Uri contactUri, long contactId, boolean showHeader) {
    Assert.checkArgument(!TextUtils.isEmpty(displayName));
    this.contactUri = contactUri;
    this.contactId = contactId;
    this.headerText = headerText;

    name.setText(displayName);
@@ -89,20 +90,6 @@ final class ContactViewHolder extends RecyclerView.ViewHolder implements OnClick

  @Override
  public void onClick(View v) {
    switch (clickAction) {
      case ClickAction.OPEN_CONTACT_CARD:
        Logger.get(context)
            .logInteraction(InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_CONTACTS_FRAGMENT_ITEM);
        QuickContact.showQuickContact(
            photo.getContext(),
            photo,
            contactUri,
            QuickContact.MODE_LARGE,
            null /* excludeMimes */);
        break;
      case ClickAction.INVALID:
      default:
        throw Assert.createIllegalStateFailException("Invalid click action.");
    }
    onContactSelectedListener.onContactSelected(photo, contactUri, contactId);
  }
}
+13 −7
Original line number Diff line number Diff line
@@ -29,8 +29,8 @@ import android.view.ViewGroup;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.contactphoto.ContactPhotoManager;
import com.android.dialer.contactsfragment.ContactsFragment.ClickAction;
import com.android.dialer.contactsfragment.ContactsFragment.Header;
import com.android.dialer.contactsfragment.ContactsFragment.OnContactSelectedListener;
import com.android.dialer.lettertile.LetterTileDrawable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -50,7 +50,7 @@ final class ContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
  private final ArrayMap<ContactViewHolder, Integer> holderMap = new ArrayMap<>();
  private final Context context;
  private final @Header int header;
  private final @ClickAction int clickAction;
  private final OnContactSelectedListener onContactSelectedListener;

  // List of contact sublist headers
  private String[] headers = new String[0];
@@ -59,10 +59,11 @@ final class ContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
  // Cursor with list of contacts
  private Cursor cursor;

  ContactsAdapter(Context context, @Header int header, @ClickAction int clickAction) {
  ContactsAdapter(
      Context context, @Header int header, OnContactSelectedListener onContactSelectedListener) {
    this.context = context;
    this.header = header;
    this.clickAction = clickAction;
    this.onContactSelectedListener = Assert.isNotNull(onContactSelectedListener);
  }

  void updateCursor(Cursor cursor) {
@@ -92,7 +93,8 @@ final class ContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
            LayoutInflater.from(context).inflate(R.layout.add_contact_row, parent, false));
      case CONTACT_VIEW_TYPE:
        return new ContactViewHolder(
            LayoutInflater.from(context).inflate(R.layout.contact_row, parent, false), clickAction);
            LayoutInflater.from(context).inflate(R.layout.contact_row, parent, false),
            onContactSelectedListener);
      case UNKNOWN_VIEW_TYPE:
      default:
        throw Assert.createIllegalStateFailException("Invalid view type: " + viewType);
@@ -133,7 +135,7 @@ final class ContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
    // it to the previous element and only show the anchored header if the row elements fall into
    // the same sublists.
    boolean showHeader = position == 0 || !header.equals(getHeaderString(position - 1));
    contactViewHolder.bind(header, name, contactUri, showHeader);
    contactViewHolder.bind(header, name, contactUri, getContactId(cursor), showHeader);
  }

  /**
@@ -190,11 +192,15 @@ final class ContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
  }

  private static Uri getContactUri(Cursor cursor) {
    long contactId = cursor.getLong(ContactsCursorLoader.CONTACT_ID);
    long contactId = getContactId(cursor);
    String lookupKey = cursor.getString(ContactsCursorLoader.CONTACT_LOOKUP_KEY);
    return Contacts.getLookupUri(contactId, lookupKey);
  }

  private static long getContactId(Cursor cursor) {
    return cursor.getLong(ContactsCursorLoader.CONTACT_ID);
  }

  String getHeaderString(int position) {
    if (header != Header.NONE) {
      if (position == 0) {
+43 −14
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@ package com.android.dialer.contactsfragment;

import android.content.Context;
import android.content.CursorLoader;
import android.net.Uri;
import android.provider.ContactsContract.Contacts;
import android.text.TextUtils;
import com.android.contacts.common.preference.ContactsPreferences;

/** Cursor Loader for {@link ContactsFragment}. */
final class ContactsCursorLoader extends CursorLoader {
@@ -47,26 +50,52 @@ final class ContactsCursorLoader extends CursorLoader {
        Contacts.LOOKUP_KEY, // 4
      };

  private ContactsCursorLoader(Context context, String[] contactProjection, String sortKey) {
  ContactsCursorLoader(Context context, boolean hasPhoneNumbers) {
    super(
        context,
        Contacts.CONTENT_URI
            .buildUpon()
            .appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true")
            .build(),
        contactProjection,
        contactProjection[CONTACT_DISPLAY_NAME] + " IS NOT NULL",
        buildUri(""),
        getProjection(context),
        getWhere(context, hasPhoneNumbers),
        null,
        sortKey + " ASC");
        getSortKey(context) + " ASC");
  }

  public static ContactsCursorLoader createInstanceDisplayNamePrimary(
      Context context, String sortKey) {
    return new ContactsCursorLoader(context, CONTACTS_PROJECTION_DISPLAY_NAME_PRIMARY, sortKey);
  private static String[] getProjection(Context context) {
    ContactsPreferences contactsPrefs = new ContactsPreferences(context);
    boolean displayOrderPrimary =
        (contactsPrefs.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY);
    return displayOrderPrimary
        ? CONTACTS_PROJECTION_DISPLAY_NAME_PRIMARY
        : CONTACTS_PROJECTION_DISPLAY_NAME_ALTERNATIVE;
  }

  public static ContactsCursorLoader createInstanceDisplayNameAlternative(
      Context context, String sortKey) {
    return new ContactsCursorLoader(context, CONTACTS_PROJECTION_DISPLAY_NAME_ALTERNATIVE, sortKey);
  private static String getWhere(Context context, boolean hasPhoneNumbers) {
    String where = getProjection(context)[CONTACT_DISPLAY_NAME] + " IS NOT NULL";
    if (hasPhoneNumbers) {
      where += " AND " + Contacts.HAS_PHONE_NUMBER + "=1";
    }
    return where;
  }

  private static String getSortKey(Context context) {
    ContactsPreferences contactsPrefs = new ContactsPreferences(context);
    boolean sortOrderPrimary =
        (contactsPrefs.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY);
    return sortOrderPrimary ? Contacts.SORT_KEY_PRIMARY : Contacts.SORT_KEY_ALTERNATIVE;
  }

  /** Update cursor loader to filter contacts based on the provided query. */
  public void setQuery(String query) {
    setUri(buildUri(query));
  }

  private static Uri buildUri(String query) {
    Uri.Builder baseUri;
    if (TextUtils.isEmpty(query)) {
      baseUri = Contacts.CONTENT_URI.buildUpon();
    } else {
      baseUri = Contacts.CONTENT_FILTER_URI.buildUpon().appendPath(query);
    }
    return baseUri.appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true").build();
  }
}
Loading