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