From dcefa65cf08671b748d549a2cdd169c5d2530415 Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Mon, 14 Aug 2017 12:07:47 -0700 Subject: Added ability to place RCS, Duo and IMS calls from new search fragment. Bug: 37209462 Test: SearchAdapterTest + existing tests PiperOrigin-RevId: 165210817 Change-Id: I9fb78cf7d964b97e6e95c01437780aa66405f019 --- .../cp2/SearchContactViewHolder.java | 133 +++++++++++++++++---- 1 file changed, 112 insertions(+), 21 deletions(-) (limited to 'java/com/android/dialer/searchfragment/cp2') diff --git a/java/com/android/dialer/searchfragment/cp2/SearchContactViewHolder.java b/java/com/android/dialer/searchfragment/cp2/SearchContactViewHolder.java index 1e8224ddb..327fe5303 100644 --- a/java/com/android/dialer/searchfragment/cp2/SearchContactViewHolder.java +++ b/java/com/android/dialer/searchfragment/cp2/SearchContactViewHolder.java @@ -23,6 +23,7 @@ import android.net.Uri; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; import android.support.annotation.IntDef; +import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView.ViewHolder; import android.text.TextUtils; import android.view.View; @@ -30,16 +31,19 @@ import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.QuickContactBadge; import android.widget.TextView; -import com.android.dialer.callintent.CallInitiationType.Type; -import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.Assert; import com.android.dialer.contactphoto.ContactPhotoManager; +import com.android.dialer.dialercontact.DialerContact; +import com.android.dialer.enrichedcall.EnrichedCallCapabilities; +import com.android.dialer.enrichedcall.EnrichedCallComponent; +import com.android.dialer.enrichedcall.EnrichedCallManager; import com.android.dialer.lettertile.LetterTileDrawable; +import com.android.dialer.lightbringer.LightbringerComponent; import com.android.dialer.searchfragment.common.Projections; import com.android.dialer.searchfragment.common.QueryBoldingUtil; import com.android.dialer.searchfragment.common.R; +import com.android.dialer.searchfragment.common.RowClickListener; import com.android.dialer.searchfragment.common.SearchCursor; -import com.android.dialer.telecom.TelecomUtil; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -48,24 +52,34 @@ public final class SearchContactViewHolder extends ViewHolder implements OnClick /** IntDef for the different types of actions that can be shown. */ @Retention(RetentionPolicy.SOURCE) - @IntDef({CallToAction.NONE, CallToAction.VIDEO_CALL, CallToAction.SHARE_AND_CALL}) + @IntDef({ + CallToAction.NONE, + CallToAction.VIDEO_CALL, + CallToAction.DUO_CALL, + CallToAction.SHARE_AND_CALL + }) @interface CallToAction { int NONE = 0; int VIDEO_CALL = 1; - int SHARE_AND_CALL = 2; + int DUO_CALL = 2; + int SHARE_AND_CALL = 3; } + private final RowClickListener listener; private final QuickContactBadge photo; private final TextView nameOrNumberView; private final TextView numberView; private final ImageView callToActionView; private final Context context; + private int position; private String number; + private DialerContact dialerContact; private @CallToAction int currentAction; - public SearchContactViewHolder(View view) { + public SearchContactViewHolder(View view, RowClickListener listener) { super(view); + this.listener = listener; view.setOnClickListener(this); photo = view.findViewById(R.id.photo); nameOrNumberView = view.findViewById(R.id.primary); @@ -79,6 +93,8 @@ public final class SearchContactViewHolder extends ViewHolder implements OnClick * at the cursors set position. */ public void bind(SearchCursor cursor, String query) { + dialerContact = getDialerContact(context, cursor); + position = cursor.getPosition(); number = cursor.getString(Projections.PHONE_NUMBER); String name = cursor.getString(Projections.PHONE_DISPLAY_NAME); String label = getLabel(context.getResources(), cursor); @@ -90,7 +106,7 @@ public final class SearchContactViewHolder extends ViewHolder implements OnClick nameOrNumberView.setText(QueryBoldingUtil.getNameWithQueryBolded(query, name)); numberView.setText(QueryBoldingUtil.getNumberWithQueryBolded(query, secondaryInfo)); - setCallToAction(cursor); + setCallToAction(cursor, query); if (shouldShowPhoto(cursor)) { nameOrNumberView.setVisibility(View.VISIBLE); @@ -144,8 +160,8 @@ public final class SearchContactViewHolder extends ViewHolder implements OnClick return (String) Phone.getTypeLabel(resources, numberType, numberLabel); } - private void setCallToAction(Cursor cursor) { - currentAction = getCallToAction(cursor); + private void setCallToAction(SearchCursor cursor, String query) { + currentAction = getCallToAction(context, cursor, query); switch (currentAction) { case CallToAction.NONE: callToActionView.setVisibility(View.GONE); @@ -157,6 +173,7 @@ public final class SearchContactViewHolder extends ViewHolder implements OnClick context.getDrawable(com.android.contacts.common.R.drawable.ic_phone_attach)); callToActionView.setOnClickListener(this); break; + case CallToAction.DUO_CALL: case CallToAction.VIDEO_CALL: callToActionView.setVisibility(View.VISIBLE); callToActionView.setImageDrawable( @@ -169,31 +186,69 @@ public final class SearchContactViewHolder extends ViewHolder implements OnClick } } - private static @CallToAction int getCallToAction(Cursor cursor) { + private static @CallToAction int getCallToAction( + Context context, SearchCursor cursor, String query) { int carrierPresence = cursor.getInt(Projections.PHONE_CARRIER_PRESENCE); + String number = cursor.getString(Projections.PHONE_NUMBER); if ((carrierPresence & Phone.CARRIER_PRESENCE_VT_CAPABLE) == 1) { return CallToAction.VIDEO_CALL; } - // TODO(calderwoodra): enriched calling + if (LightbringerComponent.get(context).getLightbringer().isReachable(context, number)) { + return CallToAction.DUO_CALL; + } + + EnrichedCallManager manager = EnrichedCallComponent.get(context).getEnrichedCallManager(); + EnrichedCallCapabilities capabilities = manager.getCapabilities(number); + if (capabilities != null && capabilities.isCallComposerCapable()) { + return CallToAction.SHARE_AND_CALL; + } else if (shouldRequestCapabilities(cursor, capabilities, query)) { + manager.requestCapabilities(number); + } return CallToAction.NONE; } + /** + * An RPC is initiated for each number we request capabilities for, so to limit the network load + * and latency on slow networks, we only want to request capabilities for potential contacts the + * user is interested in calling. The requirements are that: + * + * + */ + private static boolean shouldRequestCapabilities( + SearchCursor cursor, + @Nullable EnrichedCallCapabilities capabilities, + @Nullable String query) { + if (capabilities != null) { + return false; + } + + if (query != null && query.length() >= 3) { + return true; + } + + // TODO(calderwoodra): implement SearchCursor#getHeaderCount + if (cursor.getCount() <= 5) { // 4 contacts + 1 header row element + return true; + } + return false; + } + @Override public void onClick(View view) { if (view == callToActionView) { switch (currentAction) { case CallToAction.SHARE_AND_CALL: - callToActionView.setVisibility(View.VISIBLE); - callToActionView.setImageDrawable( - context.getDrawable(com.android.contacts.common.R.drawable.ic_phone_attach)); - // TODO(calderwoodra): open call composer. + listener.openCallAndShare(dialerContact); break; case CallToAction.VIDEO_CALL: - callToActionView.setVisibility(View.VISIBLE); - callToActionView.setImageDrawable( - context.getDrawable(R.drawable.quantum_ic_videocam_white_24)); - // TODO(calderwoodra): place a video call + listener.placeVideoCall(number, position); + break; + case CallToAction.DUO_CALL: + listener.placeDuoCall(number); break; case CallToAction.NONE: default: @@ -201,8 +256,44 @@ public final class SearchContactViewHolder extends ViewHolder implements OnClick "Invalid Call to action type: " + currentAction); } } else { - // TODO(calderwoodra): set the correct call initiation type. - TelecomUtil.placeCall(context, new CallIntentBuilder(number, Type.REGULAR_SEARCH).build()); + listener.placeVoiceCall(number, position); + } + } + + private static DialerContact getDialerContact(Context context, Cursor cursor) { + DialerContact.Builder contact = DialerContact.newBuilder(); + String displayName = cursor.getString(Projections.PHONE_DISPLAY_NAME); + String number = cursor.getString(Projections.PHONE_NUMBER); + Uri contactUri = + Contacts.getLookupUri( + cursor.getLong(Projections.PHONE_CONTACT_ID), + cursor.getString(Projections.PHONE_LOOKUP_KEY)); + + contact + .setNumber(number) + .setPhotoId(cursor.getLong(Projections.PHONE_PHOTO_ID)) + .setContactType(LetterTileDrawable.TYPE_DEFAULT) + .setNameOrNumber(displayName) + .setNumberLabel( + Phone.getTypeLabel( + context.getResources(), + cursor.getInt(Projections.PHONE_TYPE), + cursor.getString(Projections.PHONE_LABEL)) + .toString()); + + String photoUri = cursor.getString(Projections.PHONE_PHOTO_URI); + if (photoUri != null) { + contact.setPhotoUri(photoUri); } + + if (contactUri != null) { + contact.setContactUri(contactUri.toString()); + } + + if (!TextUtils.isEmpty(displayName)) { + contact.setDisplayNumber(number); + } + + return contact.build(); } } -- cgit v1.2.3