• 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.provider.CallLog.Calls;
22 import android.support.annotation.ColorInt;
23 import android.support.annotation.NonNull;
24 import android.support.v4.content.ContextCompat;
25 import android.support.v7.widget.RecyclerView.ViewHolder;
26 import android.text.TextUtils;
27 import android.view.View;
28 import android.widget.ImageView;
29 import android.widget.TextView;
30 import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry;
31 import com.android.dialer.calllogutils.CallLogDates;
32 import com.android.dialer.calllogutils.CallLogDurations;
33 import com.android.dialer.calllogutils.CallTypeHelper;
34 import com.android.dialer.calllogutils.CallTypeIconsView;
35 import com.android.dialer.common.LogUtil;
36 import com.android.dialer.compat.AppCompatConstants;
37 import com.android.dialer.enrichedcall.historyquery.proto.HistoryResult;
38 import com.android.dialer.enrichedcall.historyquery.proto.HistoryResult.Type;
39 import com.android.dialer.oem.MotorolaUtils;
40 import com.android.dialer.util.DialerUtils;
41 import com.android.dialer.util.IntentUtil;
42 
43 /** ViewHolder for call entries in {@link CallDetailsActivity}. */
44 public class CallDetailsEntryViewHolder extends ViewHolder {
45 
46   private final CallTypeIconsView callTypeIcon;
47   private final TextView callTypeText;
48   private final TextView callTime;
49   private final TextView callDuration;
50 
51   private final View multimediaImageContainer;
52   private final View multimediaDetailsContainer;
53   private final View multimediaDivider;
54 
55   private final TextView multimediaDetails;
56   private final TextView postCallNote;
57 
58   private final ImageView multimediaImage;
59 
60   // TODO(maxwelb): Display this when location is stored - a bug
61   @SuppressWarnings("unused")
62   private final TextView multimediaAttachmentsNumber;
63 
64   private final Context context;
65 
CallDetailsEntryViewHolder(View container)66   public CallDetailsEntryViewHolder(View container) {
67     super(container);
68     context = container.getContext();
69 
70     callTypeIcon = (CallTypeIconsView) container.findViewById(R.id.call_direction);
71     callTypeText = (TextView) container.findViewById(R.id.call_type);
72     callTime = (TextView) container.findViewById(R.id.call_time);
73     callDuration = (TextView) container.findViewById(R.id.call_duration);
74 
75     multimediaImageContainer = container.findViewById(R.id.multimedia_image_container);
76     multimediaDetailsContainer = container.findViewById(R.id.ec_container);
77     multimediaDivider = container.findViewById(R.id.divider);
78     multimediaDetails = (TextView) container.findViewById(R.id.multimedia_details);
79     postCallNote = (TextView) container.findViewById(R.id.post_call_note);
80     multimediaImage = (ImageView) container.findViewById(R.id.multimedia_image);
81     multimediaAttachmentsNumber =
82         (TextView) container.findViewById(R.id.multimedia_attachments_number);
83   }
84 
setCallDetails( String number, CallDetailsEntry entry, CallTypeHelper callTypeHelper, boolean showMultimediaDivider)85   void setCallDetails(
86       String number,
87       CallDetailsEntry entry,
88       CallTypeHelper callTypeHelper,
89       boolean showMultimediaDivider) {
90     int callType = entry.getCallType();
91     boolean isVideoCall = (entry.getFeatures() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO;
92     boolean isPulledCall =
93         (entry.getFeatures() & Calls.FEATURES_PULLED_EXTERNALLY)
94             == Calls.FEATURES_PULLED_EXTERNALLY;
95     boolean isDuoCall = entry.getIsDuoCall();
96 
97     callTime.setTextColor(getColorForCallType(context, callType));
98     callTypeIcon.clear();
99     callTypeIcon.add(callType);
100     callTypeIcon.setShowVideo(isVideoCall);
101     callTypeIcon.setShowHd(
102         (entry.getFeatures() & Calls.FEATURES_HD_CALL) == Calls.FEATURES_HD_CALL);
103     callTypeIcon.setShowWifi(
104         MotorolaUtils.shouldShowWifiIconInCallLog(context, entry.getFeatures()));
105 
106     callTypeText.setText(
107         callTypeHelper.getCallTypeText(callType, isVideoCall, isPulledCall, isDuoCall));
108     callTime.setText(CallLogDates.formatDate(context, entry.getDate()));
109 
110     if (CallTypeHelper.isMissedCallType(callType)) {
111       callDuration.setVisibility(View.GONE);
112     } else {
113       callDuration.setVisibility(View.VISIBLE);
114       callDuration.setText(
115           CallLogDurations.formatDurationAndDataUsage(
116               context, entry.getDuration(), entry.getDataUsage()));
117       callDuration.setContentDescription(
118           CallLogDurations.formatDurationAndDataUsageA11y(
119               context, entry.getDuration(), entry.getDataUsage()));
120     }
121     setMultimediaDetails(number, entry, showMultimediaDivider);
122   }
123 
setMultimediaDetails(String number, CallDetailsEntry entry, boolean showDivider)124   private void setMultimediaDetails(String number, CallDetailsEntry entry, boolean showDivider) {
125     multimediaDivider.setVisibility(showDivider ? View.VISIBLE : View.GONE);
126     if (entry.getHistoryResultsList().isEmpty()) {
127       LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "no data, hiding UI");
128       multimediaDetailsContainer.setVisibility(View.GONE);
129     } else {
130 
131       HistoryResult historyResult = entry.getHistoryResults(0);
132       multimediaDetailsContainer.setVisibility(View.VISIBLE);
133       multimediaDetailsContainer.setOnClickListener((v) -> startSmsIntent(context, number));
134       multimediaImageContainer.setOnClickListener((v) -> startSmsIntent(context, number));
135       multimediaImageContainer.setClipToOutline(true);
136 
137       if (!TextUtils.isEmpty(historyResult.getImageUri())) {
138         LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "setting image");
139         multimediaImageContainer.setVisibility(View.VISIBLE);
140         multimediaImage.setImageURI(Uri.parse(historyResult.getImageUri()));
141         multimediaDetails.setText(
142             isIncoming(historyResult) ? R.string.received_a_photo : R.string.sent_a_photo);
143       } else {
144         LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "no image");
145       }
146 
147       // Set text after image to overwrite the received/sent a photo text
148       if (!TextUtils.isEmpty(historyResult.getText())) {
149         LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "showing text");
150         multimediaDetails.setText(
151             context.getString(R.string.message_in_quotes, historyResult.getText()));
152       } else {
153         LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "no text");
154       }
155 
156       if (entry.getHistoryResultsList().size() > 1
157           && !TextUtils.isEmpty(entry.getHistoryResults(1).getText())) {
158         LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "showing post call note");
159         postCallNote.setVisibility(View.VISIBLE);
160         postCallNote.setText(
161             context.getString(R.string.message_in_quotes, entry.getHistoryResults(1).getText()));
162         postCallNote.setOnClickListener((v) -> startSmsIntent(context, number));
163       } else {
164         LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "no post call note");
165       }
166     }
167   }
168 
startSmsIntent(Context context, String number)169   private void startSmsIntent(Context context, String number) {
170     DialerUtils.startActivityWithErrorToast(context, IntentUtil.getSendSmsIntent(number));
171   }
172 
isIncoming(@onNull HistoryResult historyResult)173   private static boolean isIncoming(@NonNull HistoryResult historyResult) {
174     return historyResult.getType() == Type.INCOMING_POST_CALL
175         || historyResult.getType() == Type.INCOMING_CALL_COMPOSER;
176   }
177 
getColorForCallType(Context context, int callType)178   private static @ColorInt int getColorForCallType(Context context, int callType) {
179     switch (callType) {
180       case AppCompatConstants.CALLS_OUTGOING_TYPE:
181       case AppCompatConstants.CALLS_VOICEMAIL_TYPE:
182       case AppCompatConstants.CALLS_BLOCKED_TYPE:
183       case AppCompatConstants.CALLS_INCOMING_TYPE:
184       case AppCompatConstants.CALLS_ANSWERED_EXTERNALLY_TYPE:
185       case AppCompatConstants.CALLS_REJECTED_TYPE:
186         return ContextCompat.getColor(context, R.color.dialer_secondary_text_color);
187       case AppCompatConstants.CALLS_MISSED_TYPE:
188       default:
189         // It is possible for users to end up with calls with unknown call types in their
190         // call history, possibly due to 3rd party call log implementations (e.g. to
191         // distinguish between rejected and missed calls). Instead of crashing, just
192         // assume that all unknown call types are missed calls.
193         return ContextCompat.getColor(context, R.color.missed_call);
194     }
195   }
196 }
197