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