diff options
Diffstat (limited to 'java/com/android/dialer/calllogutils')
8 files changed, 348 insertions, 95 deletions
diff --git a/java/com/android/dialer/calllogutils/CallLogDates.java b/java/com/android/dialer/calllogutils/CallLogDates.java index 2c332901c..9c04c05f7 100644 --- a/java/com/android/dialer/calllogutils/CallLogDates.java +++ b/java/com/android/dialer/calllogutils/CallLogDates.java @@ -36,13 +36,16 @@ public final class CallLogDates { * if < 1 minute ago: "Just now"; * else if < 1 hour ago: time relative to now (e.g., "8 min ago"); * else if today: time (e.g., "12:15 PM"); - * else if < 7 days: abbreviated day of week (e.g., "Wed"); - * else if < 1 year: date with abbreviated month, day, but no year (e.g., "Jan 15"); - * else: date with abbreviated month, day, and year (e.g., "Jan 15, 2018"). + * else if < 7 days: day of week (e.g., "Wed"); + * else if < 1 year: date with month, day, but no year (e.g., "Jan 15"); + * else: date with month, day, and year (e.g., "Jan 15, 2018"). * </pre> + * + * <p>Callers can decide whether to abbreviate date/time by specifying flag {@code + * abbreviateDateTime}. */ public static CharSequence newCallLogTimestampLabel( - Context context, long nowMillis, long timestampMillis) { + Context context, long nowMillis, long timestampMillis, boolean abbreviateDateTime) { // For calls logged less than 1 minute ago, display "Just now". if (nowMillis - timestampMillis < TimeUnit.MINUTES.toMillis(1)) { return context.getString(R.string.just_now); @@ -50,16 +53,19 @@ public final class CallLogDates { // For calls logged less than 1 hour ago, display time relative to now (e.g., "8 min ago"). if (nowMillis - timestampMillis < TimeUnit.HOURS.toMillis(1)) { - return DateUtils.getRelativeTimeSpanString( - timestampMillis, - nowMillis, - DateUtils.MINUTE_IN_MILLIS, - DateUtils.FORMAT_ABBREV_RELATIVE) - .toString() - // The platform method DateUtils#getRelativeTimeSpanString adds a dot ('.') after the - // abbreviated time unit for some languages (e.g., "8 min. ago") but we prefer not to have - // the dot. - .replace(".", ""); + return abbreviateDateTime + ? DateUtils.getRelativeTimeSpanString( + timestampMillis, + nowMillis, + DateUtils.MINUTE_IN_MILLIS, + DateUtils.FORMAT_ABBREV_RELATIVE) + .toString() + // The platform method DateUtils#getRelativeTimeSpanString adds a dot ('.') after the + // abbreviated time unit for some languages (e.g., "8 min. ago") but we prefer not to + // have the dot. + .replace(".", "") + : DateUtils.getRelativeTimeSpanString( + timestampMillis, nowMillis, DateUtils.MINUTE_IN_MILLIS); } int dayDifference = getDayDifference(nowMillis, timestampMillis); @@ -69,19 +75,19 @@ public final class CallLogDates { return DateUtils.formatDateTime(context, timestampMillis, DateUtils.FORMAT_SHOW_TIME); } - // For calls logged within a week, display the abbreviated day of week (e.g., "Wed"). + // For calls logged within a week, display the day of week (e.g., "Wed"). if (dayDifference < 7) { - return formatDayOfWeek(context, timestampMillis); + return formatDayOfWeek(context, timestampMillis, abbreviateDateTime); } - // For calls logged within a year, display abbreviated month, day, but no year (e.g., "Jan 15"). + // For calls logged within a year, display month, day, but no year (e.g., "Jan 15"). if (isWithinOneYear(nowMillis, timestampMillis)) { - return formatAbbreviatedDate(context, timestampMillis, /* showYear = */ false); + return formatDate(context, timestampMillis, /* showYear = */ false, abbreviateDateTime); } - // For calls logged no less than one year ago, display abbreviated month, day, and year + // For calls logged no less than one year ago, display month, day, and year // (e.g., "Jan 15, 2018"). - return formatAbbreviatedDate(context, timestampMillis, /* showYear = */ true); + return formatDate(context, timestampMillis, /* showYear = */ true, abbreviateDateTime); } /** @@ -106,36 +112,41 @@ public final class CallLogDates { } /** - * Formats the provided timestamp (in milliseconds) into abbreviated day of week. + * Formats the provided timestamp (in milliseconds) into the month, day, and optionally, year. * - * <p>For example, returns a string like "Wed" or "Chor". + * <p>For example, returns a string like "Jan 15" or "Jan 15, 2018". * * <p>For pre-N devices, the returned value may not start with a capital if the local convention * is to not capitalize day names. On N+ devices, the returned value is always capitalized. */ - private static CharSequence formatDayOfWeek(Context context, long timestamp) { - return toTitleCase( - DateUtils.formatDateTime( - context, timestamp, DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_WEEKDAY)); + private static CharSequence formatDate( + Context context, long timestamp, boolean showYear, boolean abbreviateDateTime) { + int formatFlags = 0; + if (abbreviateDateTime) { + formatFlags |= DateUtils.FORMAT_ABBREV_MONTH; + } + if (!showYear) { + formatFlags |= DateUtils.FORMAT_NO_YEAR; + } + + return toTitleCase(DateUtils.formatDateTime(context, timestamp, formatFlags)); } /** - * Formats the provided timestamp (in milliseconds) into the month abbreviation, day, and - * optionally, year. + * Formats the provided timestamp (in milliseconds) into day of week. * - * <p>For example, returns a string like "Jan 15" or "Jan 15, 2018". + * <p>For example, returns a string like "Wed" or "Chor". * * <p>For pre-N devices, the returned value may not start with a capital if the local convention * is to not capitalize day names. On N+ devices, the returned value is always capitalized. */ - private static CharSequence formatAbbreviatedDate( - Context context, long timestamp, boolean showYear) { - int flags = DateUtils.FORMAT_ABBREV_MONTH; - if (!showYear) { - flags |= DateUtils.FORMAT_NO_YEAR; - } - - return toTitleCase(DateUtils.formatDateTime(context, timestamp, flags)); + private static CharSequence formatDayOfWeek( + Context context, long timestamp, boolean abbreviateDateTime) { + int formatFlags = + abbreviateDateTime + ? (DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_WEEKDAY) + : DateUtils.FORMAT_SHOW_WEEKDAY; + return toTitleCase(DateUtils.formatDateTime(context, timestamp, formatFlags)); } private static CharSequence toTitleCase(CharSequence value) { diff --git a/java/com/android/dialer/calllogutils/CallLogEntryDescriptions.java b/java/com/android/dialer/calllogutils/CallLogEntryDescriptions.java new file mode 100644 index 000000000..244087989 --- /dev/null +++ b/java/com/android/dialer/calllogutils/CallLogEntryDescriptions.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dialer.calllogutils; + +import android.content.Context; +import android.provider.CallLog.Calls; +import android.support.annotation.PluralsRes; +import android.telecom.PhoneAccountHandle; +import android.text.TextUtils; +import com.android.dialer.calllog.model.CoalescedRow; +import com.android.dialer.telecom.TelecomUtil; +import com.android.dialer.time.Clock; +import com.google.common.collect.Collections2; +import java.util.List; + +/** Builds descriptions of call log entries for accessibility users. */ +public final class CallLogEntryDescriptions { + + private CallLogEntryDescriptions() {} + + /** + * Builds the content description for a call log entry. + * + * <p>The description is of format<br> + * {primary description}, {secondary description}, {phone account description}. + * + * <ul> + * <li>The primary description depends on the number of calls in the entry. For example:<br> + * "1 answered call from Jane Smith", or<br> + * "2 calls, the latest is an answered call from Jane Smith". + * <li>The secondary description is the same as the secondary text for the call log entry, + * except that date/time is not abbreviated. For example:<br> + * "mobile, 11 minutes ago". + * <li>The phone account description is of format "on {phone_account_label}, via {number}". For + * example:<br> + * "on SIM 1, via 6502531234".<br> + * Note that the phone account description will be empty if the device has only one SIM. + * </ul> + * + * <p>An example of the full description can be:<br> + * "2 calls, the latest is an answered call from Jane Smith, mobile, 11 minutes ago, on SIM 1, via + * 6502531234". + */ + public static CharSequence buildDescriptionForEntry( + Context context, Clock clock, CoalescedRow row) { + + // Build the primary description. + // Examples: + // (1) For an entry containing only 1 call: + // "1 missed call from James Smith". + // (2) For entries containing multiple calls: + // "2 calls, the latest is a missed call from Jame Smith". + CharSequence primaryDescription = + context + .getResources() + .getQuantityString( + getPrimaryDescriptionResIdForCallType(row), + row.getCoalescedIds().getCoalescedIdCount(), + row.getCoalescedIds().getCoalescedIdCount(), + CallLogEntryText.buildPrimaryText(context, row)); + + // Build the secondary description. + // An example: "mobile, 11 minutes ago". + CharSequence secondaryDescription = + joinSecondaryTextComponents( + CallLogEntryText.buildSecondaryTextListForEntries( + context, clock, row, /* abbreviateDateTime = */ false)); + + // Build the phone account description. + // Note that this description can be an empty string. + CharSequence phoneAccountDescription = buildPhoneAccountDescription(context, row); + + return TextUtils.isEmpty(phoneAccountDescription) + ? context + .getResources() + .getString( + R.string.a11y_new_call_log_entry_full_description_without_phone_account_info, + primaryDescription, + secondaryDescription) + : context + .getResources() + .getString( + R.string.a11y_new_call_log_entry_full_description_with_phone_account_info, + primaryDescription, + secondaryDescription, + phoneAccountDescription); + } + + private static @PluralsRes int getPrimaryDescriptionResIdForCallType(CoalescedRow row) { + switch (row.getCallType()) { + case Calls.INCOMING_TYPE: + case Calls.ANSWERED_EXTERNALLY_TYPE: + return R.plurals.a11y_new_call_log_entry_answered_call; + case Calls.OUTGOING_TYPE: + return R.plurals.a11y_new_call_log_entry_outgoing_call; + case Calls.MISSED_TYPE: + return R.plurals.a11y_new_call_log_entry_missed_call; + case Calls.VOICEMAIL_TYPE: + throw new IllegalStateException("Voicemails not expected in call log"); + case Calls.BLOCKED_TYPE: + return R.plurals.a11y_new_call_log_entry_blocked_call; + default: + // It is possible for users to end up with calls with unknown call types in their + // call history, possibly due to 3rd party call log implementations (e.g. to + // distinguish between rejected and missed calls). Instead of crashing, just + // assume that all unknown call types are missed calls. + return R.plurals.a11y_new_call_log_entry_missed_call; + } + } + + private static CharSequence buildPhoneAccountDescription(Context context, CoalescedRow row) { + PhoneAccountHandle phoneAccountHandle = + TelecomUtil.composePhoneAccountHandle( + row.getPhoneAccountComponentName(), row.getPhoneAccountId()); + if (phoneAccountHandle == null) { + return ""; + } + + String phoneAccountLabel = PhoneAccountUtils.getAccountLabel(context, phoneAccountHandle); + if (TextUtils.isEmpty(phoneAccountLabel)) { + return ""; + } + + if (TextUtils.isEmpty(row.getNumber().getNormalizedNumber())) { + return ""; + } + + return context + .getResources() + .getString( + R.string.a11y_new_call_log_entry_phone_account, + phoneAccountLabel, + row.getNumber().getNormalizedNumber()); + } + + private static CharSequence joinSecondaryTextComponents(List<CharSequence> components) { + return TextUtils.join( + ", ", Collections2.filter(components, (text) -> !TextUtils.isEmpty(text))); + } +} diff --git a/java/com/android/dialer/calllogutils/CallLogEntryText.java b/java/com/android/dialer/calllogutils/CallLogEntryText.java index acf8ef932..895497f0f 100644 --- a/java/com/android/dialer/calllogutils/CallLogEntryText.java +++ b/java/com/android/dialer/calllogutils/CallLogEntryText.java @@ -26,6 +26,7 @@ import com.android.dialer.time.Clock; import com.google.common.base.Optional; import com.google.common.collect.Collections2; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -76,45 +77,69 @@ public final class CallLogEntryText { } /** - * The secondary text to show in the main call log entry list. + * The secondary text to be shown in the main call log entry list. + * + * <p>This method first obtains a list of strings to be shown in order and then concatenates them + * with " • ". + * + * <p>Examples: + * + * <ul> + * <li>Mobile, Duo video • 10 min ago + * <li>Spam • Mobile • Now + * <li>Blocked • Spam • Mobile • Now + * </ul> + * + * @see #buildSecondaryTextListForEntries(Context, Clock, CoalescedRow, boolean) for details. + */ + public static CharSequence buildSecondaryTextForEntries( + Context context, Clock clock, CoalescedRow row) { + return joinSecondaryTextComponents( + buildSecondaryTextListForEntries(context, clock, row, /* abbreviateDateTime = */ true)); + } + + /** + * Returns a list of strings to be shown in order as the main call log entry's secondary text. * * <p>Rules: * * <ul> - * <li>An emergency number: Date + * <li>An emergency number: [{Date}] * <li>Number - not blocked, call - not spam: - * <p>$Label(, Duo video|Carrier video)?|$Location • Date + * <p>[{$Label(, Duo video|Carrier video)?|$Location}, {Date}] * <li>Number - blocked, call - not spam: - * <p>Blocked • $Label(, Duo video|Carrier video)?|$Location • Date + * <p>["Blocked", {$Label(, Duo video|Carrier video)?|$Location}, {Date}] * <li>Number - not blocked, call - spam: - * <p>Spam • $Label(, Duo video|Carrier video)? • Date + * <p>["Spam", {$Label(, Duo video|Carrier video)?}, {Date}] * <li>Number - blocked, call - spam: - * <p>Blocked • Spam • $Label(, Duo video|Carrier video)? • Date + * <p>["Blocked, Spam", {$Label(, Duo video|Carrier video)?}, {Date}] * </ul> * * <p>Examples: * * <ul> - * <li>Mobile, Duo video • Now - * <li>Duo video • 10 min ago - * <li>Mobile • 11:45 PM - * <li>Mobile • Sun - * <li>Blocked • Mobile, Duo video • Now - * <li>Blocked • Brooklyn, NJ • 10 min ago - * <li>Spam • Mobile • Now - * <li>Spam • Now - * <li>Blocked • Spam • Mobile • Now - * <li>Brooklyn, NJ • Jan 15 + * <li>["Mobile, Duo video", "Now"] + * <li>["Duo video", "10 min ago"] + * <li>["Mobile", "11:45 PM"] + * <li>["Mobile", "Sun"] + * <li>["Blocked", "Mobile, Duo video", "Now"] + * <li>["Blocked", "Brooklyn, NJ", "10 min ago"] + * <li>["Spam", "Mobile", "Now"] + * <li>["Spam", "Now"] + * <li>["Blocked", "Spam", "Mobile", "Now"] + * <li>["Brooklyn, NJ", "Jan 15"] * </ul> * - * <p>See {@link CallLogDates#newCallLogTimestampLabel(Context, long, long)} for date rules. + * <p>See {@link CallLogDates#newCallLogTimestampLabel(Context, long, long, boolean)} for date + * rules. */ - public static CharSequence buildSecondaryTextForEntries( - Context context, Clock clock, CoalescedRow row) { + static List<CharSequence> buildSecondaryTextListForEntries( + Context context, Clock clock, CoalescedRow row, boolean abbreviateDateTime) { // For emergency numbers, the secondary text should contain only the timestamp. if (row.getNumberAttributes().getIsEmergencyNumber()) { - return CallLogDates.newCallLogTimestampLabel( - context, clock.currentTimeMillis(), row.getTimestamp()); + return Collections.singletonList( + CallLogDates.newCallLogTimestampLabel( + context, clock.currentTimeMillis(), row.getTimestamp(), abbreviateDateTime)); } List<CharSequence> components = new ArrayList<>(); @@ -130,8 +155,8 @@ public final class CallLogEntryText { components.add( CallLogDates.newCallLogTimestampLabel( - context, clock.currentTimeMillis(), row.getTimestamp())); - return joinSecondaryTextComponents(components); + context, clock.currentTimeMillis(), row.getTimestamp(), abbreviateDateTime)); + return components; } /** diff --git a/java/com/android/dialer/calllogutils/CallTypeHelper.java b/java/com/android/dialer/calllogutils/CallTypeHelper.java index 6feaeb998..1bcaa317b 100644 --- a/java/com/android/dialer/calllogutils/CallTypeHelper.java +++ b/java/com/android/dialer/calllogutils/CallTypeHelper.java @@ -17,7 +17,7 @@ package com.android.dialer.calllogutils; import android.content.res.Resources; -import com.android.dialer.compat.AppCompatConstants; +import android.provider.CallLog.Calls; import com.android.dialer.duo.Duo; /** Helper class to perform operations related to call types. */ @@ -87,17 +87,17 @@ public class CallTypeHelper { } public static boolean isMissedCallType(int callType) { - return (callType != AppCompatConstants.CALLS_INCOMING_TYPE - && callType != AppCompatConstants.CALLS_OUTGOING_TYPE - && callType != AppCompatConstants.CALLS_VOICEMAIL_TYPE - && callType != AppCompatConstants.CALLS_ANSWERED_EXTERNALLY_TYPE); + return (callType != Calls.INCOMING_TYPE + && callType != Calls.OUTGOING_TYPE + && callType != Calls.VOICEMAIL_TYPE + && callType != Calls.ANSWERED_EXTERNALLY_TYPE); } /** Returns the text used to represent the given call type. */ public CharSequence getCallTypeText( int callType, boolean isVideoCall, boolean isPulledCall, boolean isDuoCall) { switch (callType) { - case AppCompatConstants.CALLS_INCOMING_TYPE: + case Calls.INCOMING_TYPE: if (isVideoCall) { if (isPulledCall) { return incomingVideoPulledName; @@ -115,7 +115,7 @@ public class CallTypeHelper { } } - case AppCompatConstants.CALLS_OUTGOING_TYPE: + case Calls.OUTGOING_TYPE: if (isVideoCall) { if (isPulledCall) { return outgoingVideoPulledName; @@ -133,23 +133,23 @@ public class CallTypeHelper { } } - case AppCompatConstants.CALLS_MISSED_TYPE: + case Calls.MISSED_TYPE: if (isVideoCall) { return missedVideoName; } else { return missedName; } - case AppCompatConstants.CALLS_VOICEMAIL_TYPE: + case Calls.VOICEMAIL_TYPE: return voicemailName; - case AppCompatConstants.CALLS_REJECTED_TYPE: + case Calls.REJECTED_TYPE: return rejectedName; - case AppCompatConstants.CALLS_BLOCKED_TYPE: + case Calls.BLOCKED_TYPE: return blockedName; - case AppCompatConstants.CALLS_ANSWERED_EXTERNALLY_TYPE: + case Calls.ANSWERED_EXTERNALLY_TYPE: return answeredElsewhereName; default: diff --git a/java/com/android/dialer/calllogutils/CallTypeIconsView.java b/java/com/android/dialer/calllogutils/CallTypeIconsView.java index 30d9b6178..19c30c575 100644 --- a/java/com/android/dialer/calllogutils/CallTypeIconsView.java +++ b/java/com/android/dialer/calllogutils/CallTypeIconsView.java @@ -23,11 +23,12 @@ import android.graphics.Canvas; import android.graphics.PorterDuff; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.provider.CallLog.Calls; import android.support.annotation.VisibleForTesting; import android.util.AttributeSet; import android.view.View; -import com.android.dialer.compat.AppCompatConstants; -import com.android.dialer.theme.ThemeUtil; +import com.android.dialer.theme.base.Theme; +import com.android.dialer.theme.base.ThemeComponent; import java.util.ArrayList; import java.util.List; @@ -167,16 +168,16 @@ public class CallTypeIconsView extends View { private Drawable getCallTypeDrawable(int callType) { Resources resources = useLargeIcons ? largeResouces : CallTypeIconsView.resources; switch (callType) { - case AppCompatConstants.CALLS_INCOMING_TYPE: - case AppCompatConstants.CALLS_ANSWERED_EXTERNALLY_TYPE: + case Calls.INCOMING_TYPE: + case Calls.ANSWERED_EXTERNALLY_TYPE: return resources.incoming; - case AppCompatConstants.CALLS_OUTGOING_TYPE: + case Calls.OUTGOING_TYPE: return resources.outgoing; - case AppCompatConstants.CALLS_MISSED_TYPE: + case Calls.MISSED_TYPE: return resources.missed; - case AppCompatConstants.CALLS_VOICEMAIL_TYPE: + case Calls.VOICEMAIL_TYPE: return resources.voicemail; - case AppCompatConstants.CALLS_BLOCKED_TYPE: + case Calls.BLOCKED_TYPE: return resources.blocked; default: // It is possible for users to end up with calls with unknown call types in their @@ -289,55 +290,56 @@ public class CallTypeIconsView extends View { int iconId = R.drawable.quantum_ic_call_received_white_24; Drawable drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId); incoming = drawable.mutate(); - incoming.setColorFilter(r.getColor(R.color.answered_call), PorterDuff.Mode.MULTIPLY); + incoming.setColorFilter(r.getColor(R.color.dialer_call_green), PorterDuff.Mode.MULTIPLY); // Create a rotated instance of the call arrow for outgoing calls. iconId = R.drawable.quantum_ic_call_made_white_24; drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId); outgoing = drawable.mutate(); - outgoing.setColorFilter(r.getColor(R.color.answered_call), PorterDuff.Mode.MULTIPLY); + outgoing.setColorFilter(r.getColor(R.color.dialer_call_green), PorterDuff.Mode.MULTIPLY); // Need to make a copy of the arrow drawable, otherwise the same instance colored // above will be recolored here. iconId = R.drawable.quantum_ic_call_missed_white_24; drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId); missed = drawable.mutate(); - missed.setColorFilter(r.getColor(R.color.missed_call), PorterDuff.Mode.MULTIPLY); + missed.setColorFilter(r.getColor(R.color.dialer_red), PorterDuff.Mode.MULTIPLY); + Theme theme = ThemeComponent.get(context).theme(); iconId = R.drawable.quantum_ic_voicemail_white_24; drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId); voicemail = drawable.mutate(); - voicemail.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY); + voicemail.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY); iconId = R.drawable.quantum_ic_block_white_24; drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId); blocked = drawable.mutate(); - blocked.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY); + blocked.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY); iconId = R.drawable.quantum_ic_videocam_vd_white_24; drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId); videoCall = drawable.mutate(); - videoCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY); + videoCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY); iconId = R.drawable.quantum_ic_hd_white_24; drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId); hdCall = drawable.mutate(); - hdCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY); + hdCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY); iconId = R.drawable.quantum_ic_signal_wifi_4_bar_white_24; drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId); wifiCall = drawable.mutate(); - wifiCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY); + wifiCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY); iconId = R.drawable.quantum_ic_language_white_24; drawable = largeIcons ? r.getDrawable(iconId) : getScaledBitmap(context, iconId); assistedDialedCall = drawable.mutate(); - assistedDialedCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY); + assistedDialedCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY); iconId = R.drawable.quantum_ic_rtt_vd_theme_24; drawable = largeIcons ? r.getDrawable(iconId, null) : getScaledBitmap(context, iconId); rttCall = drawable.mutate(); - rttCall.setColorFilter(ThemeUtil.getColorIcon(), PorterDuff.Mode.MULTIPLY); + rttCall.setColorFilter(theme.getColorIcon(), PorterDuff.Mode.MULTIPLY); iconMargin = largeIcons ? 0 : r.getDimensionPixelSize(R.dimen.call_log_icon_margin); } diff --git a/java/com/android/dialer/calllogutils/PhotoInfoBuilder.java b/java/com/android/dialer/calllogutils/PhotoInfoBuilder.java index 0677c9114..2e2e4abcb 100644 --- a/java/com/android/dialer/calllogutils/PhotoInfoBuilder.java +++ b/java/com/android/dialer/calllogutils/PhotoInfoBuilder.java @@ -16,6 +16,7 @@ package com.android.dialer.calllogutils; +import android.content.Context; import android.provider.CallLog.Calls; import android.support.v4.os.BuildCompat; import com.android.dialer.NumberAttributes; @@ -28,8 +29,9 @@ import com.android.dialer.voicemail.model.VoicemailEntry; public final class PhotoInfoBuilder { /** Returns a {@link PhotoInfo.Builder} with info from {@link CoalescedRow}. */ - public static PhotoInfo.Builder fromCoalescedRow(CoalescedRow coalescedRow) { + public static PhotoInfo.Builder fromCoalescedRow(Context context, CoalescedRow coalescedRow) { return fromNumberAttributes(coalescedRow.getNumberAttributes()) + .setName(CallLogEntryText.buildPrimaryText(context, coalescedRow).toString()) .setFormattedNumber(coalescedRow.getFormattedNumber()) .setIsVoicemail(coalescedRow.getIsVoicemailCall()) .setIsSpam( diff --git a/java/com/android/dialer/calllogutils/res/values/colors.xml b/java/com/android/dialer/calllogutils/res/values/colors.xml index 8662163c1..3a9e3ae8a 100644 --- a/java/com/android/dialer/calllogutils/res/values/colors.xml +++ b/java/com/android/dialer/calllogutils/res/values/colors.xml @@ -15,8 +15,4 @@ ~ limitations under the License --> <resources> - <!-- Color for missed call icons. --> - <color name="missed_call">#C53929</color> - <!-- Color for answered or outgoing call icons. --> - <color name="answered_call">#00c853</color> </resources>
\ No newline at end of file diff --git a/java/com/android/dialer/calllogutils/res/values/strings.xml b/java/com/android/dialer/calllogutils/res/values/strings.xml index e476bdd6c..52b6d3408 100644 --- a/java/com/android/dialer/calllogutils/res/values/strings.xml +++ b/java/com/android/dialer/calllogutils/res/values/strings.xml @@ -145,4 +145,67 @@ <!-- String used to display calls from spam numbers in the call log. [CHAR LIMIT=30] --> <string name="new_call_log_secondary_spam">Spam</string> + + <!-- + String introducing to a11y users a call log entry in which the latest call is a missed call. + [CHAR LIMIT=NONE] + --> + <plurals name="a11y_new_call_log_entry_missed_call"> + <item quantity="one"><xliff:g example="1" id="count">%1$d</xliff:g> missed call from <xliff:g example="Jane Smith" id="primaryInfoForEntry">%2$s</xliff:g></item> + <item quantity="other"><xliff:g example="2" id="count">%1$d</xliff:g> calls, the latest is a missed call from <xliff:g example="Jane Smith" id="primaryInfoForEntry">%2$s</xliff:g></item> + </plurals> + + <!-- + String introducing to a11y users a call log entry in which the latest call is an answered call. + [CHAR LIMIT=NONE] + --> + <plurals name="a11y_new_call_log_entry_answered_call"> + <item quantity="one"><xliff:g example="1" id="count">%1$d</xliff:g> answered call from <xliff:g example="Jane Smith" id="primaryInfoForEntry">%2$s</xliff:g></item> + <item quantity="other"><xliff:g example="2" id="count">%1$d</xliff:g> calls, the latest is an answered call from <xliff:g example="Jane Smith" id="primaryInfoForEntry">%2$s</xliff:g></item> + </plurals> + + <!-- + String introducing to a11y users a call log entry in which the latest call is an outgoing call. + [CHAR LIMIT=NONE] + --> + <plurals name="a11y_new_call_log_entry_outgoing_call"> + <item quantity="one"><xliff:g example="1" id="count">%1$d</xliff:g> outgoing call to <xliff:g example="Jane Smith" id="primaryInfoForEntry">%2$s</xliff:g></item> + <item quantity="other"><xliff:g example="2" id="count">%1$d</xliff:g> calls, the latest is an outgoing call to <xliff:g example="Jane Smith" id="primaryInfoForEntry">%2$s</xliff:g></item> + </plurals> + + <!-- + String introducing to a11y users a call log entry in which the latest call is a blocked call. + [CHAR LIMIT=NONE] + --> + <plurals name="a11y_new_call_log_entry_blocked_call"> + <item quantity="one"><xliff:g example="1" id="count">%1$d</xliff:g> blocked call from <xliff:g example="Jane Smith" id="primaryInfoForEntry">%2$s</xliff:g></item> + <item quantity="other"><xliff:g example="2" id="count">%1$d</xliff:g> calls, the latest is a blocked call from <xliff:g example="Jane Smith" id="primaryInfoForEntry">%2$s</xliff:g></item> + </plurals> + + + <!-- + String describing to a11y users the phone account used to make/receive the latest call in a call + log entry. + [CHAR LIMIT=NONE] + --> + <string name="a11y_new_call_log_entry_phone_account"> + on <xliff:g example="SIM 1" id="phoneAccount">%1$s</xliff:g>, + via <xliff:g example="(555) 555-5555" id="number">%2$s</xliff:g> + </string> + + <!-- + String template describing to a11y users a call log entry without phone account info. + [CHAR LIMIT=NONE] + --> + <string name="a11y_new_call_log_entry_full_description_without_phone_account_info"> + <xliff:g example="A missed call from Jane Smith" id="primaryDescriptionForEntry">%1$s</xliff:g>, <xliff:g example="mobile, 30 minutes ago" id="secondaryDescriptionForEntry">%2$s</xliff:g>. + </string> + + <!-- + String template describing to a11y users a call log entry with phone account info. + [CHAR LIMIT=NONE] + --> + <string name="a11y_new_call_log_entry_full_description_with_phone_account_info"> + <xliff:g example="A missed call from Jane Smith" id="primaryDescriptionForEntry">%1$s</xliff:g>, <xliff:g example="mobile, 30 minutes ago" id="secondaryDescriptionForEntry">%2$s</xliff:g>, <xliff:g example="on SIM 1, via (555) 555-5555">%3$s</xliff:g>. + </string> </resources> |