194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/* 294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Copyright (C) 2011 The Android Open Source Project 394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * you may not use this file except in compliance with the License. 694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * You may obtain a copy of the License at 794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 1094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Unless required by applicable law or agreed to in writing, software 1194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 1294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * See the License for the specific language governing permissions and 1494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * limitations under the License. 1594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 1694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpackage com.android.dialer; 1894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.res.Resources; 2094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.graphics.Typeface; 21034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Leeimport android.provider.ContactsContract; 2294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.ContactsContract.CommonDataKinds.Phone; 2394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.telephony.PhoneNumberUtils; 2494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.SpannableString; 2594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.Spanned; 2694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.TextUtils; 2794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.format.DateUtils; 2894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.style.ForegroundColorSpan; 2994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.style.StyleSpan; 3094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.View; 3194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.widget.TextView; 3294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 33217d1edcaf8b57829207abf9901c016b1fba9005Chiao Chengimport com.android.contacts.common.test.NeededForTesting; 3494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.calllog.CallTypeHelper; 35034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Leeimport com.android.dialer.calllog.ContactInfo; 3694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.calllog.PhoneNumberHelper; 37fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Chengimport com.android.dialer.calllog.PhoneNumberUtilsWrapper; 3894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 3994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/** 4094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Helper class to fill in the views in {@link PhoneCallDetailsViews}. 4194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 4294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpublic class PhoneCallDetailsHelper { 4394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** The maximum number of icons will be shown to represent the call types in a group. */ 4494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private static final int MAX_CALL_TYPE_ICONS = 3; 4594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 4694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final Resources mResources; 4794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** The injected current time in milliseconds since the epoch. Used only by tests. */ 4894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private Long mCurrentTimeMillisForTest; 4994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Helper classes. 5094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final CallTypeHelper mCallTypeHelper; 5194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final PhoneNumberHelper mPhoneNumberHelper; 52fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng private final PhoneNumberUtilsWrapper mPhoneNumberUtilsWrapper; 5394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 5494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 5594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Creates a new instance of the helper. 5694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 5794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Generally you should have a single instance of this helper in any context. 5894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 5994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * @param resources used to look up strings 6094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 6194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public PhoneCallDetailsHelper(Resources resources, CallTypeHelper callTypeHelper, 62fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng PhoneNumberUtilsWrapper phoneUtils) { 6394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mResources = resources; 6494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mCallTypeHelper = callTypeHelper; 65fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng mPhoneNumberHelper = new PhoneNumberHelper(resources); 66fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng mPhoneNumberUtilsWrapper = phoneUtils; 6794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 6894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 6994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Fills the call details views with content. */ 7094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void setPhoneCallDetails(PhoneCallDetailsViews views, PhoneCallDetails details, 7194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng boolean isHighlighted) { 7294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Display up to a given number of icons. 7394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng views.callTypeIcons.clear(); 7494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng int count = details.callTypes.length; 7594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng for (int index = 0; index < count && index < MAX_CALL_TYPE_ICONS; ++index) { 7694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng views.callTypeIcons.add(details.callTypes[index]); 7794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 787e8ea191d0858f02b6b1c002f54c18ab798bd732Yorke Lee views.callTypeIcons.requestLayout(); 7994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng views.callTypeIcons.setVisibility(View.VISIBLE); 8094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 8194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Show the total call count only if there are more than the maximum number of icons. 8294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final Integer callCount; 8394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (count > MAX_CALL_TYPE_ICONS) { 8494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng callCount = count; 8594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 8694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng callCount = null; 8794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 8894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // The color to highlight the count and date in, if any. This is based on the first call. 8994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Integer highlightColor = 9094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng isHighlighted ? mCallTypeHelper.getHighlightedColor(details.callTypes[0]) : null; 9194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 9294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // The date of this call, relative to the current time. 9394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CharSequence dateText = 9494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng DateUtils.getRelativeTimeSpanString(details.date, 9594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getCurrentTimeMillis(), 9694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng DateUtils.MINUTE_IN_MILLIS, 9794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng DateUtils.FORMAT_ABBREV_RELATIVE); 9894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 9994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Set the call count and date. 10094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng setCallCountAndDate(views, callCount, dateText, highlightColor); 10194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 10294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CharSequence numberFormattedLabel = null; 10394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Only show a label if the number is shown and it is not a SIP address. 10494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (!TextUtils.isEmpty(details.number) 10594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng && !PhoneNumberUtils.isUriNumber(details.number.toString())) { 106034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee if (details.numberLabel == ContactInfo.GEOCODE_AS_LABEL) { 107034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee numberFormattedLabel = details.geocode; 108034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee } else { 109034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee numberFormattedLabel = Phone.getTypeLabel(mResources, details.numberType, 110034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee details.numberLabel); 111034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee } 11294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 11394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 11494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence nameText; 11594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence numberText; 11694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence labelText; 11794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence displayNumber = 118719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner mPhoneNumberHelper.getDisplayNumber(details.number, 119719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner details.numberPresentation, details.formattedNumber); 12094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (TextUtils.isEmpty(details.name)) { 12194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameText = displayNumber; 12294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (TextUtils.isEmpty(details.geocode) 123fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng || mPhoneNumberUtilsWrapper.isVoicemailNumber(details.number)) { 12494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng numberText = mResources.getString(R.string.call_log_empty_gecode); 12594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 12694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng numberText = details.geocode; 12794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 128481994f4962ec937ba8775578c2bb9d76141fd7fYorke Lee labelText = numberText; 129c341db0532d8b60ca29aa0becf05a4eec9bdc43eFabrice Di Meglio // We have a real phone number as "nameView" so make it always LTR 130c341db0532d8b60ca29aa0becf05a4eec9bdc43eFabrice Di Meglio views.nameView.setTextDirection(View.TEXT_DIRECTION_LTR); 13194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 13294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameText = details.name; 13394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng numberText = displayNumber; 134481994f4962ec937ba8775578c2bb9d76141fd7fYorke Lee labelText = TextUtils.isEmpty(numberFormattedLabel) ? numberText : 135481994f4962ec937ba8775578c2bb9d76141fd7fYorke Lee numberFormattedLabel; 13694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 13794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 13894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng views.nameView.setText(nameText); 139481994f4962ec937ba8775578c2bb9d76141fd7fYorke Lee 14094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng views.labelView.setText(labelText); 14194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng views.labelView.setVisibility(TextUtils.isEmpty(labelText) ? View.GONE : View.VISIBLE); 14294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 14394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 14494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Sets the text of the header view for the details page of a phone call. */ 14594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void setCallDetailsHeader(TextView nameView, PhoneCallDetails details) { 14694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence nameText; 14794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence displayNumber = 148719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner mPhoneNumberHelper.getDisplayNumber(details.number, details.numberPresentation, 14994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mResources.getString(R.string.recentCalls_addToContact)); 15094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (TextUtils.isEmpty(details.name)) { 15194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameText = displayNumber; 15294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 15394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameText = details.name; 15494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 15594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 15694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameView.setText(nameText); 15794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 15894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 15994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @NeededForTesting 16094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void setCurrentTimeForTest(long currentTimeMillis) { 16194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mCurrentTimeMillisForTest = currentTimeMillis; 16294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 16394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 16494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 16594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Returns the current time in milliseconds since the epoch. 16694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 16794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * It can be injected in tests using {@link #setCurrentTimeForTest(long)}. 16894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 16994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private long getCurrentTimeMillis() { 17094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (mCurrentTimeMillisForTest == null) { 17194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return System.currentTimeMillis(); 17294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 17394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return mCurrentTimeMillisForTest; 17494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 17594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 17694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 17794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Sets the call count and date. */ 17894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void setCallCountAndDate(PhoneCallDetailsViews views, Integer callCount, 17994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CharSequence dateText, Integer highlightColor) { 18094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Combine the count (if present) and the date. 18194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence text; 18294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (callCount != null) { 18394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng text = mResources.getString( 18494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng R.string.call_log_item_count_and_date, callCount.intValue(), dateText); 18594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 18694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng text = dateText; 18794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 18894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 18994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Apply the highlight color if present. 19094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence formattedText; 19194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (highlightColor != null) { 19294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng formattedText = addBoldAndColor(text, highlightColor); 19394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 19494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng formattedText = text; 19594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 19694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 19794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng views.callTypeAndDate.setText(formattedText); 19894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 19994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 20094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Creates a SpannableString for the given text which is bold and in the given color. */ 20194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private CharSequence addBoldAndColor(CharSequence text, int color) { 20294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng int flags = Spanned.SPAN_INCLUSIVE_INCLUSIVE; 20394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng SpannableString result = new SpannableString(text); 20494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng result.setSpan(new StyleSpan(Typeface.BOLD), 0, text.length(), flags); 20594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng result.setSpan(new ForegroundColorSpan(color), 0, text.length(), flags); 20694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return result; 20794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 20894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng} 209