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