1ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos/*
2ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * Copyright (C) 2014 The Android Open Source Project
3ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos *
4ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * Licensed under the Apache License, Version 2.0 (the "License");
5ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * you may not use this file except in compliance with the License.
6ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * You may obtain a copy of the License at
7ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos *
8ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos *      http://www.apache.org/licenses/LICENSE-2.0
9ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos *
10ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * Unless required by applicable law or agreed to in writing, software
11ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * distributed under the License is distributed on an "AS IS" BASIS,
12ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * See the License for the specific language governing permissions and
14ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * limitations under the License.
15ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos */
16ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulospackage com.android.contacts.interactions;
17ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
18ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport com.android.contacts.R;
19ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport com.android.contacts.common.util.BitmapUtil;
207ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jangimport com.android.contacts.common.util.ContactDisplayUtils;
21ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
22ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport android.content.ContentValues;
23ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport android.content.Context;
24ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport android.content.Intent;
25ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport android.content.res.Resources;
26ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport android.graphics.PorterDuff;
27ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport android.graphics.drawable.Drawable;
28ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport android.net.Uri;
29ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport android.provider.CallLog.Calls;
30ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulosimport android.provider.ContactsContract.CommonDataKinds.Phone;
31c62cc7931593b4137f8a507689b653e1e15e1260Brian Attwellimport android.text.BidiFormatter;
327ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jangimport android.text.Spannable;
33c62cc7931593b4137f8a507689b653e1e15e1260Brian Attwellimport android.text.TextDirectionHeuristics;
34ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
35ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos/**
36ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * Represents a call log event interaction, wrapping the columns in
37ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * {@link android.provider.CallLog.Calls}.
38ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos *
39ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * This class does not return log entries related to voicemail or SIP calls. Additionally,
40ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * this class ignores number presentation. Number presentation affects how to identify phone
41ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * numbers. Since, we already know the identity of the phone number owner we can ignore number
42ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * presentation.
43ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos *
44ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * As a result of ignoring voicemail and number presentation, we don't need to worry about API
45ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos * version.
46ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos */
47ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulospublic class CallLogInteraction implements ContactInteraction {
48ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
49ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    private static final String URI_TARGET_PREFIX = "tel:";
50ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    private static final int CALL_LOG_ICON_RES = R.drawable.ic_phone_24dp;
51ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    private static final int CALL_ARROW_ICON_RES = R.drawable.ic_call_arrow;
52c62cc7931593b4137f8a507689b653e1e15e1260Brian Attwell    private static BidiFormatter sBidiFormatter = BidiFormatter.getInstance();
53ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
54ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    private ContentValues mValues;
55ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
56ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public CallLogInteraction(ContentValues values) {
57ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        mValues = values;
58ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
59ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
60ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    @Override
61ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public Intent getIntent() {
6275d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        String number = getNumber();
6375d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        return number == null ? null : new Intent(Intent.ACTION_CALL).setData(
6475d5a915cb764f610db6141148c57b1c8e080564Paul Soulos                Uri.parse(URI_TARGET_PREFIX + number));
65ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
66ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
67ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    @Override
68ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public String getViewHeader(Context context) {
69ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return getNumber();
70ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
71ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
72ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    @Override
73ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public long getInteractionDate() {
7475d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        Long date = getDate();
7575d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        return date == null ? -1 : date;
76ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
77ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
78ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    @Override
79ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public String getViewBody(Context context) {
8075d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        Integer numberType = getCachedNumberType();
8175d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        if (numberType == null) {
82ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos            return null;
83ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        }
84ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return Phone.getTypeLabel(context.getResources(), getCachedNumberType(),
85ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                getCachedNumberLabel()).toString();
86ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
87ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
88ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    @Override
89ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public String getViewFooter(Context context) {
9075d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        Long date = getDate();
9175d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        return date == null ? null : ContactInteractionUtil.formatDateStringFromTimestamp(
9275d5a915cb764f610db6141148c57b1c8e080564Paul Soulos                date, context);
93ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
94ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
95ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    @Override
96ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public Drawable getIcon(Context context) {
97ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return context.getResources().getDrawable(CALL_LOG_ICON_RES);
98ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
99ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
100ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    @Override
101ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public Drawable getBodyIcon(Context context) {
102ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return null;
103ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
104ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
105ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    @Override
106ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public Drawable getFooterIcon(Context context) {
107ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        Drawable callArrow = null;
108ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        Resources res = context.getResources();
10975d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        Integer type = getType();
11075d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        if (type == null) {
11175d5a915cb764f610db6141148c57b1c8e080564Paul Soulos            return null;
11275d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        }
11375d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        switch (type) {
114ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos            case Calls.INCOMING_TYPE:
115ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                callArrow = res.getDrawable(CALL_ARROW_ICON_RES);
116ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                callArrow.setColorFilter(res.getColor(R.color.call_arrow_green),
117ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                        PorterDuff.Mode.MULTIPLY);
118ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                break;
119ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos            case Calls.MISSED_TYPE:
120ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                callArrow = res.getDrawable(CALL_ARROW_ICON_RES);
121ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                callArrow.setColorFilter(res.getColor(R.color.call_arrow_red),
122ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                        PorterDuff.Mode.MULTIPLY);
123ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                break;
124ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos            case Calls.OUTGOING_TYPE:
125ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                callArrow = BitmapUtil.getRotatedDrawable(res, CALL_ARROW_ICON_RES, 180f);
126ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                callArrow.setColorFilter(res.getColor(R.color.call_arrow_green),
127ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                        PorterDuff.Mode.MULTIPLY);
128ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos                break;
129ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        }
130ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return callArrow;
131ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
132ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
133ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public String getCachedName() {
134ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsString(Calls.CACHED_NAME);
135ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
136ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
137ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public String getCachedNumberLabel() {
138ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsString(Calls.CACHED_NUMBER_LABEL);
139ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
140ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
14175d5a915cb764f610db6141148c57b1c8e080564Paul Soulos    public Integer getCachedNumberType() {
14275d5a915cb764f610db6141148c57b1c8e080564Paul Soulos        return mValues.getAsInteger(Calls.CACHED_NUMBER_TYPE);
143ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
144ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
14575d5a915cb764f610db6141148c57b1c8e080564Paul Soulos    public Long getDate() {
146ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsLong(Calls.DATE);
147ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
148ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
14975d5a915cb764f610db6141148c57b1c8e080564Paul Soulos    public Long getDuration() {
150ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsLong(Calls.DURATION);
151ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
152ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
15375d5a915cb764f610db6141148c57b1c8e080564Paul Soulos    public Boolean getIsRead() {
154ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsBoolean(Calls.IS_READ);
155ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
156ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
15775d5a915cb764f610db6141148c57b1c8e080564Paul Soulos    public Integer getLimitParamKey() {
158ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsInteger(Calls.LIMIT_PARAM_KEY);
159ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
160ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
16175d5a915cb764f610db6141148c57b1c8e080564Paul Soulos    public Boolean getNew() {
162ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsBoolean(Calls.NEW);
163ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
164ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
165ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    public String getNumber() {
166b2215766433478ac1c53d61c08f4844326dfe4f8Jay Shrauner        final String number = mValues.getAsString(Calls.NUMBER);
167b2215766433478ac1c53d61c08f4844326dfe4f8Jay Shrauner        return number == null ? null :
168b2215766433478ac1c53d61c08f4844326dfe4f8Jay Shrauner            sBidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR);
169ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
170ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
17175d5a915cb764f610db6141148c57b1c8e080564Paul Soulos    public Integer getNumberPresentation() {
172ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsInteger(Calls.NUMBER_PRESENTATION);
173ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
174ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
17575d5a915cb764f610db6141148c57b1c8e080564Paul Soulos    public Integer getOffsetParamKey() {
176ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsInteger(Calls.OFFSET_PARAM_KEY);
177ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
178ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos
17975d5a915cb764f610db6141148c57b1c8e080564Paul Soulos    public Integer getType() {
180ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos        return mValues.getAsInteger(Calls.TYPE);
181ab840448dd00ce3f02ec7317df69b24613ade8a9Paul Soulos    }
18223e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos
18323e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos    @Override
1847ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang    public Spannable getContentDescription(Context context) {
1857ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang        final String phoneNumber = getViewHeader(context);
1867ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang        final String contentDescription = context.getResources().getString(
1877ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang                R.string.content_description_recent_call,
1887ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang                getCallTypeString(context), phoneNumber, getViewFooter(context));
1897ce5352a70e8aaf120bf4f7bd05d595f46abb080Walter Jang        return ContactDisplayUtils.getTelephoneTtsSpannable(contentDescription, phoneNumber);
19023e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos    }
19123e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos
19223e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos    private String getCallTypeString(Context context) {
19323e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos        String callType = "";
19423e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos        Resources res = context.getResources();
19523e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos        Integer type = getType();
19623e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos        if (type == null) {
19723e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos            return callType;
19823e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos        }
19923e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos        switch (type) {
20023e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos            case Calls.INCOMING_TYPE:
20123e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos                callType = res.getString(R.string.content_description_recent_call_type_incoming);
20223e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos                break;
20323e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos            case Calls.MISSED_TYPE:
20423e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos                callType = res.getString(R.string.content_description_recent_call_type_missed);
20523e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos                break;
20623e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos            case Calls.OUTGOING_TYPE:
20723e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos                callType = res.getString(R.string.content_description_recent_call_type_outgoing);
20823e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos                break;
20923e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos        }
21023e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos        return callType;
21123e2836c1e9cbe8996a1344301e69d67bb617891Paul Soulos    }
21248290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos
21348290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos    @Override
21448290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos    public int getIconResourceId() {
21548290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos        return CALL_LOG_ICON_RES;
21648290bed7c6a8bd5e7be8b206dddacf9047a945fPaul Soulos    }
217b2215766433478ac1c53d61c08f4844326dfe4f8Jay Shrauner}
218