156 lines
6.2 KiB
Java
156 lines
6.2 KiB
Java
|
/*
|
||
|
* 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.telephony.PhoneNumberUtils;
|
||
|
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 =
|
||
|
TextUtils.expandTemplate(
|
||
|
context
|
||
|
.getResources()
|
||
|
.getQuantityString(
|
||
|
getPrimaryDescriptionResIdForCallType(row),
|
||
|
row.getCoalescedIds().getCoalescedIdCount()),
|
||
|
String.valueOf(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)
|
||
|
? TextUtils.expandTemplate(
|
||
|
context
|
||
|
.getResources()
|
||
|
.getText(
|
||
|
R.string.a11y_new_call_log_entry_full_description_without_phone_account_info),
|
||
|
primaryDescription,
|
||
|
secondaryDescription)
|
||
|
: TextUtils.expandTemplate(
|
||
|
context
|
||
|
.getResources()
|
||
|
.getText(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 TextUtils.expandTemplate(
|
||
|
context.getResources().getText(R.string.a11y_new_call_log_entry_phone_account),
|
||
|
phoneAccountLabel,
|
||
|
PhoneNumberUtils.createTtsSpannable(row.getNumber().getNormalizedNumber()));
|
||
|
}
|
||
|
|
||
|
private static CharSequence joinSecondaryTextComponents(List<CharSequence> components) {
|
||
|
return TextUtils.join(
|
||
|
", ", Collections2.filter(components, (text) -> !TextUtils.isEmpty(text)));
|
||
|
}
|
||
|
}
|