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