summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Gunn <tgunn@google.com>2014-02-03 08:31:10 -0800
committerJay Shrauner <shrauner@google.com>2014-03-04 12:17:24 -0800
commit27c57f5ec6421d8de15214c09114266b4a917bed (patch)
treea10e40800f315c989d945310900e3a40b4c3cea3
parentef793edd768d25b43bc4ea597ae68fa0d742be74 (diff)
Call History Affordances Swap
1. Swapped the intents for the primary view 2. Changed the icon for the secondary action button 3. Added a vertical divider line to separate the secondary action button from the primary view 4. Cleaned up the accessibility text Bug: 12800272 Change-Id: Ifd4ceff0d67b1587c4378e29be7344de50057a7d (cherry picked from commit 45ed3b5932ed590b45235d7b2befa736a95e7f75)
-rw-r--r--res/layout/call_log_list_item.xml42
-rw-r--r--res/values/dimens.xml7
-rw-r--r--res/values/strings.xml80
-rw-r--r--src/com/android/dialer/PhoneCallDetailsHelper.java54
-rw-r--r--src/com/android/dialer/calllog/CallLogAdapter.java52
-rw-r--r--src/com/android/dialer/calllog/CallLogFragment.java2
-rw-r--r--src/com/android/dialer/calllog/CallLogListItemHelper.java203
-rw-r--r--src/com/android/dialer/calllog/CallLogListItemViews.java12
-rw-r--r--src/com/android/dialer/list/PhoneFavoriteFragment.java2
-rw-r--r--src/com/android/dialerbind/ObjectFactory.java14
-rw-r--r--tests/AndroidManifest.xml1
-rw-r--r--tests/src/com/android/dialer/calllog/CallLogFragmentTest.java28
-rw-r--r--tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java245
13 files changed, 632 insertions, 110 deletions
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
index 1d368f63d..15d7a9275 100644
--- a/res/layout/call_log_list_item.xml
+++ b/res/layout/call_log_list_item.xml
@@ -114,18 +114,38 @@
/>
</LinearLayout>
</LinearLayout>
- <ImageButton
- android:id="@+id/secondary_action_icon"
- android:layout_width="@dimen/call_log_call_action_width"
+ <!-- Linear layout to house a vertical separator line and the
+ secondary action button. Used as a convenience to hide both
+ the separator and action button at the same time. -->
+ <LinearLayout
+ android:id="@+id/secondary_action_view"
+ android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:paddingStart="@dimen/call_log_inner_margin"
- android:paddingTop="@dimen/call_log_inner_margin"
- android:paddingBottom="@dimen/call_log_inner_margin"
- android:paddingEnd="@dimen/call_log_inner_margin"
- android:scaleType="center"
- android:background="?android:attr/selectableItemBackground"
- android:nextFocusLeft="@id/primary_action_view"
- />
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ >
+ <!-- Thin vertical divider to visually separate the secondary action button -->
+ <View
+ android:id="@+id/vertical_divider"
+ android:layout_width="@dimen/call_log_list_item_vertical_divider_width"
+ android:layout_height="match_parent"
+ android:layout_marginTop="@dimen/call_log_list_item_vertical_divider_margin"
+ android:layout_marginBottom="@dimen/call_log_list_item_vertical_divider_margin"
+ android:background="?android:attr/dividerVertical"/>
+ <!-- The secondary action button; either play voicemail or call details. -->
+ <ImageButton
+ android:id="@+id/secondary_action_icon"
+ android:layout_width="@dimen/call_log_call_action_width"
+ android:layout_height="match_parent"
+ android:paddingStart="@dimen/call_log_inner_margin"
+ android:paddingTop="@dimen/call_log_inner_margin"
+ android:paddingBottom="@dimen/call_log_inner_margin"
+ android:paddingEnd="@dimen/call_log_inner_margin"
+ android:scaleType="center"
+ android:background="?android:attr/selectableItemBackground"
+ android:nextFocusLeft="@id/primary_action_view"
+ />
+ </LinearLayout>
</LinearLayout>
<TextView
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 53d9c47e5..942698741 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -43,6 +43,13 @@
<dimen name="call_log_list_contact_photo_size">64dip</dimen>
<dimen name="call_detail_contact_name_margin">24dip</dimen>
<dimen name="call_detail_button_spacing">2dip</dimen>
+ <!-- Defines the vertical margin for the vertical separator between
+ the main area of a call log entry and the secondary action button. -->
+ <dimen name="call_log_list_item_vertical_divider_margin">8dp</dimen>
+
+ <!-- Defines the width of the vertical separator between
+ the main area of a call log entry and the secondary action button. -->
+ <dimen name="call_log_list_item_vertical_divider_width">1dp</dimen>
<!-- Layout weight values for dialpad screen. These layouts will be used in one
LinearLayout (dialpad_fragment.xml), configuring dialpad screen's vertical
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a0376a6e0..e84834113 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -435,6 +435,86 @@
-->
<string name="description_call">Call <xliff:g id="name">%1$s</xliff:g></string>
+ <!-- String describing the button to access the contact details for a name or number.
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_contact_details">Contact details for <xliff:g id="nameOrNumber">%1$s</xliff:g></string>
+
+ <!-- String describing the button to access call details in the call log.
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_call_details">Call details</string>
+
+ <!-- String indicating a call log entry has an associated voicemail.
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_new_voicemail">New voicemail.</string>
+
+ <!-- String indicating the number of calls to/from a caller in the call log.
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_num_calls"><xliff:g id="numberOfCalls">%1$s</xliff:g> calls.</string>
+
+
+ <!-- Call history description for a missed call from a caller.
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_return_missed_call">Return missed call from <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g> <xliff:g id="timeOfCall">%3$s</xliff:g></string>
+
+
+ <!-- Call history description for an answered call for a caller.
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_return_answered_call">Return answered call from <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g> <xliff:g id="timeOfCall">%3$s</xliff:g></string>
+
+ <!-- Call history description for a missed call from an unknown caller.
+ Drops the "return" part of description_return_missed_call since it is not
+ possible to actually call an unknown number.
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_unknown_missed_call">Missed call from <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g> <xliff:g id="timeOfCall">%3$s</xliff:g></string>
+
+
+ <!-- Call history description for an answered call from an unknown caller.
+ Drops the "return" part of description_return_answered_call since it is not
+ possible to actually call an unknown number.
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_unknown_answered_call">Answered call from <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g> <xliff:g id="timeOfCall">%3$s</xliff:g></string>
+
+ <!-- String describing an outgoing call entry in the call log. Used to indicate that
+ a call will be made to the specified caller. Used when there are multiple calls to/from
+ the caller.
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_call_last_multiple">Call <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g>. Last called <xliff:g id="timeOfCall">%3$s</xliff:g>.</string>
+
+ <!-- String describing an outgoing call entry in the call log. Used to indicate that
+ a call will be made to the specified caller. Used when there is only a single call
+ related to/from the caller.
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ -->
+ <string name="description_call_last">Call <xliff:g id="nameOrNumber">%1$s</xliff:g> <xliff:g id="typeOrLocation">%2$s</xliff:g>. Called <xliff:g id="timeOfCall">%3$s</xliff:g>.</string>
+
<!-- String describing the button to SMS a number or contact.
diff --git a/src/com/android/dialer/PhoneCallDetailsHelper.java b/src/com/android/dialer/PhoneCallDetailsHelper.java
index 446df021d..aee5052eb 100644
--- a/src/com/android/dialer/PhoneCallDetailsHelper.java
+++ b/src/com/android/dialer/PhoneCallDetailsHelper.java
@@ -90,26 +90,13 @@ public class PhoneCallDetailsHelper {
isHighlighted ? mCallTypeHelper.getHighlightedColor(details.callTypes[0]) : null;
// The date of this call, relative to the current time.
- CharSequence dateText =
- DateUtils.getRelativeTimeSpanString(details.date,
- getCurrentTimeMillis(),
- DateUtils.MINUTE_IN_MILLIS,
- DateUtils.FORMAT_ABBREV_RELATIVE);
+ CharSequence dateText = getCallDate(details);
// Set the call count and date.
setCallCountAndDate(views, callCount, dateText, highlightColor);
- CharSequence numberFormattedLabel = null;
- // Only show a label if the number is shown and it is not a SIP address.
- if (!TextUtils.isEmpty(details.number)
- && !PhoneNumberUtils.isUriNumber(details.number.toString())) {
- if (details.numberLabel == ContactInfo.GEOCODE_AS_LABEL) {
- numberFormattedLabel = details.geocode;
- } else {
- numberFormattedLabel = Phone.getTypeLabel(mResources, details.numberType,
- details.numberLabel);
- }
- }
+ // Get type of call (ie mobile, home, etc) if known, or the caller's
+ CharSequence numberFormattedLabel = getCallTypeOrLocation(details);
final CharSequence nameText;
final CharSequence numberText;
@@ -140,6 +127,41 @@ public class PhoneCallDetailsHelper {
views.labelView.setVisibility(TextUtils.isEmpty(labelText) ? View.GONE : View.VISIBLE);
}
+ /**
+ * For a call, if there is an associated contact for the caller, return the known call type
+ * (e.g. mobile, home, work). If there is no associated contact, attempt to use the caller's
+ * location if known.
+ * @param details Call details to use.
+ * @return Type of call (mobile/home) if known, or the location of the caller (if known).
+ */
+ public CharSequence getCallTypeOrLocation(PhoneCallDetails details) {
+ CharSequence numberFormattedLabel = null;
+ // Only show a label if the number is shown and it is not a SIP address.
+ if (!TextUtils.isEmpty(details.number)
+ && !PhoneNumberUtils.isUriNumber(details.number.toString())) {
+ if (details.numberLabel == ContactInfo.GEOCODE_AS_LABEL) {
+ numberFormattedLabel = details.geocode;
+ } else {
+ numberFormattedLabel = Phone.getTypeLabel(mResources, details.numberType,
+ details.numberLabel);
+ }
+ }
+ return numberFormattedLabel;
+ }
+
+ /**
+ * Get the call date/time of the call, relative to the current time.
+ * e.g. 3 minutes ago
+ * @param details Call details to use.
+ * @return String representing when the call occurred.
+ */
+ public CharSequence getCallDate(PhoneCallDetails details) {
+ return DateUtils.getRelativeTimeSpanString(details.date,
+ getCurrentTimeMillis(),
+ DateUtils.MINUTE_IN_MILLIS,
+ DateUtils.FORMAT_ABBREV_RELATIVE);
+ }
+
/** Sets the text of the header view for the details page of a phone call. */
public void setCallDetailsHeader(TextView nameView, PhoneCallDetails details) {
final CharSequence nameText;
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index a668196c5..32699e654 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -183,9 +183,11 @@ public class CallLogAdapter extends GroupingListAdapter
/** Can be set to true by tests to disable processing of requests. */
private volatile boolean mRequestProcessingDisabled = false;
- /** True if CallLogAdapter is created from the PhoneFavoriteFragment, where the primary
- * action should be set to call a number instead of opening the detail page. */
- private boolean mUseCallAsPrimaryAction = false;
+ /**
+ * Whether to show the secondary action button used to play voicemail or show call details.
+ * True if created from a CallLogFragment.
+ * False if created from the PhoneFavoriteFragment. */
+ private boolean mShowSecondaryActionButton = true;
private boolean mIsCallLog = true;
private int mNumMissedCalls = 0;
@@ -246,14 +248,14 @@ public class CallLogAdapter extends GroupingListAdapter
};
public CallLogAdapter(Context context, CallFetcher callFetcher,
- ContactInfoHelper contactInfoHelper, boolean useCallAsPrimaryAction,
+ ContactInfoHelper contactInfoHelper, boolean showSecondaryActionButton,
boolean isCallLog) {
super(context);
mContext = context;
mCallFetcher = callFetcher;
mContactInfoHelper = contactInfoHelper;
- mUseCallAsPrimaryAction = useCallAsPrimaryAction;
+ mShowSecondaryActionButton = showSecondaryActionButton;
mIsCallLog = isCallLog;
mContactInfoCache = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE);
@@ -508,7 +510,7 @@ public class CallLogAdapter extends GroupingListAdapter
// Get the views to bind to.
CallLogListItemViews views = CallLogListItemViews.fromView(view);
views.primaryActionView.setOnClickListener(mActionListener);
- views.secondaryActionView.setOnClickListener(mActionListener);
+ views.secondaryActionButtonView.setOnClickListener(mActionListener);
view.setTag(views);
}
@@ -535,31 +537,30 @@ public class CallLogAdapter extends GroupingListAdapter
final ContactInfo cachedContactInfo = getContactInfoFromCallLog(c);
- if (!mUseCallAsPrimaryAction) {
- // Sets the primary action to open call detail page.
- views.primaryActionView.setTag(
- IntentProvider.getCallDetailIntentProvider(
- getCursor(), c.getPosition(), c.getLong(CallLogQuery.ID), count));
- } else if (PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation)) {
+ // Primary action is always to call, if possible.
+ if (PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation)) {
// Sets the primary action to call the number.
views.primaryActionView.setTag(IntentProvider.getReturnCallIntentProvider(number));
} else {
views.primaryActionView.setTag(null);
}
- // Store away the voicemail information so we can play it directly.
- if (callType == Calls.VOICEMAIL_TYPE) {
- String voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI);
- final long rowId = c.getLong(CallLogQuery.ID);
- views.secondaryActionView.setTag(
- IntentProvider.getPlayVoicemailIntentProvider(rowId, voicemailUri));
- } else if (!TextUtils.isEmpty(number)) {
- // Store away the number so we can call it directly if you click on the call icon.
- views.secondaryActionView.setTag(
- IntentProvider.getReturnCallIntentProvider(number));
+ if ( mShowSecondaryActionButton ) {
+ // Store away the voicemail information so we can play it directly.
+ if (callType == Calls.VOICEMAIL_TYPE) {
+ String voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI);
+ final long rowId = c.getLong(CallLogQuery.ID);
+ views.secondaryActionButtonView.setTag(
+ IntentProvider.getPlayVoicemailIntentProvider(rowId, voicemailUri));
+ } else {
+ // Store the call details information.
+ views.secondaryActionButtonView.setTag(
+ IntentProvider.getCallDetailIntentProvider(
+ getCursor(), c.getPosition(), c.getLong(CallLogQuery.ID), count));
+ }
} else {
// No action enabled.
- views.secondaryActionView.setTag(null);
+ views.secondaryActionButtonView.setTag(null);
}
// Lookup contacts with this number
@@ -624,7 +625,7 @@ public class CallLogAdapter extends GroupingListAdapter
// New items also use the highlighted version of the text.
final boolean isHighlighted = isNew;
mCallLogViewsHelper.setPhoneCallDetails(views, details, isHighlighted,
- mUseCallAsPrimaryAction);
+ mShowSecondaryActionButton);
if (photoId == 0 && photoUri != null) {
setPhoto(views, photoUri, lookupUri);
@@ -632,9 +633,6 @@ public class CallLogAdapter extends GroupingListAdapter
setPhoto(views, photoId, lookupUri);
}
- views.quickContactView.setContentDescription(views.phoneCallDetailsViews.nameView.
- getText());
-
// Listen for the first draw
if (mViewTreeObserver == null) {
mViewTreeObserver = view.getViewTreeObserver();
diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java
index c8e261358..37af4dba0 100644
--- a/src/com/android/dialer/calllog/CallLogFragment.java
+++ b/src/com/android/dialer/calllog/CallLogFragment.java
@@ -230,7 +230,7 @@ public class CallLogFragment extends ListFragment
updateEmptyMessage(mCallTypeFilter);
String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
mAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this, new ContactInfoHelper(
- getActivity(), currentCountryIso), false, true);
+ getActivity(), currentCountryIso), true, true);
setListAdapter(mAdapter);
getListView().setItemsCanFocus(true);
}
diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java
index a38ef012b..a85cd019e 100644
--- a/src/com/android/dialer/calllog/CallLogListItemHelper.java
+++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java
@@ -17,6 +17,7 @@
package com.android.dialer.calllog;
import android.content.res.Resources;
+import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.text.TextUtils;
import android.view.View;
@@ -55,37 +56,201 @@ import com.android.dialer.R;
* @param views the views to populate
* @param details the details of a phone call needed to fill in the data
* @param isHighlighted whether to use the highlight text for the call
+ * @param showSecondaryActionButton whether to show the secondary action button or not
*/
public void setPhoneCallDetails(CallLogListItemViews views, PhoneCallDetails details,
- boolean isHighlighted, boolean useCallAsPrimaryAction) {
+ boolean isHighlighted, boolean showSecondaryActionButton) {
mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details,
isHighlighted);
- boolean canCall = PhoneNumberUtilsWrapper.canPlaceCallsTo(details.number,
- details.numberPresentation);
boolean canPlay = details.callTypes[0] == Calls.VOICEMAIL_TYPE;
- if (canPlay) {
- // Playback action takes preference.
- configurePlaySecondaryAction(views, isHighlighted);
- } else if (canCall && !useCallAsPrimaryAction) {
- // Call is the secondary action.
- configureCallSecondaryAction(views, details);
+ // Set the accessibility text for the contact badge
+ views.quickContactView.setContentDescription(getContactBadgeDescription(details));
+
+ // Set the primary action accessibility description
+ views.primaryActionView.setContentDescription(getCallDescription(details));
+
+ // If secondary action is visible, either show voicemail playback icon, or
+ // show the "clock" icon corresponding to the call details screen.
+ if (showSecondaryActionButton) {
+ if (canPlay) {
+ // Playback action takes preference.
+ configurePlaySecondaryAction(views, isHighlighted);
+ } else {
+ // Call details is the secondary action.
+ configureCallDetailsSecondaryAction(views, details);
+ }
} else {
- // No action available.
+ // No secondary action is to be shown (ie this is likely a PhoneFavoriteFragment)
views.secondaryActionView.setVisibility(View.GONE);
}
}
- /** Sets the secondary action to correspond to the call button. */
- private void configureCallSecondaryAction(CallLogListItemViews views,
+ /**
+ * Sets the secondary action to invoke call details.
+ *
+ * @param views the views to populate
+ * @param details the details of a phone call needed to fill in the call details data
+ */
+ private void configureCallDetailsSecondaryAction(CallLogListItemViews views,
PhoneCallDetails details) {
views.secondaryActionView.setVisibility(View.VISIBLE);
- views.secondaryActionView.setImageResource(R.drawable.ic_phone_dk);
- views.secondaryActionView.setContentDescription(getCallActionDescription(details));
+ // Use the small dark grey clock icon.
+ views.secondaryActionButtonView.setImageResource(R.drawable.ic_menu_history_dk);
+ views.secondaryActionButtonView.setContentDescription(
+ mResources.getString(R.string.description_call_details));
+ }
+
+ /**
+ * 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) {
+ return mResources.getString(R.string.description_contact_details, getNameOrNumber(details));
}
- /** Returns the description used by the call action for this phone call. */
- private CharSequence getCallActionDescription(PhoneCallDetails 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}.
+ * If most recent call is a voicemail, {Voicemail Prefix} is "New Voicemail.", otherwise "".
+ *
+ * If more than one call for the caller, {Number of Calls} is:
+ * "{number of calls} calls.", otherwise "".
+ *
+ * The {Caller Information} references the most recent call associated with the caller.
+ * For incoming calls:
+ * If missed call: Return missed call from {Name/Number} {Call Type} {Call Time}.
+ * If answered call: Return answered call from {Name/Number} {Call Type} {Call Time}.
+ *
+ * For unknown callers, drop the "Return" part, since the call can't be returned:
+ * If answered unknown: Answered call from {Name/Number} {Call Time}.
+ * If missed unknown: Missed call from {Name/Number} {Call Time}.
+ *
+ * For outgoing calls:
+ * If outgoing: Call {Name/Number] {Call Type}. {Last} called {Call Time}.
+ * Where {Last} is dropped if the number of calls for the caller is 1.
+ *
+ * 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.
+ *
+ * Examples:
+ * 3 calls. New Voicemail. Return missed call from Joe Smith mobile 2 hours ago.
+ * 2 calls. Call John Doe mobile. Last called 1 hour ago.
+ * @param details Details of call.
+ * @return Return call action description.
+ */
+ public CharSequence getCallDescription(PhoneCallDetails details) {
+ int lastCallType = getLastCallType(details.callTypes);
+ boolean isVoiceMail = lastCallType == Calls.VOICEMAIL_TYPE;
+
+ // 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);
+
+ StringBuilder callDescription = new StringBuilder();
+
+ // Prepend the voicemail indication.
+ if (isVoiceMail) {
+ callDescription.append(mResources.getString(R.string.description_new_voicemail));
+ }
+
+ // 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));
+ }
+
+ int stringID = getCallDescriptionStringID(details);
+
+ // Use chosen string resource to build up the message.
+ callDescription.append(mResources.getString(stringID,
+ nameOrNumber,
+ // If no type or location can be determined, sub in empty string.
+ typeOrLocation == null ? "" : typeOrLocation,
+ timeOfCall));
+
+ return callDescription;
+ }
+
+ /**
+ * Determine the appropriate string ID to describe a call for accessibility purposes.
+ *
+ * @param details Call details.
+ * @return String resource ID to use.
+ */
+ public int getCallDescriptionStringID(PhoneCallDetails details) {
+ int lastCallType = getLastCallType(details.callTypes);
+ boolean isNumberCallable = PhoneNumberUtilsWrapper.canPlaceCallsTo(details.number,
+ details.numberPresentation);
+
+ // Default string to use is "call XYZ..." just in case we manage to fall through.
+ int stringID = R.string.description_call_last_multiple;
+
+ if (!isNumberCallable) {
+ // Number isn't callable; this is an incoming call from an unknown caller.
+ // An uncallable outgoing call wouldn't be in the call log.
+
+ // Voicemail and missed calls are both considered missed.
+ if (lastCallType == Calls.VOICEMAIL_TYPE ||
+ lastCallType == Calls.MISSED_TYPE) {
+ stringID = R.string.description_unknown_missed_call;
+ } else if (lastCallType == Calls.INCOMING_TYPE) {
+ stringID = R.string.description_unknown_answered_call;
+ }
+ } else {
+ // Known caller, so callable.
+
+ // Missed call (ie voicemail or missed)
+ if (lastCallType == Calls.VOICEMAIL_TYPE ||
+ lastCallType == Calls.MISSED_TYPE) {
+ stringID = R.string.description_return_missed_call;
+ } else if (lastCallType == Calls.INCOMING_TYPE) {
+ // Incoming answered.
+ stringID = R.string.description_return_answered_call;
+ } else {
+ // Outgoing call.
+
+ // If we have a history of multiple calls
+ if (details.callTypes.length > 1) {
+ stringID = R.string.description_call_last_multiple;
+ } else {
+ stringID = R.string.description_call_last;
+ }
+ }
+ }
+ 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.name)) {
recipient = details.name;
@@ -93,15 +258,15 @@ import com.android.dialer.R;
recipient = mPhoneNumberHelper.getDisplayNumber(
details.number, details.numberPresentation, details.formattedNumber);
}
- return mResources.getString(R.string.description_call, recipient);
+ return recipient;
}
/** Sets the secondary action to correspond to the play button. */
private void configurePlaySecondaryAction(CallLogListItemViews views, boolean isHighlighted) {
views.secondaryActionView.setVisibility(View.VISIBLE);
- views.secondaryActionView.setImageResource(
+ views.secondaryActionButtonView.setImageResource(
isHighlighted ? R.drawable.ic_play_active_holo_dark : R.drawable.ic_play_holo_light);
- views.secondaryActionView.setContentDescription(
+ views.secondaryActionButtonView.setContentDescription(
mResources.getString(R.string.description_call_log_play_button));
}
}
diff --git a/src/com/android/dialer/calllog/CallLogListItemViews.java b/src/com/android/dialer/calllog/CallLogListItemViews.java
index ed6218f86..a3789569e 100644
--- a/src/com/android/dialer/calllog/CallLogListItemViews.java
+++ b/src/com/android/dialer/calllog/CallLogListItemViews.java
@@ -34,19 +34,25 @@ public final class CallLogListItemViews {
public final QuickContactBadge quickContactView;
/** The primary action view of the entry. */
public final View primaryActionView;
+ /** The secondary action view, which includes both the vertical divider line and
+ * the action button itself. Used so that the button and divider line can be
+ * made visible/hidden as a whole. */
+ public final View secondaryActionView;
/** The secondary action button on the entry. */
- public final ImageView secondaryActionView;
+ public final ImageView secondaryActionButtonView;
/** The details of the phone call. */
public final PhoneCallDetailsViews phoneCallDetailsViews;
/** The text of the header of a section. */
public final TextView listHeaderTextView;
private CallLogListItemViews(QuickContactBadge quickContactView, View primaryActionView,
- ImageView secondaryActionView, PhoneCallDetailsViews phoneCallDetailsViews,
+ View secondaryActionView, ImageView secondaryActionButtonView,
+ PhoneCallDetailsViews phoneCallDetailsViews,
TextView listHeaderTextView) {
this.quickContactView = quickContactView;
this.primaryActionView = primaryActionView;
this.secondaryActionView = secondaryActionView;
+ this.secondaryActionButtonView = secondaryActionButtonView;
this.phoneCallDetailsViews = phoneCallDetailsViews;
this.listHeaderTextView = listHeaderTextView;
}
@@ -55,6 +61,7 @@ public final class CallLogListItemViews {
return new CallLogListItemViews(
(QuickContactBadge) view.findViewById(R.id.quick_contact_photo),
view.findViewById(R.id.primary_action_view),
+ view.findViewById(R.id.secondary_action_view),
(ImageView) view.findViewById(R.id.secondary_action_icon),
PhoneCallDetailsViews.fromView(view),
(TextView) view.findViewById(R.id.call_log_header));
@@ -65,6 +72,7 @@ public final class CallLogListItemViews {
return new CallLogListItemViews(
new QuickContactBadge(context),
new View(context),
+ new View(context),
new ImageView(context),
PhoneCallDetailsViews.createForTest(context),
new TextView(context));
diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java
index efc659fb6..027674a96 100644
--- a/src/com/android/dialer/list/PhoneFavoriteFragment.java
+++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java
@@ -251,7 +251,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
this, 1);
final String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
mCallLogAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this,
- new ContactInfoHelper(getActivity(), currentCountryIso), true, false);
+ new ContactInfoHelper(getActivity(), currentCountryIso), false, false);
setHasOptionsMenu(true);
}
diff --git a/src/com/android/dialerbind/ObjectFactory.java b/src/com/android/dialerbind/ObjectFactory.java
index c43dffcea..be91e3310 100644
--- a/src/com/android/dialerbind/ObjectFactory.java
+++ b/src/com/android/dialerbind/ObjectFactory.java
@@ -34,10 +34,20 @@ public class ObjectFactory {
return null;
}
+ /**
+ * Create a new instance of the call log adapter.
+ * @param context The context to use.
+ * @param callFetcher Instance of call fetcher to use.
+ * @param contactInfoHelper Instance of contact info helper class to use.
+ * @param hideSecondaryAction If true, secondary action will be hidden (ie call details
+ * or play voicemail).
+ * @param isCallLog Is this call log adapter being used on the call log?
+ * @return Instance of CallLogAdapter.
+ */
public static CallLogAdapter newCallLogAdapter(Context context, CallFetcher callFetcher,
- ContactInfoHelper contactInfoHelper, boolean useCallAsPrimaryAction,
+ ContactInfoHelper contactInfoHelper, boolean hideSecondaryAction,
boolean isCallLog) {
- return new CallLogAdapter(context, callFetcher, contactInfoHelper, useCallAsPrimaryAction,
+ return new CallLogAdapter(context, callFetcher, contactInfoHelper, hideSecondaryAction,
isCallLog);
}
}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 3a714e39a..94aa3aada 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -25,6 +25,7 @@
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
diff --git a/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java b/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java
index 4ccdaaf33..49d32e5cb 100644
--- a/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogFragmentTest.java
@@ -117,7 +117,7 @@ public class CallLogFragmentTest extends ActivityInstrumentationTestCase2<Fragme
FragmentManager fragmentManager = mActivity.getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(FragmentTestActivity.LAYOUT_ID, mFragment);
- transaction.commit();
+ transaction.commitAllowingStateLoss();
// Wait for the fragment to be loaded.
getInstrumentation().waitForIdleSync();
@@ -320,7 +320,12 @@ public class CallLogFragmentTest extends ActivityInstrumentationTestCase2<Fragme
mAdapter.bindStandAloneView(view, getActivity(), mCursor);
CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag();
+
+ // The primaryActionView tag is set in the
+ // {@link com.android.dialer.calllog.CallLogAdapter#bindView} method. If it is possible
+ // to place a call to the phone number, a call intent will have been created for the
+ // primaryActionView.
+ IntentProvider intentProvider = (IntentProvider) views.primaryActionView.getTag();
Intent intent = intentProvider.getIntent(mActivity);
// Starts a call.
assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction());
@@ -336,7 +341,7 @@ public class CallLogFragmentTest extends ActivityInstrumentationTestCase2<Fragme
mAdapter.bindStandAloneView(view, getActivity(), mCursor);
CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag();
+ IntentProvider intentProvider = (IntentProvider) views.secondaryActionButtonView.getTag();
Intent intent = intentProvider.getIntent(mActivity);
// Starts the call detail activity.
assertEquals(new ComponentName(mActivity, CallDetailActivity.class),
@@ -362,8 +367,9 @@ public class CallLogFragmentTest extends ActivityInstrumentationTestCase2<Fragme
// HELPERS to check conditions on the DB/views
//
/**
- * Go over all the views in the list and check that the Call
- * icon's visibility matches the nature of the number.
+ * Go over the views in the list and check to ensure that
+ * callable numbers have an associated call intent, where numbers
+ * which are not callable have a null intent.
*/
private void checkCallStatus() {
for (int i = 0; i < mList.length; i++) {
@@ -374,9 +380,17 @@ public class CallLogFragmentTest extends ActivityInstrumentationTestCase2<Fragme
int presentation = getPhoneNumberPresentationForListEntry(i);
if (presentation == Calls.PRESENTATION_RESTRICTED ||
presentation == Calls.PRESENTATION_UNKNOWN) {
- assertFalse(View.VISIBLE == mItem.secondaryActionView.getVisibility());
+ //If number is not callable, the primary action view should have a null tag.
+ assertNull(mItem.primaryActionView.getTag());
} else {
- assertEquals(View.VISIBLE, mItem.secondaryActionView.getVisibility());
+ //If the number is callable, the primary action view should have a non-null tag.
+ assertNotNull(mItem.primaryActionView.getTag());
+
+ IntentProvider intentProvider = (IntentProvider)mItem.primaryActionView.getTag();
+ Intent callIntent = intentProvider.getIntent(mActivity);
+
+ //The intent should be to make the call
+ assertEquals(Intent.ACTION_CALL_PRIVILEGED, callIntent.getAction());
}
}
}
diff --git a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
index a10dec908..7e4736e35 100644
--- a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
@@ -24,6 +24,7 @@ import android.view.View;
import com.android.dialer.PhoneCallDetails;
import com.android.dialer.PhoneCallDetailsHelper;
+import com.android.dialer.R;
/**
* Unit tests for {@link CallLogListItemHelper}.
@@ -52,19 +53,21 @@ public class CallLogListItemHelperTest extends AndroidTestCase {
private PhoneNumberDisplayHelper mPhoneNumberHelper;
private PhoneNumberDisplayHelper mPhoneNumberDisplayHelper;
+ private Resources mResources;
+
@Override
protected void setUp() throws Exception {
super.setUp();
Context context = getContext();
- Resources resources = context.getResources();
- CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
+ mResources = context.getResources();
+ CallTypeHelper callTypeHelper = new CallTypeHelper(mResources);
final TestPhoneNumberUtilsWrapper phoneUtils = new TestPhoneNumberUtilsWrapper(
TEST_VOICEMAIL_NUMBER);
PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
- resources, callTypeHelper, phoneUtils);
- mPhoneNumberDisplayHelper = new PhoneNumberDisplayHelper(resources);
+ mResources, callTypeHelper, phoneUtils);
+ mPhoneNumberDisplayHelper = new PhoneNumberDisplayHelper(mResources);
mHelper = new CallLogListItemHelper(phoneCallDetailsHelper, mPhoneNumberDisplayHelper,
- resources);
+ mResources);
mViews = CallLogListItemViews.createForTest(context);
}
@@ -78,92 +81,286 @@ public class CallLogListItemHelperTest extends AndroidTestCase {
public void testSetPhoneCallDetails() {
setPhoneCallDetailsWithNumber("12125551234", Calls.PRESENTATION_ALLOWED,
"1-212-555-1234");
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
}
public void testSetPhoneCallDetailsInFavorites() {
setPhoneCallDetailsWithNumberInFavorites("12125551234", Calls.PRESENTATION_ALLOWED,
"1-212-555-1234");
- assertNoCallButton();
+ assertNoCallIntent();
}
public void testSetPhoneCallDetails_Unknown() {
setPhoneCallDetailsWithNumber("", Calls.PRESENTATION_UNKNOWN, "");
- assertNoCallButton();
+ assertNoCallIntent();
}
public void testSetPhoneCallDetailsInFavorites_Unknown() {
setPhoneCallDetailsWithNumberInFavorites("", Calls.PRESENTATION_UNKNOWN, "");
- assertNoCallButton();
+ assertNoCallIntent();
}
public void testSetPhoneCallDetails_Private() {
setPhoneCallDetailsWithNumber("", Calls.PRESENTATION_RESTRICTED, "");
- assertNoCallButton();
+ assertNoCallIntent();
}
public void testSetPhoneCallDetailsInFavorites_Private() {
setPhoneCallDetailsWithNumberInFavorites("", Calls.PRESENTATION_RESTRICTED, "");
- assertNoCallButton();
+ assertNoCallIntent();
}
public void testSetPhoneCallDetails_Payphone() {
setPhoneCallDetailsWithNumber("", Calls.PRESENTATION_PAYPHONE, "");
- assertNoCallButton();
+ assertNoCallIntent();
}
public void testSetPhoneCallDetailsInFavorites_Payphone() {
setPhoneCallDetailsWithNumberInFavorites("", Calls.PRESENTATION_PAYPHONE, "");
- assertNoCallButton();
+ assertNoCallIntent();
}
public void testSetPhoneCallDetails_VoicemailNumber() {
setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER,
Calls.PRESENTATION_ALLOWED, TEST_VOICEMAIL_NUMBER);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
}
public void testSetPhoneCallDetails_ReadVoicemail() {
setPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
}
public void testSetPhoneCallDetails_UnreadVoicemail() {
setUnreadPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
}
public void testSetPhoneCallDetails_VoicemailFromUnknown() {
setPhoneCallDetailsWithNumberAndType("", Calls.PRESENTATION_UNKNOWN,
"", Calls.VOICEMAIL_TYPE);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
}
public void testSetPhoneCallDetailsInFavorites_VoicemailNumber() {
setPhoneCallDetailsWithNumberInFavorites(TEST_VOICEMAIL_NUMBER,
Calls.PRESENTATION_ALLOWED, TEST_VOICEMAIL_NUMBER);
- assertNoCallButton();
+ assertNoCallIntent();
}
public void testSetPhoneCallDetailsInFavorites_ReadVoicemail() {
setPhoneCallDetailsWithTypesInFavorites(Calls.VOICEMAIL_TYPE);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
}
public void testSetPhoneCallDetailsInFavorites_UnreadVoicemail() {
setUnreadPhoneCallDetailsWithTypesInFavorites(Calls.VOICEMAIL_TYPE);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
}
public void testSetPhoneCallDetailsInFavorites_VoicemailFromUnknown() {
setPhoneCallDetailsWithNumberAndTypeInFavorites("", Calls.PRESENTATION_UNKNOWN,
"", Calls.VOICEMAIL_TYPE);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ assertEquals(View.VISIBLE, mViews.secondaryActionButtonView.getVisibility());
+ }
+
+ /**
+ * Test getCallDescriptionID method used to get the accessibility description for calls.
+ * Test case where an answered unknown call is received.
+ */
+ public void testGetCallDescriptionID_UnknownAnswered() {
+ PhoneCallDetails details = new PhoneCallDetails("", Calls.PRESENTATION_UNKNOWN, "",
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION);
+ assertEquals(R.string.description_unknown_answered_call,
+ mHelper.getCallDescriptionStringID(details));
+ }
+
+ /**
+ * Test getCallDescriptionID method used to get the accessibility description for calls.
+ * Test case where an missed unknown call is received.
+ */
+ public void testGetCallDescriptionID_UnknownMissed() {
+ PhoneCallDetails details = new PhoneCallDetails("", Calls.PRESENTATION_UNKNOWN, "",
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.MISSED_TYPE}, TEST_DATE, TEST_DURATION);
+ assertEquals(R.string.description_unknown_missed_call,
+ mHelper.getCallDescriptionStringID(details));
+ }
+
+ /**
+ * Test getCallDescriptionID method used to get the accessibility description for calls.
+ * Test case where an missed unknown call is received and a voicemail was left.
+ */
+ public void testGetCallDescriptionID_UnknownVoicemail() {
+ PhoneCallDetails details = new PhoneCallDetails("", Calls.PRESENTATION_UNKNOWN, "",
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION);
+ assertEquals(R.string.description_unknown_missed_call,
+ mHelper.getCallDescriptionStringID(details));
+ }
+
+ /**
+ * Test getCallDescriptionID method used to get the accessibility description for calls.
+ * Test case where an answered call from a known caller is received.
+ */
+ public void testGetCallDescriptionID_KnownAnswered() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION);
+ assertEquals(R.string.description_return_answered_call,
+ mHelper.getCallDescriptionStringID(details));
+ }
+
+ /**
+ * Test getCallDescriptionID method used to get the accessibility description for calls.
+ * Test case where a missed call from a known caller is received.
+ */
+ public void testGetCallDescriptionID_KnownMissed() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.MISSED_TYPE}, TEST_DATE, TEST_DURATION);
+ assertEquals(R.string.description_return_missed_call,
+ mHelper.getCallDescriptionStringID(details));
+ }
+
+ /**
+ * Test getCallDescriptionID method used to get the accessibility description for calls.
+ * Test case where a missed call from a known caller is received and a voicemail was left.
+ */
+ public void testGetCallDescriptionID_KnownVoicemail() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION);
+ assertEquals(R.string.description_return_missed_call,
+ mHelper.getCallDescriptionStringID(details));
+ }
+
+ /**
+ * Test getCallDescriptionID method used to get the accessibility description for calls.
+ * Test case where an outgoing call is made to a known number and there is a history of
+ * only a single call for this caller.
+ */
+ public void testGetCallDescriptionID_OutgoingSingle() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
+ assertEquals(R.string.description_call_last,
+ mHelper.getCallDescriptionStringID(details));
+ }
+
+ /**
+ * Test getCallDescriptionID method used to get the accessibility description for calls.
+ * Test case where an outgoing call is made to a known number and there is a history of
+ * many calls for this caller.
+ */
+ public void testGetCallDescriptionID_OutgoingMultiple() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
+ assertEquals(R.string.description_call_last_multiple,
+ mHelper.getCallDescriptionStringID(details));
+ }
+
+ /**
+ * Test getCallDescription method used to get the accessibility description for calls.
+ * For outgoing calls, we should NOT have "New Voicemail" in the description.
+ */
+ public void testGetCallDescription_NoVoicemailOutgoing() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
+ CharSequence description = mHelper.getCallDescription(details);
+ assertFalse(description.toString()
+ .contains(this.mResources.getString(R.string.description_new_voicemail)));
+ }
+
+ /**
+ * Test getCallDescription method used to get the accessibility description for calls.
+ * For regular incoming calls, we should NOT have "New Voicemail" in the description.
+ */
+ public void testGetCallDescription_NoVoicemailIncoming() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
+ CharSequence description = mHelper.getCallDescription(details);
+ assertFalse(description.toString()
+ .contains(this.mResources.getString(R.string.description_new_voicemail)));
+ }
+
+ /**
+ * Test getCallDescription method used to get the accessibility description for calls.
+ * For regular missed calls, we should NOT have "New Voicemail" in the description.
+ */
+ public void testGetCallDescription_NoVoicemailMissed() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.MISSED_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
+ CharSequence description = mHelper.getCallDescription(details);
+ assertFalse(description.toString()
+ .contains(this.mResources.getString(R.string.description_new_voicemail)));
+ }
+
+ /**
+ * Test getCallDescription method used to get the accessibility description for calls.
+ * For voicemail calls, we should have "New Voicemail" in the description.
+ */
+ public void testGetCallDescription_Voicemail() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE}, TEST_DATE, TEST_DURATION);
+ CharSequence description = mHelper.getCallDescription(details);
+ assertTrue(description.toString()
+ .contains(this.mResources.getString(R.string.description_new_voicemail)));
+ }
+
+ /**
+ * Test getCallDescription method used to get the accessibility description for calls.
+ * Test that the "X calls" message is not present if there is only a single call.
+ */
+ public void testGetCallDescription_NumCallsSingle() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.VOICEMAIL_TYPE}, TEST_DATE, TEST_DURATION);
+ CharSequence description = mHelper.getCallDescription(details);
+
+ // Rather than hard coding the "X calls" string message, we'll generate it with an empty
+ // number of calls, and trim the resulting string. This gets us just the word "calls",
+ // and ensures any trivial changes to that string resource won't unnecessarily break
+ // the unit test.
+ assertFalse(description.toString()
+ .contains(this.mResources.getString(R.string.description_num_calls, "").trim()));
+ }
+
+ /**
+ * Test getCallDescription method used to get the accessibility description for calls.
+ * Test that the "X calls" message is present if there are many calls.
+ */
+ public void testGetCallDescription_NumCallsMultiple() {
+ PhoneCallDetails details = new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE}, TEST_DATE, TEST_DURATION);
+ CharSequence description = mHelper.getCallDescription(details);
+ assertTrue(description.toString()
+ .contains(this.mResources.getString(R.string.description_num_calls, 2)));
}
- /** Asserts that the whole call area is gone. */
- private void assertNoCallButton() {
- assertEquals(View.GONE, mViews.secondaryActionView.getVisibility());
+ /** Asserts that the primary action view does not have a call intent. */
+ private void assertNoCallIntent() {
+ Object intentProvider = (IntentProvider)mViews.primaryActionView.getTag();
+ // The intent provider should be null as there is no ability to make a call.
+ assertNull(intentProvider);
}
/** Sets the details of a phone call using the specified phone number. */