• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.dialer.calldetails;
18 
19 import android.content.Context;
20 import android.net.Uri;
21 import android.support.v7.widget.RecyclerView;
22 import android.telecom.PhoneAccount;
23 import android.text.TextUtils;
24 import android.view.View;
25 import android.view.View.OnClickListener;
26 import android.widget.ImageView;
27 import android.widget.QuickContactBadge;
28 import android.widget.RelativeLayout;
29 import android.widget.TextView;
30 import com.android.dialer.calldetails.CallDetailsActivity.AssistedDialingNumberParseWorker;
31 import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry;
32 import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction;
33 import com.android.dialer.common.Assert;
34 import com.android.dialer.common.LogUtil;
35 import com.android.dialer.common.concurrent.DialerExecutor.FailureListener;
36 import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener;
37 import com.android.dialer.compat.telephony.TelephonyManagerCompat;
38 import com.android.dialer.contactphoto.ContactPhotoManager;
39 import com.android.dialer.dialercontact.DialerContact;
40 import com.android.dialer.logging.InteractionEvent;
41 import com.android.dialer.logging.Logger;
42 
43 /** ViewHolder for Header/Contact in {@link CallDetailsActivity}. */
44 public class CallDetailsHeaderViewHolder extends RecyclerView.ViewHolder
45     implements OnClickListener, FailureListener {
46 
47   private final CallDetailsHeaderListener callDetailsHeaderListener;
48   private final ImageView callbackButton;
49   private final TextView nameView;
50   private final TextView numberView;
51   private final TextView networkView;
52   private final QuickContactBadge contactPhoto;
53   private final Context context;
54   private final TextView assistedDialingInternationalDirectDialCodeAndCountryCodeText;
55   private final RelativeLayout assistedDialingContainer;
56 
57   private DialerContact contact;
58   private @CallbackAction int callbackAction;
59 
CallDetailsHeaderViewHolder(View container, CallDetailsHeaderListener callDetailsHeaderListener)60   CallDetailsHeaderViewHolder(View container, CallDetailsHeaderListener callDetailsHeaderListener) {
61     super(container);
62     context = container.getContext();
63     callbackButton = container.findViewById(R.id.call_back_button);
64     nameView = container.findViewById(R.id.contact_name);
65     numberView = container.findViewById(R.id.phone_number);
66     networkView = container.findViewById(R.id.network);
67     contactPhoto = container.findViewById(R.id.quick_contact_photo);
68     assistedDialingInternationalDirectDialCodeAndCountryCodeText =
69         container.findViewById(R.id.assisted_dialing_text);
70     assistedDialingContainer = container.findViewById(R.id.assisted_dialing_container);
71 
72     assistedDialingContainer.setOnClickListener(
73         callDetailsHeaderListener::openAssistedDialingSettings);
74 
75     callbackButton.setOnClickListener(this);
76     this.callDetailsHeaderListener = callDetailsHeaderListener;
77     Logger.get(context)
78         .logQuickContactOnTouch(
79             contactPhoto, InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_CALL_DETAILS, true);
80   }
81 
hasAssistedDialingFeature(Integer features)82   private boolean hasAssistedDialingFeature(Integer features) {
83     return (features & TelephonyManagerCompat.FEATURES_ASSISTED_DIALING)
84         == TelephonyManagerCompat.FEATURES_ASSISTED_DIALING;
85   }
86 
updateAssistedDialingInfo(CallDetailsEntry callDetailsEntry)87   void updateAssistedDialingInfo(CallDetailsEntry callDetailsEntry) {
88 
89     if (callDetailsEntry != null && hasAssistedDialingFeature(callDetailsEntry.getFeatures())) {
90       showAssistedDialingContainer(true);
91       callDetailsHeaderListener.createAssistedDialerNumberParserTask(
92           new CallDetailsActivity.AssistedDialingNumberParseWorker(),
93           this::updateAssistedDialingText,
94           this::onFailure);
95 
96     } else {
97       showAssistedDialingContainer(false);
98     }
99   }
100 
showAssistedDialingContainer(boolean shouldShowContainer)101   private void showAssistedDialingContainer(boolean shouldShowContainer) {
102     if (shouldShowContainer) {
103       assistedDialingContainer.setVisibility(View.VISIBLE);
104     } else {
105       LogUtil.i(
106           "CallDetailsHeaderViewHolder.updateAssistedDialingInfo",
107           "hiding assisted dialing ui elements");
108       assistedDialingContainer.setVisibility(View.GONE);
109     }
110   }
111 
updateAssistedDialingText(Integer countryCode)112   private void updateAssistedDialingText(Integer countryCode) {
113 
114     // Try and handle any poorly formed inputs.
115     if (countryCode <= 0) {
116       onFailure(new IllegalStateException());
117       return;
118     }
119 
120     LogUtil.i(
121         "CallDetailsHeaderViewHolder.updateAssistedDialingText", "Updating Assisted Dialing Text");
122     assistedDialingInternationalDirectDialCodeAndCountryCodeText.setText(
123         context.getString(
124             R.string.assisted_dialing_country_code_entry, String.valueOf(countryCode)));
125   }
126 
127   @Override
onFailure(Throwable unused)128   public void onFailure(Throwable unused) {
129     assistedDialingInternationalDirectDialCodeAndCountryCodeText.setText(
130         R.string.assisted_dialing_country_code_entry_failure);
131   }
132 
133   /** Populates the contact info fields based on the current contact information. */
updateContactInfo(DialerContact contact, @CallbackAction int callbackAction)134   void updateContactInfo(DialerContact contact, @CallbackAction int callbackAction) {
135     this.contact = contact;
136     ContactPhotoManager.getInstance(context)
137         .loadDialerThumbnailOrPhoto(
138             contactPhoto,
139             contact.getContactUri().isEmpty() ? null : Uri.parse(contact.getContactUri()),
140             contact.getPhotoId(),
141             contact.getPhotoUri().isEmpty() ? null : Uri.parse(contact.getPhotoUri()),
142             contact.getNameOrNumber(),
143             contact.getContactType());
144 
145     nameView.setText(contact.getNameOrNumber());
146     if (!TextUtils.isEmpty(contact.getDisplayNumber())) {
147       numberView.setVisibility(View.VISIBLE);
148       String secondaryInfo =
149           TextUtils.isEmpty(contact.getNumberLabel())
150               ? contact.getDisplayNumber()
151               : context.getString(
152                   com.android.contacts.common.R.string.call_subject_type_and_number,
153                   contact.getNumberLabel(),
154                   contact.getDisplayNumber());
155       numberView.setText(secondaryInfo);
156     } else {
157       numberView.setVisibility(View.GONE);
158       numberView.setText(null);
159     }
160 
161     if (!TextUtils.isEmpty(contact.getSimDetails().getNetwork())) {
162       networkView.setVisibility(View.VISIBLE);
163       networkView.setText(contact.getSimDetails().getNetwork());
164       if (contact.getSimDetails().getColor() != PhoneAccount.NO_HIGHLIGHT_COLOR) {
165         networkView.setTextColor(contact.getSimDetails().getColor());
166       }
167     }
168 
169     setCallbackAction(callbackAction);
170   }
171 
setCallbackAction(@allbackAction int callbackAction)172   private void setCallbackAction(@CallbackAction int callbackAction) {
173     this.callbackAction = callbackAction;
174     switch (callbackAction) {
175       case CallbackAction.DUO:
176       case CallbackAction.IMS_VIDEO:
177         callbackButton.setVisibility(View.VISIBLE);
178         callbackButton.setImageResource(R.drawable.quantum_ic_videocam_vd_theme_24);
179         break;
180       case CallbackAction.VOICE:
181         callbackButton.setVisibility(View.VISIBLE);
182         callbackButton.setImageResource(R.drawable.quantum_ic_call_vd_theme_24);
183         break;
184       case CallbackAction.NONE:
185         callbackButton.setVisibility(View.GONE);
186         break;
187       default:
188         throw Assert.createIllegalStateFailException("Invalid action: " + callbackAction);
189     }
190   }
191 
192   @Override
onClick(View view)193   public void onClick(View view) {
194     if (view == callbackButton) {
195       switch (callbackAction) {
196         case CallbackAction.IMS_VIDEO:
197           callDetailsHeaderListener.placeImsVideoCall(contact.getNumber());
198           break;
199         case CallbackAction.DUO:
200           callDetailsHeaderListener.placeDuoVideoCall(contact.getNumber());
201           break;
202         case CallbackAction.VOICE:
203           callDetailsHeaderListener.placeVoiceCall(
204               contact.getNumber(), contact.getPostDialDigits());
205           break;
206         case CallbackAction.NONE:
207         default:
208           throw Assert.createIllegalStateFailException("Invalid action: " + callbackAction);
209       }
210     } else {
211       throw Assert.createIllegalStateFailException("View OnClickListener not implemented: " + view);
212     }
213   }
214 
215   /** Listener for the call details header */
216   interface CallDetailsHeaderListener {
217 
218     /** Places an IMS video call. */
placeImsVideoCall(String phoneNumber)219     void placeImsVideoCall(String phoneNumber);
220 
221     /** Places a Duo video call. */
placeDuoVideoCall(String phoneNumber)222     void placeDuoVideoCall(String phoneNumber);
223 
224     /** Place a traditional voice call. */
placeVoiceCall(String phoneNumber, String postDialDigits)225     void placeVoiceCall(String phoneNumber, String postDialDigits);
226 
227     /** Access the Assisted Dialing settings * */
openAssistedDialingSettings(View view)228     void openAssistedDialingSettings(View view);
229 
createAssistedDialerNumberParserTask( AssistedDialingNumberParseWorker worker, SuccessListener<Integer> onSuccess, FailureListener onFailure)230     void createAssistedDialerNumberParserTask(
231         AssistedDialingNumberParseWorker worker,
232         SuccessListener<Integer> onSuccess,
233         FailureListener onFailure);
234   }
235 }
236