Home | History | Annotate | Download | only in calldetails
      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 
     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 
     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 
    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 
    169   private void startSmsIntent(Context context, String number) {
    170     DialerUtils.startActivityWithErrorToast(context, IntentUtil.getSendSmsIntent(number));
    171   }
    172 
    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 
    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