• 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 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 
CallLogInteraction(ContentValues values)56     public CallLogInteraction(ContentValues values) {
57         mValues = values;
58     }
59 
60     @Override
getIntent()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
getViewHeader(Context context)68     public String getViewHeader(Context context) {
69         return getNumber();
70     }
71 
72     @Override
getInteractionDate()73     public long getInteractionDate() {
74         Long date = getDate();
75         return date == null ? -1 : date;
76     }
77 
78     @Override
getViewBody(Context context)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
getViewFooter(Context context)89     public String getViewFooter(Context context) {
90         Long date = getDate();
91         return date == null ? null : ContactInteractionUtil.formatDateStringFromTimestamp(
92                 date, context);
93     }
94 
95     @Override
getIcon(Context context)96     public Drawable getIcon(Context context) {
97         return context.getResources().getDrawable(CALL_LOG_ICON_RES);
98     }
99 
100     @Override
getBodyIcon(Context context)101     public Drawable getBodyIcon(Context context) {
102         return null;
103     }
104 
105     @Override
getFooterIcon(Context context)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 
getCachedName()133     public String getCachedName() {
134         return mValues.getAsString(Calls.CACHED_NAME);
135     }
136 
getCachedNumberLabel()137     public String getCachedNumberLabel() {
138         return mValues.getAsString(Calls.CACHED_NUMBER_LABEL);
139     }
140 
getCachedNumberType()141     public Integer getCachedNumberType() {
142         return mValues.getAsInteger(Calls.CACHED_NUMBER_TYPE);
143     }
144 
getDate()145     public Long getDate() {
146         return mValues.getAsLong(Calls.DATE);
147     }
148 
getDuration()149     public Long getDuration() {
150         return mValues.getAsLong(Calls.DURATION);
151     }
152 
getIsRead()153     public Boolean getIsRead() {
154         return mValues.getAsBoolean(Calls.IS_READ);
155     }
156 
getLimitParamKey()157     public Integer getLimitParamKey() {
158         return mValues.getAsInteger(Calls.LIMIT_PARAM_KEY);
159     }
160 
getNew()161     public Boolean getNew() {
162         return mValues.getAsBoolean(Calls.NEW);
163     }
164 
getNumber()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 
getNumberPresentation()171     public Integer getNumberPresentation() {
172         return mValues.getAsInteger(Calls.NUMBER_PRESENTATION);
173     }
174 
getOffsetParamKey()175     public Integer getOffsetParamKey() {
176         return mValues.getAsInteger(Calls.OFFSET_PARAM_KEY);
177     }
178 
getType()179     public Integer getType() {
180         return mValues.getAsInteger(Calls.TYPE);
181     }
182 
183     @Override
getContentDescription(Context context)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 
getCallTypeString(Context context)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
getIconResourceId()214     public int getIconResourceId() {
215         return CALL_LOG_ICON_RES;
216     }
217 }
218