summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/app/calllog/CallLogListItemHelper.java
diff options
context:
space:
mode:
authorEric Erfanian <erfanian@google.com>2017-02-22 16:32:36 -0800
committerEric Erfanian <erfanian@google.com>2017-03-01 09:56:52 -0800
commitccca31529c07970e89419fb85a9e8153a5396838 (patch)
treea7034c0a01672b97728c13282a2672771cd28baa /java/com/android/dialer/app/calllog/CallLogListItemHelper.java
parente7ae4624ba6f25cb8e648db74e0d64c0113a16ba (diff)
Update dialer sources.
Test: Built package and system image. This change clobbers the old source, and is an export from an internal Google repository. The internal repository was forked form Android in March, and this change includes modifications since then, to near the v8 release. Since the fork, we've moved code from monolithic to independent modules. In addition, we've switched to Blaze/Bazel as the build sysetm. This export, however, still uses make. New dependencies have been added: - Dagger - Auto-Value - Glide - Libshortcutbadger Going forward, development will still be in Google3, and the Gerrit release will become an automated export, with the next drop happening in ~ two weeks. Android.mk includes local modifications from ToT. Abridged changelog: Bug fixes ● Not able to mute, add a call when using Phone app in multiwindow mode ● Double tap on keypad triggering multiple key and tones ● Reported spam numbers not showing as spam in the call log ● Crash when user tries to block number while Phone app is not set as default ● Crash when user picks a number from search auto-complete list Visual Voicemail (VVM) improvements ● Share Voicemail audio via standard exporting mechanisms that support file attachment (email, MMS, etc.) ● Make phone number, email and web sites in VVM transcript clickable ● Set PIN before declining VVM Terms of Service {Carrier} ● Set client type for outbound visual voicemail SMS {Carrier} New incoming call and incall UI on older devices (Android M) ● Updated Phone app icon ● New incall UI (large buttons, button labels) ● New and animated Answer/Reject gestures Accessibility ● Add custom answer/decline call buttons on answer screen for touch exploration accessibility services ● Increase size of touch target ● Add verbal feedback when a Voicemail fails to load ● Fix pressing of Phone buttons while in a phone call using Switch Access ● Fix selecting and opening contacts in talkback mode ● Split focus for ‘Learn More’ link in caller id & spam to help distinguish similar text Other ● Backup & Restore for App Preferences ● Prompt user to enable Wi-Fi calling if the call ends due to out of service and Wi-Fi is connected ● Rename “Dialpad” to “Keypad” ● Show "Private number" for restricted calls ● Delete unused items (vcard, add contact, call history) from Phone menu Change-Id: I2a7e53532a24c21bf308bf0a6d178d7ddbca4958
Diffstat (limited to 'java/com/android/dialer/app/calllog/CallLogListItemHelper.java')
-rw-r--r--java/com/android/dialer/app/calllog/CallLogListItemHelper.java277
1 files changed, 277 insertions, 0 deletions
diff --git a/java/com/android/dialer/app/calllog/CallLogListItemHelper.java b/java/com/android/dialer/app/calllog/CallLogListItemHelper.java
new file mode 100644
index 000000000..ea2119c83
--- /dev/null
+++ b/java/com/android/dialer/app/calllog/CallLogListItemHelper.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2011 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.app.calllog;
+
+import android.content.res.Resources;
+import android.provider.CallLog.Calls;
+import android.support.annotation.WorkerThread;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.util.Log;
+import com.android.dialer.app.PhoneCallDetails;
+import com.android.dialer.app.R;
+import com.android.dialer.app.calllog.calllogcache.CallLogCache;
+import com.android.dialer.common.Assert;
+import com.android.dialer.compat.AppCompatConstants;
+
+/** Helper class to fill in the views of a call log entry. */
+/* package */ class CallLogListItemHelper {
+
+ private static final String TAG = "CallLogListItemHelper";
+
+ /** Helper for populating the details of a phone call. */
+ private final PhoneCallDetailsHelper mPhoneCallDetailsHelper;
+ /** Resources to look up strings. */
+ private final Resources mResources;
+
+ private final CallLogCache mCallLogCache;
+
+ /**
+ * Creates a new helper instance.
+ *
+ * @param phoneCallDetailsHelper used to set the details of a phone call
+ * @param resources The object from which resources can be retrieved
+ * @param callLogCache A cache for values retrieved from telecom/telephony
+ */
+ public CallLogListItemHelper(
+ PhoneCallDetailsHelper phoneCallDetailsHelper,
+ Resources resources,
+ CallLogCache callLogCache) {
+ mPhoneCallDetailsHelper = phoneCallDetailsHelper;
+ mResources = resources;
+ mCallLogCache = callLogCache;
+ }
+
+ /**
+ * Update phone call details. This is called before any drawing to avoid expensive operation on UI
+ * thread.
+ *
+ * @param details
+ */
+ @WorkerThread
+ public void updatePhoneCallDetails(PhoneCallDetails details) {
+ Assert.isWorkerThread();
+ details.callLocationAndDate = mPhoneCallDetailsHelper.getCallLocationAndDate(details);
+ details.callDescription = getCallDescription(details);
+ }
+
+ /**
+ * Sets the name, label, and number for a contact.
+ *
+ * @param views the views to populate
+ * @param details the details of a phone call needed to fill in the data
+ */
+ public void setPhoneCallDetails(CallLogListItemViewHolder views, PhoneCallDetails details) {
+ mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details);
+
+ // Set the accessibility text for the contact badge
+ views.quickContactView.setContentDescription(getContactBadgeDescription(details));
+
+ // Set the primary action accessibility description
+ views.primaryActionView.setContentDescription(details.callDescription);
+
+ // Cache name or number of caller. Used when setting the content descriptions of buttons
+ // when the actions ViewStub is inflated.
+ views.nameOrNumber = getNameOrNumber(details);
+
+ // The call type or Location associated with the call. Use when setting text for a
+ // voicemail log's call button
+ views.callTypeOrLocation = mPhoneCallDetailsHelper.getCallTypeOrLocation(details);
+
+ // Cache country iso. Used for number filtering.
+ views.countryIso = details.countryIso;
+
+ views.updatePhoto();
+ }
+
+ /**
+ * Sets the accessibility descriptions for the action buttons in the action button ViewStub.
+ *
+ * @param views The views associated with the current call log entry.
+ */
+ public void setActionContentDescriptions(CallLogListItemViewHolder views) {
+ if (views.nameOrNumber == null) {
+ Log.e(TAG, "setActionContentDescriptions; name or number is null.");
+ }
+
+ // Calling expandTemplate with a null parameter will cause a NullPointerException.
+ // Although we don't expect a null name or number, it is best to protect against it.
+ CharSequence nameOrNumber = views.nameOrNumber == null ? "" : views.nameOrNumber;
+
+ views.videoCallButtonView.setContentDescription(
+ TextUtils.expandTemplate(
+ mResources.getString(R.string.description_video_call_action), nameOrNumber));
+
+ views.createNewContactButtonView.setContentDescription(
+ TextUtils.expandTemplate(
+ mResources.getString(R.string.description_create_new_contact_action), nameOrNumber));
+
+ views.addToExistingContactButtonView.setContentDescription(
+ TextUtils.expandTemplate(
+ mResources.getString(R.string.description_add_to_existing_contact_action),
+ nameOrNumber));
+
+ views.detailsButtonView.setContentDescription(
+ TextUtils.expandTemplate(
+ mResources.getString(R.string.description_details_action), nameOrNumber));
+ }
+
+ /**
+ * Returns the accessibility description for the contact badge for a call log entry.
+ *
+ * @param details Details of call.
+ * @return Accessibility description.
+ */
+ private CharSequence getContactBadgeDescription(PhoneCallDetails details) {
+ if (details.isSpam) {
+ return mResources.getString(
+ R.string.description_spam_contact_details, getNameOrNumber(details));
+ }
+ return mResources.getString(R.string.description_contact_details, getNameOrNumber(details));
+ }
+
+ /**
+ * Returns the accessibility description of the "return call/call" action for a call log entry.
+ * Accessibility text is a combination of: {Voicemail Prefix}. {Number of Calls}. {Caller
+ * information} {Phone Account}. If most recent call is a voicemail, {Voicemail Prefix} is "New
+ * Voicemail.", otherwise "".
+ *
+ * <p>If more than one call for the caller, {Number of Calls} is: "{number of calls} calls.",
+ * otherwise "".
+ *
+ * <p>The {Caller Information} references the most recent call associated with the caller. For
+ * incoming calls: If missed call: Missed call from {Name/Number} {Call Type} {Call Time}. If
+ * answered call: Answered call from {Name/Number} {Call Type} {Call Time}.
+ *
+ * <p>For outgoing calls: If outgoing: Call to {Name/Number] {Call Type} {Call Time}.
+ *
+ * <p>Where: {Name/Number} is the name or number of the caller (as shown in call log). {Call type}
+ * is the contact phone number type (eg mobile) or location. {Call Time} is the time since the
+ * last call for the contact occurred.
+ *
+ * <p>The {Phone Account} refers to the account/SIM through which the call was placed or received
+ * in multi-SIM devices.
+ *
+ * <p>Examples: 3 calls. New Voicemail. Missed call from Joe Smith mobile 2 hours ago on SIM 1.
+ *
+ * <p>2 calls. Answered call from John Doe mobile 1 hour ago.
+ *
+ * @param context The application context.
+ * @param details Details of call.
+ * @return Return call action description.
+ */
+ public CharSequence getCallDescription(PhoneCallDetails details) {
+ // Get the name or number of the caller.
+ final CharSequence nameOrNumber = getNameOrNumber(details);
+
+ // Get the call type or location of the caller; null if not applicable
+ final CharSequence typeOrLocation = mPhoneCallDetailsHelper.getCallTypeOrLocation(details);
+
+ // Get the time/date of the call
+ final CharSequence timeOfCall = mPhoneCallDetailsHelper.getCallDate(details);
+
+ SpannableStringBuilder callDescription = new SpannableStringBuilder();
+
+ // Add number of calls if more than one.
+ if (details.callTypes.length > 1) {
+ callDescription.append(
+ mResources.getString(R.string.description_num_calls, details.callTypes.length));
+ }
+
+ // If call had video capabilities, add the "Video Call" string.
+ if ((details.features & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO) {
+ callDescription.append(mResources.getString(R.string.description_video_call));
+ }
+
+ String accountLabel = mCallLogCache.getAccountLabel(details.accountHandle);
+ CharSequence onAccountLabel =
+ PhoneCallDetails.createAccountLabelDescription(mResources, details.viaNumber, accountLabel);
+
+ int stringID = getCallDescriptionStringID(details.callTypes, details.isRead);
+ callDescription.append(
+ TextUtils.expandTemplate(
+ mResources.getString(stringID),
+ nameOrNumber,
+ typeOrLocation == null ? "" : typeOrLocation,
+ timeOfCall,
+ onAccountLabel));
+
+ return callDescription;
+ }
+
+ /**
+ * Determine the appropriate string ID to describe a call for accessibility purposes.
+ *
+ * @param callTypes The type of call corresponding to this entry or multiple if this entry
+ * represents multiple calls grouped together.
+ * @param isRead If the entry is a voicemail, {@code true} if the voicemail is read.
+ * @return String resource ID to use.
+ */
+ public int getCallDescriptionStringID(int[] callTypes, boolean isRead) {
+ int lastCallType = getLastCallType(callTypes);
+ int stringID;
+
+ if (lastCallType == AppCompatConstants.CALLS_MISSED_TYPE) {
+ //Message: Missed call from <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>,
+ //<PhoneAccount>.
+ stringID = R.string.description_incoming_missed_call;
+ } else if (lastCallType == AppCompatConstants.CALLS_INCOMING_TYPE) {
+ //Message: Answered call from <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>,
+ //<PhoneAccount>.
+ stringID = R.string.description_incoming_answered_call;
+ } else if (lastCallType == AppCompatConstants.CALLS_VOICEMAIL_TYPE) {
+ //Message: (Unread) [V/v]oicemail from <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>,
+ //<PhoneAccount>.
+ stringID =
+ isRead ? R.string.description_read_voicemail : R.string.description_unread_voicemail;
+ } else {
+ //Message: Call to <NameOrNumber>, <TypeOrLocation>, <TimeOfCall>, <PhoneAccount>.
+ stringID = R.string.description_outgoing_call;
+ }
+ return stringID;
+ }
+
+ /**
+ * Determine the call type for the most recent call.
+ *
+ * @param callTypes Call types to check.
+ * @return Call type.
+ */
+ private int getLastCallType(int[] callTypes) {
+ if (callTypes.length > 0) {
+ return callTypes[0];
+ } else {
+ return Calls.MISSED_TYPE;
+ }
+ }
+
+ /**
+ * Return the name or number of the caller specified by the details.
+ *
+ * @param details Call details
+ * @return the name (if known) of the caller, otherwise the formatted number.
+ */
+ private CharSequence getNameOrNumber(PhoneCallDetails details) {
+ final CharSequence recipient;
+ if (!TextUtils.isEmpty(details.getPreferredName())) {
+ recipient = details.getPreferredName();
+ } else {
+ recipient = details.displayNumber + details.postDialDigits;
+ }
+ return recipient;
+ }
+}