1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2011 The Android Open Source Project
3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License.
6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at
7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software
11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and
14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License.
15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.dialer.app.calllog;
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.res.Resources;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Typeface;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.CallLog.Calls;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.CommonDataKinds.Phone;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.v4.content.ContextCompat;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telecom.PhoneAccount;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.TextUtils;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.format.DateUtils;
288369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanianimport android.text.util.Linkify;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.View;
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.widget.TextView;
31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.app.R;
32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.app.calllog.calllogcache.CallLogCache;
33d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.dialer.calllogutils.PhoneCallDetails;
348369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanianimport com.android.dialer.logging.ContactSource;
35d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.dialer.oem.MotorolaUtils;
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.phonenumberutil.PhoneNumberHelper;
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.util.DialerUtils;
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.ArrayList;
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.Calendar;
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.concurrent.TimeUnit;
41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** Helper class to fill in the views in {@link PhoneCallDetailsViews}. */
43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class PhoneCallDetailsHelper {
44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** The maximum number of icons will be shown to represent the call types in a group. */
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int MAX_CALL_TYPE_ICONS = 3;
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final Context mContext;
49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final Resources mResources;
50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final CallLogCache mCallLogCache;
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Calendar used to construct dates */
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final Calendar mCalendar;
53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** The injected current time in milliseconds since the epoch. Used only by tests. */
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private Long mCurrentTimeMillisForTest;
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private CharSequence mPhoneTypeLabelForTest;
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** List of items to be concatenated together for accessibility descriptions */
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ArrayList<CharSequence> mDescriptionItems = new ArrayList<>();
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Creates a new instance of the helper.
62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>Generally you should have a single instance of this helper in any context.
64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param resources used to look up strings
66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public PhoneCallDetailsHelper(Context context, Resources resources, CallLogCache callLogCache) {
68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mContext = context;
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mResources = resources;
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mCallLogCache = callLogCache;
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mCalendar = Calendar.getInstance();
72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Fills the call details views with content. */
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setPhoneCallDetails(PhoneCallDetailsViews views, PhoneCallDetails details) {
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Display up to a given number of icons.
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    views.callTypeIcons.clear();
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int count = details.callTypes.length;
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    boolean isVoicemail = false;
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    for (int index = 0; index < count && index < MAX_CALL_TYPE_ICONS; ++index) {
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      views.callTypeIcons.add(details.callTypes[index]);
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (index == 0) {
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        isVoicemail = details.callTypes[index] == Calls.VOICEMAIL_TYPE;
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Show the video icon if the call had video enabled.
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    views.callTypeIcons.setShowVideo(
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (details.features & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO);
90d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    views.callTypeIcons.setShowHd(
91d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        MotorolaUtils.shouldShowHdIconInCallLog(mContext, details.features));
929050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian    views.callTypeIcons.setShowWifi(
939050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        MotorolaUtils.shouldShowWifiIconInCallLog(mContext, details.features));
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    views.callTypeIcons.requestLayout();
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    views.callTypeIcons.setVisibility(View.VISIBLE);
96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Show the total call count only if there are more than the maximum number of icons.
98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final Integer callCount;
99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (count > MAX_CALL_TYPE_ICONS) {
100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      callCount = count;
101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      callCount = null;
103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Set the call count, location, date and if voicemail, set the duration.
106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    setDetailText(views, callCount, details);
107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Set the account label if it exists.
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    String accountLabel = mCallLogCache.getAccountLabel(details.accountHandle);
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!TextUtils.isEmpty(details.viaNumber)) {
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.isEmpty(accountLabel)) {
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        accountLabel =
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            mResources.getString(
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                R.string.call_log_via_number_phone_account, accountLabel, details.viaNumber);
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        accountLabel = mResources.getString(R.string.call_log_via_number, details.viaNumber);
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!TextUtils.isEmpty(accountLabel)) {
120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      views.callAccountLabel.setVisibility(View.VISIBLE);
121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      views.callAccountLabel.setText(accountLabel);
122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int color = mCallLogCache.getAccountColor(details.accountHandle);
123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (color == PhoneAccount.NO_HIGHLIGHT_COLOR) {
124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        int defaultColor = R.color.dialer_secondary_text_color;
125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        views.callAccountLabel.setTextColor(mContext.getResources().getColor(defaultColor));
126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        views.callAccountLabel.setTextColor(color);
128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      views.callAccountLabel.setVisibility(View.GONE);
131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final CharSequence nameText;
134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final CharSequence displayNumber = details.displayNumber;
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(details.getPreferredName())) {
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      nameText = displayNumber;
137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // We have a real phone number as "nameView" so make it always LTR
138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      views.nameView.setTextDirection(View.TEXT_DIRECTION_LTR);
139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      nameText = details.getPreferredName();
141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    views.nameView.setText(nameText);
144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (isVoicemail) {
1468369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian      int relevantLinkTypes = Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS | Linkify.WEB_URLS;
1478369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian      views.voicemailTranscriptionView.setAutoLinkMask(relevantLinkTypes);
148e85fa664ac1e7394a7e9e5d0c8dc61ba1e33ab1csail      views.voicemailTranscriptionView.setText(
149e85fa664ac1e7394a7e9e5d0c8dc61ba1e33ab1csail          TextUtils.isEmpty(details.transcription) ? null : details.transcription);
150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Bold if not read
153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Typeface typeface = details.isRead ? Typeface.SANS_SERIF : Typeface.DEFAULT_BOLD;
154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    views.nameView.setTypeface(typeface);
155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    views.voicemailTranscriptionView.setTypeface(typeface);
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    views.callLocationAndDate.setTypeface(typeface);
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    views.callLocationAndDate.setTextColor(
158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ContextCompat.getColor(
159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            mContext,
160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            details.isRead ? R.color.call_log_detail_color : R.color.call_log_unread_text_color));
161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Builds a string containing the call location and date. For voicemail logs only the call date is
165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * returned because location information is displayed in the call action button
166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param details The call details.
168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return The call location and date string.
169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public CharSequence getCallLocationAndDate(PhoneCallDetails details) {
171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mDescriptionItems.clear();
172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (details.callTypes[0] != Calls.VOICEMAIL_TYPE) {
174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Get type of call (ie mobile, home, etc) if known, or the caller's location.
175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      CharSequence callTypeOrLocation = getCallTypeOrLocation(details);
176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Only add the call type or location if its not empty.  It will be empty for unknown
178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // callers.
179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.isEmpty(callTypeOrLocation)) {
180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mDescriptionItems.add(callTypeOrLocation);
181ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // The date of this call
185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mDescriptionItems.add(getCallDate(details));
186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Create a comma separated list from the call type or location, and call date.
188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return DialerUtils.join(mDescriptionItems);
189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
190ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
191ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
192ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * For a call, if there is an associated contact for the caller, return the known call type (e.g.
193ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * mobile, home, work). If there is no associated contact, attempt to use the caller's location if
194ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * known.
195ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
196ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param details Call details to use.
197ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return Type of call (mobile/home) if known, or the location of the caller (if known).
198ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
199ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public CharSequence getCallTypeOrLocation(PhoneCallDetails details) {
200ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (details.isSpam) {
201ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return mResources.getString(R.string.spam_number_call_log_label);
202ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (details.isBlocked) {
203ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return mResources.getString(R.string.blocked_number_call_log_label);
204ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
205ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
206ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    CharSequence numberFormattedLabel = null;
207ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Only show a label if the number is shown and it is not a SIP address.
208ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!TextUtils.isEmpty(details.number)
209ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && !PhoneNumberHelper.isUriNumber(details.number.toString())
210ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && !mCallLogCache.isVoicemailNumber(details.accountHandle, details.number)) {
211ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
212d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      if (shouldShowLocation(details)) {
213ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        numberFormattedLabel = details.geocode;
214ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else if (!(details.numberType == Phone.TYPE_CUSTOM
215ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          && TextUtils.isEmpty(details.numberLabel))) {
216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // Get type label only if it will not be "Custom" because of an empty number label.
217ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        numberFormattedLabel =
218ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            mPhoneTypeLabelForTest != null
219ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                ? mPhoneTypeLabelForTest
220ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                : Phone.getTypeLabel(mResources, details.numberType, details.numberLabel);
221ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!TextUtils.isEmpty(details.namePrimary) && TextUtils.isEmpty(numberFormattedLabel)) {
225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      numberFormattedLabel = details.displayNumber;
226ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
227ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return numberFormattedLabel;
228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
230d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  /** Returns true if primary name is empty or the data is from Cequint Caller ID. */
231d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  private static boolean shouldShowLocation(PhoneCallDetails details) {
232d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    if (TextUtils.isEmpty(details.geocode)) {
233d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      return false;
234d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    }
235d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    // For caller ID provided by Cequint we want to show the geo location.
2368369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    if (details.sourceType == ContactSource.Type.SOURCE_TYPE_CEQUINT_CALLER_ID) {
237d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      return true;
238d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    }
239d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    // Don't bother showing geo location for contacts.
240d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    if (!TextUtils.isEmpty(details.namePrimary)) {
241d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian      return false;
242d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    }
243d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    return true;
244d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  }
245d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian
246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setPhoneTypeLabelForTest(CharSequence phoneTypeLabel) {
247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    this.mPhoneTypeLabelForTest = phoneTypeLabel;
248ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
250ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
251ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Get the call date/time of the call. For the call log this is relative to the current time. e.g.
252ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * 3 minutes ago. For voicemail, see {@link #getGranularDateTime(PhoneCallDetails)}
253ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
254ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param details Call details to use.
255ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return String representing when the call occurred.
256ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
257ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public CharSequence getCallDate(PhoneCallDetails details) {
258ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (details.callTypes[0] == Calls.VOICEMAIL_TYPE) {
259ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return getGranularDateTime(details);
260ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
261ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
262ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return DateUtils.getRelativeTimeSpanString(
263ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        details.date,
264ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        getCurrentTimeMillis(),
265ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        DateUtils.MINUTE_IN_MILLIS,
266ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        DateUtils.FORMAT_ABBREV_RELATIVE);
267ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
268ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
269ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
270ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Get the granular version of the call date/time of the call. The result is always in the form
271ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * 'DATE at TIME'. The date value changes based on when the call was created.
272ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
273ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>If created today, DATE is 'Today' If created this year, DATE is 'MMM dd' Otherwise, DATE is
274ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * 'MMM dd, yyyy'
275ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
276ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>TIME is the localized time format, e.g. 'hh:mm a' or 'HH:mm'
277ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
278ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param details Call details to use
279ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return String representing when the call occurred
280ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
281ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public CharSequence getGranularDateTime(PhoneCallDetails details) {
282ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mResources.getString(
283ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        R.string.voicemailCallLogDateTimeFormat,
284ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        getGranularDate(details.date),
285ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        DateUtils.formatDateTime(mContext, details.date, DateUtils.FORMAT_SHOW_TIME));
286ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
287ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
288ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
289ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Get the granular version of the call date. See {@link #getGranularDateTime(PhoneCallDetails)}
290ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
291ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private String getGranularDate(long date) {
292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (DateUtils.isToday(date)) {
293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return mResources.getString(R.string.voicemailCallLogToday);
294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return DateUtils.formatDateTime(
296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mContext,
297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        date,
298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        DateUtils.FORMAT_SHOW_DATE
299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            | DateUtils.FORMAT_ABBREV_MONTH
300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            | (shouldShowYear(date) ? DateUtils.FORMAT_SHOW_YEAR : DateUtils.FORMAT_NO_YEAR));
301ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
302ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Determines whether the year should be shown for the given date
305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
306ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return {@code true} if date is within the current year, {@code false} otherwise
307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean shouldShowYear(long date) {
309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mCalendar.setTimeInMillis(getCurrentTimeMillis());
310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int currentYear = mCalendar.get(Calendar.YEAR);
311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mCalendar.setTimeInMillis(date);
312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return currentYear != mCalendar.get(Calendar.YEAR);
313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Sets the text of the header view for the details page of a phone call. */
316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setCallDetailsHeader(TextView nameView, PhoneCallDetails details) {
317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final CharSequence nameText;
318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!TextUtils.isEmpty(details.namePrimary)) {
319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      nameText = details.namePrimary;
320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (!TextUtils.isEmpty(details.displayNumber)) {
321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      nameText = details.displayNumber;
322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      nameText = mResources.getString(R.string.unknown);
324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    nameView.setText(nameText);
327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setCurrentTimeForTest(long currentTimeMillis) {
330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mCurrentTimeMillisForTest = currentTimeMillis;
331ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
332ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
334ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Returns the current time in milliseconds since the epoch.
335ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
336ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>It can be injected in tests using {@link #setCurrentTimeForTest(long)}.
337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
338ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private long getCurrentTimeMillis() {
339ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mCurrentTimeMillisForTest == null) {
340ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return System.currentTimeMillis();
341ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
342ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return mCurrentTimeMillisForTest;
343ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
344ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
345ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
346ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Sets the call count, date, and if it is a voicemail, sets the duration. */
347ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void setDetailText(
348ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      PhoneCallDetailsViews views, Integer callCount, PhoneCallDetails details) {
349ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Combine the count (if present) and the date.
350ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    CharSequence dateText = details.callLocationAndDate;
351ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final CharSequence text;
352ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (callCount != null) {
353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      text = mResources.getString(R.string.call_log_item_count_and_date, callCount, dateText);
354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
355ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      text = dateText;
356ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
357ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
358ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (details.callTypes[0] == Calls.VOICEMAIL_TYPE && details.duration > 0) {
359ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      views.callLocationAndDate.setText(
360ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          mResources.getString(
361ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              R.string.voicemailCallLogDateTimeFormatWithDuration,
362ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              text,
363ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              getVoicemailDuration(details)));
364ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
365ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      views.callLocationAndDate.setText(text);
366ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
367ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
368ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
369ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private String getVoicemailDuration(PhoneCallDetails details) {
370ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    long minutes = TimeUnit.SECONDS.toMinutes(details.duration);
371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    long seconds = details.duration - TimeUnit.MINUTES.toSeconds(minutes);
372ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (minutes > 99) {
373ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      minutes = 99;
374ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
375ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mResources.getString(R.string.voicemailDurationFormat, minutes, seconds);
376ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
377ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
378