diff options
Diffstat (limited to 'java')
6 files changed, 165 insertions, 33 deletions
diff --git a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java index adf7f1b4e..6067c4239 100644 --- a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java +++ b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java @@ -551,7 +551,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder if (mCallLogCache.isVoicemailNumber(accountHandle, number)) { // Call to generic voicemail number, in case there are multiple accounts primaryActionButtonView.setTag(IntentProvider.getReturnVoicemailCallIntentProvider()); - } else if (this.info != null && this.info.lookupKey != null) { + } else if (canSupportAssistedDialing()) { primaryActionButtonView.setTag( IntentProvider.getAssistedDialIntentProvider( number + postDialDigits, @@ -618,7 +618,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder ((TextView) callButtonView.findViewById(R.id.call_type_or_location_text)); if (canPlaceCallToNumber) { - if (this.info != null && this.info.lookupKey != null) { + if (canSupportAssistedDialing()) { callButtonView.setTag( IntentProvider.getAssistedDialIntentProvider( number, mContext, mContext.getSystemService(TelephonyManager.class))); @@ -685,7 +685,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder && mCachedNumberLookupService.canReportAsInvalid(info.sourceType, info.objectId); detailsButtonView.setTag( IntentProvider.getCallDetailIntentProvider( - callDetailsEntries, buildContact(), canReportCallerId)); + callDetailsEntries, buildContact(), canReportCallerId, canSupportAssistedDialing())); } boolean isBlockedOrSpam = blockId != null || (isSpamFeatureEnabled && isSpam); @@ -764,6 +764,10 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder return accountHandle.getComponentName().equals(mDefaultPhoneAccountHandle.getComponentName()); } + private boolean canSupportAssistedDialing() { + return info != null && info.lookupKey != null; + } + private boolean canSupportCarrierVideoCall() { return mCallLogCache.canRelyOnVideoPresence() && info != null diff --git a/java/com/android/dialer/app/calllog/IntentProvider.java b/java/com/android/dialer/app/calllog/IntentProvider.java index 52a7b0faf..5030de5f5 100644 --- a/java/com/android/dialer/app/calllog/IntentProvider.java +++ b/java/com/android/dialer/app/calllog/IntentProvider.java @@ -124,15 +124,20 @@ public abstract class IntentProvider { * * @param callDetailsEntries The call details of the other calls grouped together with the call. * @param contact The contact with which this call details intent pertains to. + * @param canReportCallerId Whether reporting a caller ID is supported. + * @param canSupportAssistedDialing Whether assisted dialing is supported. * @return The call details intent provider. */ public static IntentProvider getCallDetailIntentProvider( - CallDetailsEntries callDetailsEntries, DialerContact contact, boolean canReportCallerId) { + CallDetailsEntries callDetailsEntries, + DialerContact contact, + boolean canReportCallerId, + boolean canSupportAssistedDialing) { return new IntentProvider() { @Override public Intent getIntent(Context context) { return CallDetailsActivity.newInstance( - context, callDetailsEntries, contact, canReportCallerId); + context, callDetailsEntries, contact, canReportCallerId, canSupportAssistedDialing); } }; } diff --git a/java/com/android/dialer/calldetails/CallDetailsActivity.java b/java/com/android/dialer/calldetails/CallDetailsActivity.java index 569aaa5b5..d7f414bb2 100644 --- a/java/com/android/dialer/calldetails/CallDetailsActivity.java +++ b/java/com/android/dialer/calldetails/CallDetailsActivity.java @@ -16,6 +16,7 @@ package com.android.dialer.calldetails; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; @@ -29,21 +30,30 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar.OnMenuItemClickListener; +import android.telephony.TelephonyManager; import android.view.MenuItem; +import android.widget.Toast; +import com.android.dialer.assisteddialing.ConcreteCreator; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; +import com.android.dialer.callintent.CallInitiationType; +import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.AsyncTaskExecutors; +import com.android.dialer.constants.ActivityRequestCodes; import com.android.dialer.dialercontact.DialerContact; import com.android.dialer.enrichedcall.EnrichedCallComponent; import com.android.dialer.enrichedcall.EnrichedCallManager.HistoricalDataChangedListener; import com.android.dialer.enrichedcall.historyquery.proto.HistoryResult; +import com.android.dialer.lightbringer.Lightbringer; +import com.android.dialer.lightbringer.LightbringerComponent; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.logging.UiAction; import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.postcall.PostCall; import com.android.dialer.protos.ProtoParsers; +import com.android.dialer.util.DialerUtils; import java.util.Collections; import java.util.List; import java.util.Map; @@ -51,6 +61,7 @@ import java.util.Map; /** Displays the details of a specific call log entry. */ public class CallDetailsActivity extends AppCompatActivity implements OnMenuItemClickListener, + CallDetailsHeaderViewHolder.CallbackActionListener, CallDetailsFooterViewHolder.ReportCallIdListener, HistoricalDataChangedListener { @@ -59,6 +70,7 @@ public class CallDetailsActivity extends AppCompatActivity private static final String EXTRA_CALL_DETAILS_ENTRIES = "call_details_entries"; private static final String EXTRA_CONTACT = "contact"; private static final String EXTRA_CAN_REPORT_CALLER_ID = "can_report_caller_id"; + private static final String EXTRA_CAN_SUPPORT_ASSISTED_DIALING = "can_support_assisted_dialing"; private static final String TASK_DELETE = "task_delete"; private CallDetailsEntries entries; @@ -74,7 +86,8 @@ public class CallDetailsActivity extends AppCompatActivity Context context, @NonNull CallDetailsEntries details, @NonNull DialerContact contact, - boolean canReportCallerId) { + boolean canReportCallerId, + boolean canSupportAssistedDialing) { Assert.isNotNull(details); Assert.isNotNull(contact); @@ -82,6 +95,7 @@ public class CallDetailsActivity extends AppCompatActivity ProtoParsers.put(intent, EXTRA_CONTACT, contact); ProtoParsers.put(intent, EXTRA_CALL_DETAILS_ENTRIES, details); intent.putExtra(EXTRA_CAN_REPORT_CALLER_ID, canReportCallerId); + intent.putExtra(EXTRA_CAN_SUPPORT_ASSISTED_DIALING, canSupportAssistedDialing); return intent; } @@ -142,7 +156,13 @@ public class CallDetailsActivity extends AppCompatActivity entries = ProtoParsers.getTrusted( intent, EXTRA_CALL_DETAILS_ENTRIES, CallDetailsEntries.getDefaultInstance()); - adapter = new CallDetailsAdapter(this, contact, entries.getEntriesList(), this); + adapter = + new CallDetailsAdapter( + this /* context */, + contact, + entries.getEntriesList(), + this /* callbackListener */, + this /* reportCallIdListener */); RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); @@ -188,6 +208,51 @@ public class CallDetailsActivity extends AppCompatActivity .getEntriesList()); } + @Override + public void placeImsVideoCall(String phoneNumber) { + Logger.get(this).logImpression(DialerImpression.Type.CALL_DETAILS_IMS_VIDEO_CALL_BACK); + DialerUtils.startActivityWithErrorToast( + this, + new CallIntentBuilder(phoneNumber, CallInitiationType.Type.CALL_DETAILS) + .setIsVideoCall(true) + .build()); + } + + @Override + public void placeLightbringerCall(String phoneNumber) { + Logger.get(this).logImpression(DialerImpression.Type.CALL_DETAILS_LIGHTBRINGER_CALL_BACK); + Lightbringer lightbringer = LightbringerComponent.get(this).getLightbringer(); + if (!lightbringer.isReachable(this, phoneNumber)) { + placeImsVideoCall(phoneNumber); + return; + } + + try { + startActivityForResult( + lightbringer.getIntent(this, phoneNumber), ActivityRequestCodes.DIALTACTS_LIGHTBRINGER); + } catch (ActivityNotFoundException e) { + Toast.makeText(this, R.string.activity_not_available, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void placeVoiceCall(String phoneNumber, String postDialDigits) { + Logger.get(this).logImpression(DialerImpression.Type.CALL_DETAILS_VOICE_CALL_BACK); + + boolean canSupportedAssistedDialing = + getIntent().getExtras().getBoolean(EXTRA_CAN_SUPPORT_ASSISTED_DIALING, false); + CallIntentBuilder callIntentBuilder = + new CallIntentBuilder(phoneNumber + postDialDigits, CallInitiationType.Type.CALL_DETAILS); + if (canSupportedAssistedDialing) { + callIntentBuilder.setAllowAssistedDial( + true, + ConcreteCreator.createNewAssistedDialingMediator( + getSystemService(TelephonyManager.class), this)); + } + + DialerUtils.startActivityWithErrorToast(this, callIntentBuilder.build()); + } + @NonNull private Map<CallDetailsEntry, List<HistoryResult>> getAllHistoricalData( @Nullable String number, @NonNull CallDetailsEntries entries) { diff --git a/java/com/android/dialer/calldetails/CallDetailsAdapter.java b/java/com/android/dialer/calldetails/CallDetailsAdapter.java index 645587461..1f00d9d9a 100644 --- a/java/com/android/dialer/calldetails/CallDetailsAdapter.java +++ b/java/com/android/dialer/calldetails/CallDetailsAdapter.java @@ -23,7 +23,10 @@ import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.LayoutInflater; import android.view.ViewGroup; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; +import com.android.dialer.calldetails.CallDetailsHeaderViewHolder.CallbackActionListener; import com.android.dialer.calllogutils.CallTypeHelper; +import com.android.dialer.calllogutils.CallbackActionHelper; +import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction; import com.android.dialer.common.Assert; import com.android.dialer.dialercontact.DialerContact; import com.android.dialer.lightbringer.LightbringerComponent; @@ -37,7 +40,8 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol private static final int FOOTER_VIEW_TYPE = 3; private final DialerContact contact; - private final CallDetailsFooterViewHolder.ReportCallIdListener listener; + private final CallbackActionListener callbackActionListener; + private final CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener; private final CallTypeHelper callTypeHelper; private List<CallDetailsEntry> callDetailsEntries; @@ -45,10 +49,12 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol Context context, @NonNull DialerContact contact, @NonNull List<CallDetailsEntry> callDetailsEntries, - CallDetailsFooterViewHolder.ReportCallIdListener listener) { + CallbackActionListener callbackActionListener, + CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener) { this.contact = Assert.isNotNull(contact); this.callDetailsEntries = callDetailsEntries; - this.listener = listener; + this.callbackActionListener = callbackActionListener; + this.reportCallIdListener = reportCallIdListener; callTypeHelper = new CallTypeHelper( context.getResources(), LightbringerComponent.get(context).getLightbringer()); @@ -60,13 +66,13 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol switch (viewType) { case HEADER_VIEW_TYPE: return new CallDetailsHeaderViewHolder( - inflater.inflate(R.layout.contact_container, parent, false)); + inflater.inflate(R.layout.contact_container, parent, false), callbackActionListener); case CALL_ENTRY_VIEW_TYPE: return new CallDetailsEntryViewHolder( inflater.inflate(R.layout.call_details_entry, parent, false)); case FOOTER_VIEW_TYPE: return new CallDetailsFooterViewHolder( - inflater.inflate(R.layout.call_details_footer, parent, false), listener); + inflater.inflate(R.layout.call_details_footer, parent, false), reportCallIdListener); default: throw Assert.createIllegalStateFailException( "No ViewHolder available for viewType: " + viewType); @@ -76,7 +82,7 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol @Override public void onBindViewHolder(ViewHolder holder, int position) { if (position == 0) { // Header - ((CallDetailsHeaderViewHolder) holder).updateContactInfo(contact); + ((CallDetailsHeaderViewHolder) holder).updateContactInfo(contact, getCallbackAction()); } else if (position == getItemCount() - 1) { ((CallDetailsFooterViewHolder) holder).setPhoneNumber(contact.getNumber()); } else { @@ -110,4 +116,12 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol callDetailsEntries = entries; notifyDataSetChanged(); } + + private @CallbackAction int getCallbackAction() { + Assert.checkState(!callDetailsEntries.isEmpty()); + + CallDetailsEntry entry = callDetailsEntries.get(0); + return CallbackActionHelper.getCallbackAction( + contact.getNumber(), entry.getFeatures(), entry.getIsLightbringerCall()); + } } diff --git a/java/com/android/dialer/calldetails/CallDetailsHeaderViewHolder.java b/java/com/android/dialer/calldetails/CallDetailsHeaderViewHolder.java index dcd8e3537..7c3892a33 100644 --- a/java/com/android/dialer/calldetails/CallDetailsHeaderViewHolder.java +++ b/java/com/android/dialer/calldetails/CallDetailsHeaderViewHolder.java @@ -23,23 +23,22 @@ import android.telecom.PhoneAccount; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; +import android.widget.ImageView; import android.widget.QuickContactBadge; import android.widget.TextView; -import com.android.dialer.callintent.CallInitiationType; -import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction; import com.android.dialer.common.Assert; import com.android.dialer.contactphoto.ContactPhotoManager; import com.android.dialer.dialercontact.DialerContact; -import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.InteractionEvent; import com.android.dialer.logging.Logger; -import com.android.dialer.util.DialerUtils; /** ViewHolder for Header/Contact in {@link CallDetailsActivity}. */ public class CallDetailsHeaderViewHolder extends RecyclerView.ViewHolder implements OnClickListener { - private final View callBackButton; + private final CallbackActionListener callbackActionListener; + private final ImageView callbackButton; private final TextView nameView; private final TextView numberView; private final TextView networkView; @@ -47,24 +46,26 @@ public class CallDetailsHeaderViewHolder extends RecyclerView.ViewHolder private final Context context; private DialerContact contact; + private @CallbackAction int callbackAction; - CallDetailsHeaderViewHolder(View container) { + CallDetailsHeaderViewHolder(View container, CallbackActionListener callbackActionListener) { super(container); context = container.getContext(); - callBackButton = container.findViewById(R.id.call_back_button); + callbackButton = container.findViewById(R.id.call_back_button); nameView = container.findViewById(R.id.contact_name); numberView = container.findViewById(R.id.phone_number); networkView = container.findViewById(R.id.network); contactPhoto = container.findViewById(R.id.quick_contact_photo); - callBackButton.setOnClickListener(this); + callbackButton.setOnClickListener(this); + this.callbackActionListener = callbackActionListener; Logger.get(context) .logQuickContactOnTouch( contactPhoto, InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_CALL_DETAILS, true); } /** Populates the contact info fields based on the current contact information. */ - void updateContactInfo(DialerContact contact) { + void updateContactInfo(DialerContact contact, @CallbackAction int callbackAction) { this.contact = contact; ContactPhotoManager.getInstance(context) .loadDialerThumbnailOrPhoto( @@ -99,23 +100,61 @@ public class CallDetailsHeaderViewHolder extends RecyclerView.ViewHolder } } - if (TextUtils.isEmpty(contact.getNumber())) { - callBackButton.setVisibility(View.GONE); + setCallbackAction(callbackAction); + } + + private void setCallbackAction(@CallbackAction int callbackAction) { + this.callbackAction = callbackAction; + switch (callbackAction) { + case CallbackAction.LIGHTBRINGER: + case CallbackAction.IMS_VIDEO: + callbackButton.setVisibility(View.VISIBLE); + callbackButton.setImageResource(R.drawable.quantum_ic_videocam_vd_theme_24); + break; + case CallbackAction.VOICE: + callbackButton.setVisibility(View.VISIBLE); + callbackButton.setImageResource(R.drawable.quantum_ic_call_vd_theme_24); + break; + case CallbackAction.NONE: + callbackButton.setVisibility(View.GONE); + break; + default: + throw Assert.createIllegalStateFailException("Invalid action: " + callbackAction); } } @Override public void onClick(View view) { - if (view == callBackButton) { - Logger.get(view.getContext()).logImpression(DialerImpression.Type.CALL_DETAILS_CALL_BACK); - DialerUtils.startActivityWithErrorToast( - view.getContext(), - new CallIntentBuilder( - contact.getNumber() + contact.getPostDialDigits(), - CallInitiationType.Type.CALL_DETAILS) - .build()); + if (view == callbackButton) { + switch (callbackAction) { + case CallbackAction.IMS_VIDEO: + callbackActionListener.placeImsVideoCall(contact.getNumber()); + break; + case CallbackAction.LIGHTBRINGER: + callbackActionListener.placeLightbringerCall(contact.getNumber()); + break; + case CallbackAction.VOICE: + callbackActionListener.placeVoiceCall(contact.getNumber(), contact.getPostDialDigits()); + break; + case CallbackAction.NONE: + default: + throw Assert.createIllegalStateFailException("Invalid action: " + callbackAction); + } } else { throw Assert.createIllegalStateFailException("View OnClickListener not implemented: " + view); } } + + /** Listener for making a callback */ + interface CallbackActionListener { + + /** Places an IMS video call. */ + void placeImsVideoCall(String phoneNumber); + + /** Places a Lightbringer call. */ + void placeLightbringerCall(String phoneNumber); + + /** Place a traditional voice call. */ + void placeVoiceCall(String phoneNumber, String postDialDigits); + } } diff --git a/java/com/android/dialer/logging/dialer_impression.proto b/java/com/android/dialer/logging/dialer_impression.proto index fe1c5e9ba..098391877 100644 --- a/java/com/android/dialer/logging/dialer_impression.proto +++ b/java/com/android/dialer/logging/dialer_impression.proto @@ -323,7 +323,7 @@ message DialerImpression { CALL_DETAILS_COPY_NUMBER = 1121; CALL_DETAILS_EDIT_BEFORE_CALL = 1122; - CALL_DETAILS_CALL_BACK = 1123; + CALL_DETAILS_CALL_BACK = 1123 [deprecated = true]; VVM_USER_DISMISSED_VM_ALMOST_FULL_PROMO = 1124; VVM_USER_DISMISSED_VM_FULL_PROMO = 1125; @@ -554,5 +554,10 @@ message DialerImpression { // More voicemail transcription impressions VVM_TRANSCRIPTION_POLL_REQUEST = 1283; + + // Callback impressions (with more granularity) from the call details UI + CALL_DETAILS_IMS_VIDEO_CALL_BACK = 1284; + CALL_DETAILS_LIGHTBRINGER_CALL_BACK = 1285; + CALL_DETAILS_VOICE_CALL_BACK = 1286; } } |