Home | History | Annotate | Download | only in interactions
      1 /*
      2  * Copyright (C) 2014 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 package com.android.contacts.interactions;
     17 
     18 import com.android.contacts.R;
     19 import com.android.contacts.common.util.BitmapUtil;
     20 import com.android.contacts.common.util.ContactDisplayUtils;
     21 
     22 import android.content.ContentValues;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.res.Resources;
     26 import android.graphics.PorterDuff;
     27 import android.graphics.drawable.Drawable;
     28 import android.net.Uri;
     29 import android.provider.CallLog.Calls;
     30 import android.provider.ContactsContract.CommonDataKinds.Phone;
     31 import android.text.BidiFormatter;
     32 import android.text.Spannable;
     33 import android.text.TextDirectionHeuristics;
     34 
     35 /**
     36  * Represents a call log event interaction, wrapping the columns in
     37  * {@link android.provider.CallLog.Calls}.
     38  *
     39  * This class does not return log entries related to voicemail or SIP calls. Additionally,
     40  * this class ignores number presentation. Number presentation affects how to identify phone
     41  * numbers. Since, we already know the identity of the phone number owner we can ignore number
     42  * presentation.
     43  *
     44  * As a result of ignoring voicemail and number presentation, we don't need to worry about API
     45  * version.
     46  */
     47 public class CallLogInteraction implements ContactInteraction {
     48 
     49     private static final String URI_TARGET_PREFIX = "tel:";
     50     private static final int CALL_LOG_ICON_RES = R.drawable.ic_phone_24dp;
     51     private static final int CALL_ARROW_ICON_RES = R.drawable.ic_call_arrow;
     52     private static BidiFormatter sBidiFormatter = BidiFormatter.getInstance();
     53 
     54     private ContentValues mValues;
     55 
     56     public CallLogInteraction(ContentValues values) {
     57         mValues = values;
     58     }
     59 
     60     @Override
     61     public Intent getIntent() {
     62         String number = getNumber();
     63         return number == null ? null : new Intent(Intent.ACTION_CALL).setData(
     64                 Uri.parse(URI_TARGET_PREFIX + number));
     65     }
     66 
     67     @Override
     68     public String getViewHeader(Context context) {
     69         return getNumber();
     70     }
     71 
     72     @Override
     73     public long getInteractionDate() {
     74         Long date = getDate();
     75         return date == null ? -1 : date;
     76     }
     77 
     78     @Override
     79     public String getViewBody(Context context) {
     80         Integer numberType = getCachedNumberType();
     81         if (numberType == null) {
     82             return null;
     83         }
     84         return Phone.getTypeLabel(context.getResources(), getCachedNumberType(),
     85                 getCachedNumberLabel()).toString();
     86     }
     87 
     88     @Override
     89     public String getViewFooter(Context context) {
     90         Long date = getDate();
     91         return date == null ? null : ContactInteractionUtil.formatDateStringFromTimestamp(
     92                 date, context);
     93     }
     94 
     95     @Override
     96     public Drawable getIcon(Context context) {
     97         return context.getResources().getDrawable(CALL_LOG_ICON_RES);
     98     }
     99 
    100     @Override
    101     public Drawable getBodyIcon(Context context) {
    102         return null;
    103     }
    104 
    105     @Override
    106     public Drawable getFooterIcon(Context context) {
    107         Drawable callArrow = null;
    108         Resources res = context.getResources();
    109         Integer type = getType();
    110         if (type == null) {
    111             return null;
    112         }
    113         switch (type) {
    114             case Calls.INCOMING_TYPE:
    115                 callArrow = res.getDrawable(CALL_ARROW_ICON_RES);
    116                 callArrow.setColorFilter(res.getColor(R.color.call_arrow_green),
    117                         PorterDuff.Mode.MULTIPLY);
    118                 break;
    119             case Calls.MISSED_TYPE:
    120                 callArrow = res.getDrawable(CALL_ARROW_ICON_RES);
    121                 callArrow.setColorFilter(res.getColor(R.color.call_arrow_red),
    122                         PorterDuff.Mode.MULTIPLY);
    123                 break;
    124             case Calls.OUTGOING_TYPE:
    125                 callArrow = BitmapUtil.getRotatedDrawable(res, CALL_ARROW_ICON_RES, 180f);
    126                 callArrow.setColorFilter(res.getColor(R.color.call_arrow_green),
    127                         PorterDuff.Mode.MULTIPLY);
    128                 break;
    129         }
    130         return callArrow;
    131     }
    132 
    133     public String getCachedName() {
    134         return mValues.getAsString(Calls.CACHED_NAME);
    135     }
    136 
    137     public String getCachedNumberLabel() {
    138         return mValues.getAsString(Calls.CACHED_NUMBER_LABEL);
    139     }
    140 
    141     public Integer getCachedNumberType() {
    142         return mValues.getAsInteger(Calls.CACHED_NUMBER_TYPE);
    143     }
    144 
    145     public Long getDate() {
    146         return mValues.getAsLong(Calls.DATE);
    147     }
    148 
    149     public Long getDuration() {
    150         return mValues.getAsLong(Calls.DURATION);
    151     }
    152 
    153     public Boolean getIsRead() {
    154         return mValues.getAsBoolean(Calls.IS_READ);
    155     }
    156 
    157     public Integer getLimitParamKey() {
    158         return mValues.getAsInteger(Calls.LIMIT_PARAM_KEY);
    159     }
    160 
    161     public Boolean getNew() {
    162         return mValues.getAsBoolean(Calls.NEW);
    163     }
    164 
    165     public String getNumber() {
    166         final String number = mValues.getAsString(Calls.NUMBER);
    167         return number == null ? null :
    168             sBidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR);
    169     }
    170 
    171     public Integer getNumberPresentation() {
    172         return mValues.getAsInteger(Calls.NUMBER_PRESENTATION);
    173     }
    174 
    175     public Integer getOffsetParamKey() {
    176         return mValues.getAsInteger(Calls.OFFSET_PARAM_KEY);
    177     }
    178 
    179     public Integer getType() {
    180         return mValues.getAsInteger(Calls.TYPE);
    181     }
    182 
    183     @Override
    184     public Spannable getContentDescription(Context context) {
    185         final String phoneNumber = getViewHeader(context);
    186         final String contentDescription = context.getResources().getString(
    187                 R.string.content_description_recent_call,
    188                 getCallTypeString(context), phoneNumber, getViewFooter(context));
    189         return ContactDisplayUtils.getTelephoneTtsSpannable(contentDescription, phoneNumber);
    190     }
    191 
    192     private String getCallTypeString(Context context) {
    193         String callType = "";
    194         Resources res = context.getResources();
    195         Integer type = getType();
    196         if (type == null) {
    197             return callType;
    198         }
    199         switch (type) {
    200             case Calls.INCOMING_TYPE:
    201                 callType = res.getString(R.string.content_description_recent_call_type_incoming);
    202                 break;
    203             case Calls.MISSED_TYPE:
    204                 callType = res.getString(R.string.content_description_recent_call_type_missed);
    205                 break;
    206             case Calls.OUTGOING_TYPE:
    207                 callType = res.getString(R.string.content_description_recent_call_type_outgoing);
    208                 break;
    209         }
    210         return callType;
    211     }
    212 
    213     @Override
    214     public int getIconResourceId() {
    215         return CALL_LOG_ICON_RES;
    216     }
    217 }
    218