summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Lee <anwlee@google.com>2015-08-24 17:56:17 -0700
committerAndrew Lee <anwlee@google.com>2015-09-01 16:17:07 -0700
commit0599e880630892becf1a1991e6712e0e6d9df3c8 (patch)
tree41e8ff01c32f22fc1ca48efd7251e264fc2851e1
parent7de107bff21b046c50a42bebf57eb244772412e9 (diff)
Rewrite grouping logic in Dialer.
- Remove expand/collapse and item type logic in GroupingListAdapter. Losing some potential functionality, but it does not adversely affect how we currently group, and makes grouping easier to understanding. + Rewrite GroupingListAdapter to provide O(1) lookup for group size and getItem. This requires maintaining a SparseIntArray of metadata for each list item. Cut metadata storage from long to int, to help adjust for the larger memory overhead. + Simplify the logic for building and maintaing the metadata in the GroupingListAdapter, offloading much of it to the SparseIntArray. + Explictily add all groups, including groups with single items, in the CallLogBroupBuilder. + Tidied up logic in CallLogGroupBuilder to make it more intuitive what cases it's handling and what's happening. + Updated tests to work and pass with new tests. Bug: 23422274 Change-Id: Ia7a00c4b580813cade87fdc054ffdd702f59c12c
-rw-r--r--src/com/android/dialer/calllog/CallLogAdapter.java12
-rw-r--r--src/com/android/dialer/calllog/CallLogGroupBuilder.java136
-rw-r--r--src/com/android/dialer/calllog/GroupingListAdapter.java362
-rw-r--r--src/com/android/dialer/calllog/PromoCardViewHolder.java14
-rw-r--r--tests/src/com/android/dialer/calllog/CallLogAdapterTest.java53
-rw-r--r--tests/src/com/android/dialer/calllog/CallLogGroupBuilderTest.java23
-rw-r--r--tests/src/com/android/dialer/calllog/GroupingListAdapterTests.java188
7 files changed, 197 insertions, 591 deletions
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index aa307b6c6..4593e5e4d 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -131,7 +131,7 @@ public class CallLogAdapter extends GroupingListAdapter
private SharedPreferences mPrefs;
- private boolean mShowVoicemailPromoCard = false;
+ protected boolean mShowVoicemailPromoCard = false;
/** Instance of helper class for managing views. */
private final CallLogListItemHelper mCallLogListItemHelper;
@@ -628,6 +628,11 @@ public class CallLogAdapter extends GroupingListAdapter
? 1 : 0));
}
+ @Override
+ public int getGroupSize(int position) {
+ return super.getGroupSize(position - (mShowVoicemailPromoCard ? 1 : 0));
+ }
+
protected boolean isCallLogActivity() {
return mIsCallLogActivity;
}
@@ -794,11 +799,6 @@ public class CallLogAdapter extends GroupingListAdapter
mContactInfoCache.injectContactInfoForTest(number, countryIso, contactInfo);
}
- @Override
- public void addGroup(int cursorPosition, int size, boolean expanded) {
- super.addGroup(cursorPosition, size, expanded);
- }
-
/**
* Stores the day group associated with a call in the call log.
*
diff --git a/src/com/android/dialer/calllog/CallLogGroupBuilder.java b/src/com/android/dialer/calllog/CallLogGroupBuilder.java
index 0826aeb4a..4cf2d07cd 100644
--- a/src/com/android/dialer/calllog/CallLogGroupBuilder.java
+++ b/src/com/android/dialer/calllog/CallLogGroupBuilder.java
@@ -20,6 +20,7 @@ import android.database.Cursor;
import android.provider.CallLog.Calls;
import android.telephony.PhoneNumberUtils;
import android.text.format.Time;
+import android.text.TextUtils;
import com.android.contacts.common.util.DateUtils;
import com.android.contacts.common.util.PhoneNumberHelper;
@@ -46,9 +47,8 @@ public class CallLogGroupBuilder {
* dialed.
* @param cursorPosition The starting position of the group in the cursor.
* @param size The size of the group.
- * @param expanded Whether the group is expanded; always false for the call log.
*/
- public void addGroup(int cursorPosition, int size, boolean expanded);
+ public void addGroup(int cursorPosition, int size);
/**
* Defines the interface for tracking the day group each call belongs to. Calls in a call
@@ -94,7 +94,7 @@ public class CallLogGroupBuilder {
/**
* Finds all groups of adjacent entries in the call log which should be grouped together and
- * calls {@link GroupCreator#addGroup(int, int, boolean)} on {@link #mGroupCreator} for each of
+ * calls {@link GroupCreator#addGroup(int, int)} on {@link #mGroupCreator} for each of
* them.
* <p>
* For entries that are not grouped with others, we do not need to create a group of size one.
@@ -114,98 +114,70 @@ public class CallLogGroupBuilder {
// Get current system time, used for calculating which day group calls belong to.
long currentTime = System.currentTimeMillis();
-
- int currentGroupSize = 1;
cursor.moveToFirst();
- // The number of the first entry in the group.
- String firstNumber = cursor.getString(CallLogQuery.NUMBER);
- // This is the type of the first call in the group.
- int firstCallType = cursor.getInt(CallLogQuery.CALL_TYPE);
-
- // The account information of the first entry in the group.
- String firstAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
- String firstAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
// Determine the day group for the first call in the cursor.
final long firstDate = cursor.getLong(CallLogQuery.DATE);
final long firstRowId = cursor.getLong(CallLogQuery.ID);
- int currentGroupDayGroup = getDayGroup(firstDate, currentTime);
- mGroupCreator.setDayGroup(firstRowId, currentGroupDayGroup);
+ int groupDayGroup = getDayGroup(firstDate, currentTime);
+ mGroupCreator.setDayGroup(firstRowId, groupDayGroup);
- while (cursor.moveToNext()) {
- // The number of the current row in the cursor.
- final String currentNumber = cursor.getString(CallLogQuery.NUMBER);
- final int callType = cursor.getInt(CallLogQuery.CALL_TYPE);
- final String currentAccountComponentName = cursor.getString(
- CallLogQuery.ACCOUNT_COMPONENT_NAME);
- final String currentAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
-
- final boolean sameNumber = equalNumbers(firstNumber, currentNumber);
- final boolean sameAccountComponentName = Objects.equals(
- firstAccountComponentName,
- currentAccountComponentName);
- final boolean sameAccountId = Objects.equals(
- firstAccountId,
- currentAccountId);
- final boolean sameAccount = sameAccountComponentName && sameAccountId;
-
- final boolean shouldGroup;
- final long currentCallId = cursor.getLong(CallLogQuery.ID);
- final long date = cursor.getLong(CallLogQuery.DATE);
-
- if (!sameNumber || !sameAccount) {
- // Should only group with calls from the same number.
- shouldGroup = false;
- } else if (firstCallType == Calls.VOICEMAIL_TYPE) {
- // never group voicemail.
- shouldGroup = false;
- } else {
- // Incoming, outgoing, and missed calls group together.
- shouldGroup = callType != Calls.VOICEMAIL_TYPE;
- }
+ // Instantiate the group values to those of the first call in the cursor.
+ String groupNumber = cursor.getString(CallLogQuery.NUMBER);
+ int groupCallType = cursor.getInt(CallLogQuery.CALL_TYPE);
+ String groupAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
+ String groupAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
+ int groupSize = 1;
+
+ String number;
+ int callType;
+ String accountComponentName;
+ String accountId;
- if (shouldGroup) {
+ while (cursor.moveToNext()) {
+ // Obtain the values for the current call to group.
+ number = cursor.getString(CallLogQuery.NUMBER);
+ callType = cursor.getInt(CallLogQuery.CALL_TYPE);
+ accountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
+ accountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
+
+ final boolean isSameNumber = equalNumbers(groupNumber, number);
+ final boolean isSameAccount = isSameAccount(
+ groupAccountComponentName, accountComponentName, groupAccountId, accountId);
+
+ // Group with the same number and account which are not voicemail.
+ if (isSameNumber && isSameAccount
+ && (callType != Calls.VOICEMAIL_TYPE)
+ && (groupCallType != Calls.VOICEMAIL_TYPE)) {
// Increment the size of the group to include the current call, but do not create
- // the group until we find a call that does not match.
- currentGroupSize++;
+ // the group until finding a call that does not match.
+ groupSize++;
} else {
- // The call group has changed, so determine the day group for the new call group.
- // This ensures all calls grouped together in the call log are assigned the same
- // day group.
- currentGroupDayGroup = getDayGroup(date, currentTime);
-
- // Create a group for the previous set of calls, excluding the current one, but do
- // not create a group for a single call.
- if (currentGroupSize > 1) {
- addGroup(cursor.getPosition() - currentGroupSize, currentGroupSize);
- }
+ // The call group has changed. Determine the day group for the new call group.
+ final long date = cursor.getLong(CallLogQuery.DATE);
+ groupDayGroup = getDayGroup(date, currentTime);
+
+ // Create a group for the previous group of calls, which does not include the
+ // current call.
+ mGroupCreator.addGroup(cursor.getPosition() - groupSize, groupSize);
+
// Start a new group; it will include at least the current call.
- currentGroupSize = 1;
- // The current entry is now the first in the group.
- firstNumber = currentNumber;
- firstCallType = callType;
- firstAccountComponentName = currentAccountComponentName;
- firstAccountId = currentAccountId;
+ groupSize = 1;
+
+ // Update the group values to those of the current call.
+ groupNumber = number;
+ groupCallType = callType;
+ groupAccountComponentName = accountComponentName;
+ groupAccountId = accountId;
}
// Save the day group associated with the current call.
- mGroupCreator.setDayGroup(currentCallId, currentGroupDayGroup);
- }
- // If the last set of calls at the end of the call log was itself a group, create it now.
- if (currentGroupSize > 1) {
- addGroup(count - currentGroupSize, currentGroupSize);
+ final long currentCallId = cursor.getLong(CallLogQuery.ID);
+ mGroupCreator.setDayGroup(currentCallId, groupDayGroup);
}
- }
- /**
- * Creates a group of items in the cursor.
- * <p>
- * The group is always unexpanded.
- *
- * @see CallLogAdapter#addGroup(int, int, boolean)
- */
- private void addGroup(int cursorPosition, int size) {
- mGroupCreator.addGroup(cursorPosition, size, false);
+ // Create a group for the last set of calls.
+ mGroupCreator.addGroup(count - groupSize, groupSize);
}
@VisibleForTesting
@@ -217,6 +189,10 @@ public class CallLogGroupBuilder {
}
}
+ private boolean isSameAccount(String name1, String name2, String id1, String id2) {
+ return TextUtils.equals(name1, name2) && TextUtils.equals(id1, id2);
+ }
+
@VisibleForTesting
boolean compareSipAddresses(String number1, String number2) {
if (number1 == null || number2 == null) return number1 == number2;
diff --git a/src/com/android/dialer/calllog/GroupingListAdapter.java b/src/com/android/dialer/calllog/GroupingListAdapter.java
index 8d3ab4545..54dd5f679 100644
--- a/src/com/android/dialer/calllog/GroupingListAdapter.java
+++ b/src/com/android/dialer/calllog/GroupingListAdapter.java
@@ -22,78 +22,28 @@ import android.database.Cursor;
import android.database.DataSetObserver;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
-import android.util.Log;
import android.util.SparseIntArray;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-
-import com.android.contacts.common.testing.NeededForTesting;
/**
- * Maintains a list that groups adjacent items sharing the same value of a "group-by" field.
+ * Maintains a list that groups items into groups of consecutive elements which are disjoint,
+ * that is, an item can only belong to one group. This is leveraged for grouping calls in the
+ * call log received from or made to the same phone number.
*
- * The list has three types of elements: stand-alone, group header and group child. Groups are
- * collapsible and collapsed by default. This is used by the call log to group related entries.
+ * There are two integers stored as metadata for every list item in the adapter.
*/
abstract class GroupingListAdapter extends RecyclerView.Adapter {
- private static final int GROUP_METADATA_ARRAY_INITIAL_SIZE = 16;
- private static final int GROUP_METADATA_ARRAY_INCREMENT = 128;
- private static final long GROUP_OFFSET_MASK = 0x00000000FFFFFFFFL;
- private static final long GROUP_SIZE_MASK = 0x7FFFFFFF00000000L;
- private static final long EXPANDED_GROUP_MASK = 0x8000000000000000L;
-
- public static final int ITEM_TYPE_STANDALONE = 0;
- public static final int ITEM_TYPE_GROUP_HEADER = 1;
- public static final int ITEM_TYPE_IN_GROUP = 2;
-
- /**
- * Information about a specific list item: is it a group, if so is it expanded.
- * Otherwise, is it a stand-alone item or a group member.
- */
- protected static class PositionMetadata {
- int itemType;
- boolean isExpanded;
- int cursorPosition;
- int childCount;
- private int groupPosition;
- private int listPosition = -1;
- }
-
private Context mContext;
private Cursor mCursor;
/**
- * Count of list items.
- */
- private int mCount;
-
- private int mRowIdColumnIndex;
-
- /**
- * Count of groups in the list.
- */
- private int mGroupCount;
-
- /**
- * Information about where these groups are located in the list, how large they are
- * and whether they are expanded.
- */
- private long[] mGroupMetadata;
-
- private SparseIntArray mPositionCache = new SparseIntArray();
- private int mLastCachedListPosition;
- private int mLastCachedCursorPosition;
- private int mLastCachedGroup;
-
- /**
- * A reusable temporary instance of PositionMetadata
+ * SparseIntArray, which maps the cursor position of the first element of a group to the size
+ * of the group. The index of a key in this map corresponds to the list position of that group.
*/
- private PositionMetadata mPositionMetadata = new PositionMetadata();
+ private SparseIntArray mGroupMetadata;
+ private int mItemCount;
protected ContentObserver mChangeObserver = new ContentObserver(new Handler()) {
-
@Override
public boolean deliverSelfNotifications() {
return true;
@@ -106,7 +56,6 @@ abstract class GroupingListAdapter extends RecyclerView.Adapter {
};
protected DataSetObserver mDataSetObserver = new DataSetObserver() {
-
@Override
public void onChanged() {
notifyDataSetChanged();
@@ -115,7 +64,7 @@ abstract class GroupingListAdapter extends RecyclerView.Adapter {
public GroupingListAdapter(Context context) {
mContext = context;
- resetCache();
+ reset();
}
/**
@@ -126,18 +75,6 @@ abstract class GroupingListAdapter extends RecyclerView.Adapter {
protected abstract void onContentChanged();
- /**
- * Cache should be reset whenever the cursor changes or groups are expanded or collapsed.
- */
- private void resetCache() {
- mCount = -1;
- mLastCachedListPosition = -1;
- mLastCachedCursorPosition = -1;
- mLastCachedGroup = -1;
- mPositionMetadata.listPosition = -1;
- mPositionCache.clear();
- }
-
public void changeCursor(Cursor cursor) {
if (cursor == mCursor) {
return;
@@ -148,288 +85,73 @@ abstract class GroupingListAdapter extends RecyclerView.Adapter {
mCursor.unregisterDataSetObserver(mDataSetObserver);
mCursor.close();
}
+
+ // Reset whenever the cursor is changed.
+ reset();
mCursor = cursor;
- resetCache();
- findGroups();
if (cursor != null) {
+ addGroups(mCursor);
+
+ // Calculate the item count by subtracting group child counts from the cursor count.
+ mItemCount = mGroupMetadata.size();
+
cursor.registerContentObserver(mChangeObserver);
cursor.registerDataSetObserver(mDataSetObserver);
- mRowIdColumnIndex = cursor.getColumnIndexOrThrow("_id");
notifyDataSetChanged();
}
}
- @NeededForTesting
- public Cursor getCursor() {
- return mCursor;
- }
-
- /**
- * Scans over the entire cursor looking for duplicate phone numbers that need
- * to be collapsed.
- */
- private void findGroups() {
- mGroupCount = 0;
- mGroupMetadata = new long[GROUP_METADATA_ARRAY_INITIAL_SIZE];
-
- if (mCursor == null) {
- return;
- }
-
- addGroups(mCursor);
- }
-
/**
- * Records information about grouping in the list. Should be called by the overridden
- * {@link #addGroups} method.
+ * Records information about grouping in the list.
+ * Should be called by the overridden {@link #addGroups} method.
*/
- protected void addGroup(int cursorPosition, int size, boolean expanded) {
- if (mGroupCount >= mGroupMetadata.length) {
- int newSize = idealLongArraySize(
- mGroupMetadata.length + GROUP_METADATA_ARRAY_INCREMENT);
- long[] array = new long[newSize];
- System.arraycopy(mGroupMetadata, 0, array, 0, mGroupCount);
- mGroupMetadata = array;
- }
-
- long metadata = ((long)size << 32) | cursorPosition;
- if (expanded) {
- metadata |= EXPANDED_GROUP_MASK;
+ public void addGroup(int cursorPosition, int groupSize) {
+ int lastIndex = mGroupMetadata.size() - 1;
+ if (lastIndex < 0 || cursorPosition <= mGroupMetadata.keyAt(lastIndex)) {
+ mGroupMetadata.put(cursorPosition, groupSize);
+ } else {
+ // Optimization to avoid binary search if adding groups in ascending cursor position.
+ mGroupMetadata.append(cursorPosition, groupSize);
}
- mGroupMetadata[mGroupCount++] = metadata;
- }
-
- // Copy/paste from ArrayUtils
- private int idealLongArraySize(int need) {
- return idealByteArraySize(need * 8) / 8;
- }
-
- // Copy/paste from ArrayUtils
- private int idealByteArraySize(int need) {
- for (int i = 4; i < 32; i++)
- if (need <= (1 << i) - 12)
- return (1 << i) - 12;
-
- return need;
}
@Override
public int getItemCount() {
- if (mCursor == null) {
- return 0;
- }
-
- if (mCount != -1) {
- return mCount;
- }
-
- int cursorPosition = 0;
- int count = 0;
- for (int i = 0; i < mGroupCount; i++) {
- long metadata = mGroupMetadata[i];
- int offset = (int)(metadata & GROUP_OFFSET_MASK);
- boolean expanded = (metadata & EXPANDED_GROUP_MASK) != 0;
- int size = (int)((metadata & GROUP_SIZE_MASK) >> 32);
-
- count += (offset - cursorPosition);
-
- if (expanded) {
- count += size + 1;
- } else {
- count++;
- }
-
- cursorPosition = offset + size;
- }
-
- mCount = count + mCursor.getCount() - cursorPosition;
- return mCount;
+ return mItemCount;
}
/**
- * Figures out whether the item at the specified position represents a
- * stand-alone element, a group or a group child. Also computes the
- * corresponding cursor position.
+ * Given the position of a list item, returns the size of the group of items corresponding to
+ * that position.
*/
- public void obtainPositionMetadata(PositionMetadata metadata, int position) {
- // If the description object already contains requested information, just return
- if (metadata.listPosition == position) {
- return;
- }
-
- int listPosition = 0;
- int cursorPosition = 0;
- int firstGroupToCheck = 0;
-
- // Check cache for the supplied position. What we are looking for is
- // the group descriptor immediately preceding the supplied position.
- // Once we have that, we will be able to tell whether the position
- // is the header of the group, a member of the group or a standalone item.
- if (mLastCachedListPosition != -1) {
- if (position <= mLastCachedListPosition) {
-
- // Have SparceIntArray do a binary search for us.
- int index = mPositionCache.indexOfKey(position);
-
- // If we get back a positive number, the position corresponds to
- // a group header.
- if (index < 0) {
-
- // We had a cache miss, but we did obtain valuable information anyway.
- // The negative number will allow us to compute the location of
- // the group header immediately preceding the supplied position.
- index = ~index - 1;
-
- if (index >= mPositionCache.size()) {
- index--;
- }
- }
-
- // A non-negative index gives us the position of the group header
- // corresponding or preceding the position, so we can
- // search for the group information at the supplied position
- // starting with the cached group we just found
- if (index >= 0) {
- listPosition = mPositionCache.keyAt(index);
- firstGroupToCheck = mPositionCache.valueAt(index);
- long descriptor = mGroupMetadata[firstGroupToCheck];
- cursorPosition = (int)(descriptor & GROUP_OFFSET_MASK);
- }
- } else {
-
- // If we haven't examined groups beyond the supplied position,
- // we will start where we left off previously
- firstGroupToCheck = mLastCachedGroup;
- listPosition = mLastCachedListPosition;
- cursorPosition = mLastCachedCursorPosition;
- }
- }
-
- for (int i = firstGroupToCheck; i < mGroupCount; i++) {
- long group = mGroupMetadata[i];
- int offset = (int)(group & GROUP_OFFSET_MASK);
-
- // Move pointers to the beginning of the group
- listPosition += (offset - cursorPosition);
- cursorPosition = offset;
-
- if (i > mLastCachedGroup) {
- mPositionCache.append(listPosition, i);
- mLastCachedListPosition = listPosition;
- mLastCachedCursorPosition = cursorPosition;
- mLastCachedGroup = i;
- }
-
- // Now we have several possibilities:
- // A) The requested position precedes the group
- if (position < listPosition) {
- metadata.itemType = ITEM_TYPE_STANDALONE;
- metadata.cursorPosition = cursorPosition - (listPosition - position);
- metadata.childCount = 1;
- return;
- }
-
- boolean expanded = (group & EXPANDED_GROUP_MASK) != 0;
- int size = (int) ((group & GROUP_SIZE_MASK) >> 32);
-
- // B) The requested position is a group header
- if (position == listPosition) {
- metadata.itemType = ITEM_TYPE_GROUP_HEADER;
- metadata.groupPosition = i;
- metadata.isExpanded = expanded;
- metadata.childCount = size;
- metadata.cursorPosition = offset;
- return;
- }
-
- if (expanded) {
- // C) The requested position is an element in the expanded group
- if (position < listPosition + size + 1) {
- metadata.itemType = ITEM_TYPE_IN_GROUP;
- metadata.cursorPosition = cursorPosition + (position - listPosition) - 1;
- return;
- }
-
- // D) The element is past the expanded group
- listPosition += size + 1;
- } else {
-
- // E) The element is past the collapsed group
- listPosition++;
- }
-
- // Move cursor past the group
- cursorPosition += size;
+ public int getGroupSize(int listPosition) {
+ if (listPosition >= mGroupMetadata.size()) {
+ return 0;
}
- // The required item is past the last group
- metadata.itemType = ITEM_TYPE_STANDALONE;
- metadata.cursorPosition = cursorPosition + (position - listPosition);
- metadata.childCount = 1;
- }
-
- /**
- * Returns true if the specified position in the list corresponds to a
- * group header.
- */
- public boolean isGroupHeader(int position) {
- obtainPositionMetadata(mPositionMetadata, position);
- return mPositionMetadata.itemType == ITEM_TYPE_GROUP_HEADER;
+ return mGroupMetadata.valueAt(listPosition);
}
/**
- * Given a position of a groups header in the list, returns the size of
- * the corresponding group.
+ * Given the position of a list item, returns the the first item in the group of items
+ * corresponding to that position.
*/
- public int getGroupSize(int position) {
- obtainPositionMetadata(mPositionMetadata, position);
- return mPositionMetadata.childCount;
- }
-
- /**
- * Mark group as expanded if it is collapsed and vice versa.
- */
- @NeededForTesting
- public void toggleGroup(int position) {
- obtainPositionMetadata(mPositionMetadata, position);
- if (mPositionMetadata.itemType != ITEM_TYPE_GROUP_HEADER) {
- throw new IllegalArgumentException("Not a group at position " + position);
- }
-
- if (mPositionMetadata.isExpanded) {
- mGroupMetadata[mPositionMetadata.groupPosition] &= ~EXPANDED_GROUP_MASK;
- } else {
- mGroupMetadata[mPositionMetadata.groupPosition] |= EXPANDED_GROUP_MASK;
- }
- resetCache();
- notifyDataSetChanged();
- }
-
- public int getItemViewType(int position) {
- obtainPositionMetadata(mPositionMetadata, position);
- return mPositionMetadata.itemType;
- }
-
- public Object getItem(int position) {
- if (mCursor == null) {
+ public Object getItem(int listPosition) {
+ if (mCursor == null || listPosition >= mGroupMetadata.size()) {
return null;
}
- obtainPositionMetadata(mPositionMetadata, position);
- if (mCursor.moveToPosition(mPositionMetadata.cursorPosition)) {
+ int cursorPosition = mGroupMetadata.keyAt(listPosition);
+ if (mCursor.moveToPosition(cursorPosition)) {
return mCursor;
} else {
return null;
}
}
- public long getItemId(int position) {
- Object item = getItem(position);
- if (item != null) {
- return mCursor.getLong(mRowIdColumnIndex);
- } else {
- return -1;
- }
+ private void reset() {
+ mItemCount = 0;
+ mGroupMetadata = new SparseIntArray();
}
}
diff --git a/src/com/android/dialer/calllog/PromoCardViewHolder.java b/src/com/android/dialer/calllog/PromoCardViewHolder.java
index 4c9602759..656b66938 100644
--- a/src/com/android/dialer/calllog/PromoCardViewHolder.java
+++ b/src/com/android/dialer/calllog/PromoCardViewHolder.java
@@ -15,12 +15,14 @@
*/
package com.android.dialer.calllog;
-import com.android.dialer.R;
-
+import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.View;
+import com.android.contacts.common.testing.NeededForTesting;
+import com.android.dialer.R;
+
/**
* View holder class for a promo card which will appear in the voicemail tab.
*/
@@ -68,4 +70,12 @@ public class PromoCardViewHolder extends RecyclerView.ViewHolder {
public View getOkTextView() {
return mOkTextView;
}
+
+ @NeededForTesting
+ public static PromoCardViewHolder createForTest(Context context) {
+ PromoCardViewHolder viewHolder = new PromoCardViewHolder(new View(context));
+ viewHolder.mSettingsTextView = new View(context);
+ viewHolder.mOkTextView = new View(context);
+ return viewHolder;
+ }
}
diff --git a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
index b4162e166..2bdc1972b 100644
--- a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
@@ -35,7 +35,9 @@ import java.util.List;
*/
@SmallTest
public class CallLogAdapterTest extends AndroidTestCase {
- private static final String TEST_NUMBER = "12345678";
+ private static final String TEST_NUMBER_1 = "12345678";
+ private static final String TEST_NUMBER_2 = "87654321";
+ private static final String TEST_NUMBER_3 = "18273645";
private static final String TEST_NAME = "name";
private static final String TEST_NUMBER_LABEL = "label";
private static final int TEST_NUMBER_TYPE = 1;
@@ -46,7 +48,7 @@ public class CallLogAdapterTest extends AndroidTestCase {
private MatrixCursor mCursor;
private View mView;
- private ViewHolder mViewHolder;
+ private CallLogListItemViewHolder mViewHolder;
@Override
protected void setUp() throws Exception {
@@ -98,7 +100,7 @@ public class CallLogAdapterTest extends AndroidTestCase {
TestContactInfoCache.Request request = mAdapter.getContactInfoCache().requests.get(0);
// It is for the number we need to show.
- assertEquals(TEST_NUMBER, request.number);
+ assertEquals(TEST_NUMBER_1, request.number);
// It has the right country.
assertEquals(TEST_COUNTRY_ISO, request.countryIso);
// Since there is nothing in the cache, it is an immediate request.
@@ -125,7 +127,7 @@ public class CallLogAdapterTest extends AndroidTestCase {
public void testBindView_NoCallLogButMemoryCache_EnqueueRequest() {
mCursor.addRow(createCallLogEntry());
- mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo());
+ mAdapter.injectContactInfoForTest(TEST_NUMBER_1, TEST_COUNTRY_ISO, createContactInfo());
// Bind the views of a single row.
mAdapter.changeCursor(mCursor);
@@ -141,7 +143,7 @@ public class CallLogAdapterTest extends AndroidTestCase {
public void testBindView_BothCallLogAndMemoryCache_NoEnqueueRequest() {
mCursor.addRow(createCallLogEntryWithCachedValues());
- mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo());
+ mAdapter.injectContactInfoForTest(TEST_NUMBER_1, TEST_COUNTRY_ISO, createContactInfo());
// Bind the views of a single row.
mAdapter.changeCursor(mCursor);
@@ -157,7 +159,7 @@ public class CallLogAdapterTest extends AndroidTestCase {
// Contact info contains a different name.
ContactInfo info = createContactInfo();
info.name = "new name";
- mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, info);
+ mAdapter.injectContactInfoForTest(TEST_NUMBER_1, TEST_COUNTRY_ISO, info);
// Bind the views of a single row.
mAdapter.changeCursor(mCursor);
@@ -171,10 +173,37 @@ public class CallLogAdapterTest extends AndroidTestCase {
assertFalse("should not be immediate", request.immediate);
}
+ public void testBindVoicemailPromoCard() {
+ mCursor.addRow(createCallLogEntry(TEST_NUMBER_1));
+ mCursor.addRow(createCallLogEntry(TEST_NUMBER_1));
+ mCursor.addRow(createCallLogEntry(TEST_NUMBER_2));
+ mCursor.addRow(createCallLogEntry(TEST_NUMBER_2));
+ mCursor.addRow(createCallLogEntry(TEST_NUMBER_2));
+ mCursor.addRow(createCallLogEntry(TEST_NUMBER_3));
+
+ // Bind the voicemail promo card.
+ mAdapter.showVoicemailPromoCard(true);
+ mAdapter.changeCursor(mCursor);
+ mAdapter.onBindViewHolder(PromoCardViewHolder.createForTest(getContext()), 0);
+
+ // Check that displaying the promo card does not affect the grouping or list display.
+ mAdapter.onBindViewHolder(mViewHolder, 1);
+ assertEquals(2, mAdapter.getGroupSize(1));
+ assertEquals(TEST_NUMBER_1, mViewHolder.number);
+
+ mAdapter.onBindViewHolder(mViewHolder, 2);
+ assertEquals(3, mAdapter.getGroupSize(2));
+ assertEquals(TEST_NUMBER_2, mViewHolder.number);
+
+ mAdapter.onBindViewHolder(mViewHolder, 3);
+ assertEquals(1, mAdapter.getGroupSize(3));
+ assertEquals(TEST_NUMBER_3, mViewHolder.number);
+ }
+
/** Returns a contact info with default values. */
private ContactInfo createContactInfo() {
ContactInfo info = new ContactInfo();
- info.number = TEST_NUMBER;
+ info.number = TEST_NUMBER_1;
info.name = TEST_NAME;
info.type = TEST_NUMBER_TYPE;
info.label = TEST_NUMBER_LABEL;
@@ -183,8 +212,12 @@ public class CallLogAdapterTest extends AndroidTestCase {
/** Returns a call log entry without cached values. */
private Object[] createCallLogEntry() {
+ return createCallLogEntry(TEST_NUMBER_1);
+ }
+
+ private Object[] createCallLogEntry(String testNumber) {
Object[] values = CallLogQueryTestUtils.createTestValues();
- values[CallLogQuery.NUMBER] = TEST_NUMBER;
+ values[CallLogQuery.NUMBER] = testNumber;
values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO;
return values;
}
@@ -212,6 +245,10 @@ public class CallLogAdapterTest extends AndroidTestCase {
public TestContactInfoCache getContactInfoCache() {
return (TestContactInfoCache) mContactInfoCache;
}
+
+ public void showVoicemailPromoCard(boolean show) {
+ mShowVoicemailPromoCard = true;
+ }
}
private static final class TestContactInfoCache extends ContactInfoCache {
diff --git a/tests/src/com/android/dialer/calllog/CallLogGroupBuilderTest.java b/tests/src/com/android/dialer/calllog/CallLogGroupBuilderTest.java
index 891f0686f..95558bcf6 100644
--- a/tests/src/com/android/dialer/calllog/CallLogGroupBuilderTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogGroupBuilderTest.java
@@ -82,7 +82,7 @@ public class CallLogGroupBuilderTest extends AndroidTestCase {
addCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
mBuilder.addGroups(mCursor);
assertEquals(1, mFakeGroupCreator.groups.size());
- assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0));
+ assertGroupIs(0, 3, mFakeGroupCreator.groups.get(0));
}
public void testAddGroups_MatchingIncomingAndOutgoing() {
@@ -91,13 +91,12 @@ public class CallLogGroupBuilderTest extends AndroidTestCase {
addCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
mBuilder.addGroups(mCursor);
assertEquals(1, mFakeGroupCreator.groups.size());
- assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0));
+ assertGroupIs(0, 3, mFakeGroupCreator.groups.get(0));
}
public void testAddGroups_Voicemail() {
// Does not group with other types of calls, include voicemail themselves.
assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE);
- //assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE);
assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.VOICEMAIL_TYPE);
assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE);
assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE);
@@ -150,8 +149,8 @@ public class CallLogGroupBuilderTest extends AndroidTestCase {
Calls.OUTGOING_TYPE);
mBuilder.addGroups(mCursor);
assertEquals(2, mFakeGroupCreator.groups.size());
- assertGroupIs(1, 4, false, mFakeGroupCreator.groups.get(0));
- assertGroupIs(8, 3, false, mFakeGroupCreator.groups.get(1));
+ assertGroupIs(1, 4, mFakeGroupCreator.groups.get(0));
+ assertGroupIs(8, 3, mFakeGroupCreator.groups.get(1));
}
public void testEqualPhoneNumbers() {
@@ -228,7 +227,7 @@ public class CallLogGroupBuilderTest extends AndroidTestCase {
addMultipleCallLogEntries(TEST_NUMBER1, types);
mBuilder.addGroups(mCursor);
assertEquals(1, mFakeGroupCreator.groups.size());
- assertGroupIs(0, types.length, false, mFakeGroupCreator.groups.get(0));
+ assertGroupIs(0, types.length, mFakeGroupCreator.groups.get(0));
}
@@ -266,10 +265,9 @@ public class CallLogGroupBuilderTest extends AndroidTestCase {
}
/** Asserts that the group matches the given values. */
- private void assertGroupIs(int cursorPosition, int size, boolean expanded, GroupSpec group) {
+ private void assertGroupIs(int cursorPosition, int size, GroupSpec group) {
assertEquals(cursorPosition, group.cursorPosition);
assertEquals(size, group.size);
- assertEquals(expanded, group.expanded);
}
/** Defines an added group. Used by the {@link FakeGroupCreator}. */
@@ -278,13 +276,10 @@ public class CallLogGroupBuilderTest extends AndroidTestCase {
public final int cursorPosition;
/** The number of elements in the group. */
public final int size;
- /** Whether the group should be initially expanded. */
- public final boolean expanded;
- public GroupSpec(int cursorPosition, int size, boolean expanded) {
+ public GroupSpec(int cursorPosition, int size) {
this.cursorPosition = cursorPosition;
this.size = size;
- this.expanded = expanded;
}
}
@@ -294,8 +289,8 @@ public class CallLogGroupBuilderTest extends AndroidTestCase {
public final List<GroupSpec> groups = newArrayList();
@Override
- public void addGroup(int cursorPosition, int size, boolean expanded) {
- groups.add(new GroupSpec(cursorPosition, size, expanded));
+ public void addGroup(int cursorPosition, int size) {
+ groups.add(new GroupSpec(cursorPosition, size));
}
@Override
diff --git a/tests/src/com/android/dialer/calllog/GroupingListAdapterTests.java b/tests/src/com/android/dialer/calllog/GroupingListAdapterTests.java
index 53583e0a7..45bc59812 100644
--- a/tests/src/com/android/dialer/calllog/GroupingListAdapterTests.java
+++ b/tests/src/com/android/dialer/calllog/GroupingListAdapterTests.java
@@ -16,10 +16,6 @@
package com.android.dialer.calllog;
-import static com.android.dialer.calllog.GroupingListAdapter.ITEM_TYPE_GROUP_HEADER;
-import static com.android.dialer.calllog.GroupingListAdapter.ITEM_TYPE_IN_GROUP;
-import static com.android.dialer.calllog.GroupingListAdapter.ITEM_TYPE_STANDALONE;
-
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
@@ -63,17 +59,12 @@ public class GroupingListAdapterTests extends AndroidTestCase {
if (TextUtils.equals(value, currentValue)) {
groupItemCount++;
} else {
- if (groupItemCount > 1) {
- addGroup(i - groupItemCount, groupItemCount, false);
- }
-
+ addGroup(i - groupItemCount, groupItemCount);
groupItemCount = 1;
currentValue = value;
}
}
- if (groupItemCount > 1) {
- addGroup(count - groupItemCount, groupItemCount, false);
- }
+ addGroup(count - groupItemCount, groupItemCount);
}
@Override
@@ -92,7 +83,6 @@ public class GroupingListAdapterTests extends AndroidTestCase {
}
};
-
private void buildCursor(String... numbers) {
mCursor = new MatrixCursor(PROJECTION);
mNextId = 1;
@@ -107,170 +97,51 @@ public class GroupingListAdapterTests extends AndroidTestCase {
mAdapter.changeCursor(mCursor);
assertEquals(3, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 1);
- assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 2);
+ assertMetadata(0, 1, "1");
+ assertMetadata(1, 1, "2");
+ assertMetadata(2, 1, "3");
}
- public void testGroupingWithCollapsedGroupAtTheBeginning() {
+ public void testGroupingWithGroupAtTheBeginning() {
buildCursor("1", "1", "2");
mAdapter.changeCursor(mCursor);
assertEquals(2, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_GROUP_HEADER, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 2);
- }
-
- public void testGroupingWithExpandedGroupAtTheBeginning() {
- buildCursor("1", "1", "2");
- mAdapter.changeCursor(mCursor);
- mAdapter.toggleGroup(0);
-
- assertEquals(4, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_GROUP_HEADER, true, 0);
- assertPositionMetadata(1, ITEM_TYPE_IN_GROUP, false, 0);
- assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
- assertPositionMetadata(3, ITEM_TYPE_STANDALONE, false, 2);
+ assertMetadata(0, 2, "1");
+ assertMetadata(1, 1, "2");
}
- public void testGroupingWithExpandCollapseCycleAtTheBeginning() {
- buildCursor("1", "1", "2");
- mAdapter.changeCursor(mCursor);
- mAdapter.toggleGroup(0);
- mAdapter.toggleGroup(0);
-
- assertEquals(2, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_GROUP_HEADER, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 2);
- }
-
- public void testGroupingWithCollapsedGroupInTheMiddle() {
+ public void testGroupingWithGroupInTheMiddle() {
buildCursor("1", "2", "2", "2", "3");
mAdapter.changeCursor(mCursor);
assertEquals(3, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
- assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 4);
+ assertMetadata(0, 1, "1");
+ assertMetadata(1, 3, "2");
+ assertMetadata(2, 1, "3");
}
- public void testGroupingWithExpandedGroupInTheMiddle() {
- buildCursor("1", "2", "2", "2", "3");
- mAdapter.changeCursor(mCursor);
- mAdapter.toggleGroup(1);
-
- assertEquals(6, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
- assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
- assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
- assertPositionMetadata(4, ITEM_TYPE_IN_GROUP, false, 3);
- assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 4);
- }
-
- public void testGroupingWithCollapsedGroupAtTheEnd() {
+ public void testGroupingWithGroupAtTheEnd() {
buildCursor("1", "2", "3", "3", "3");
mAdapter.changeCursor(mCursor);
assertEquals(3, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 1);
- assertPositionMetadata(2, ITEM_TYPE_GROUP_HEADER, false, 2);
+ assertMetadata(0, 1, "1");
+ assertMetadata(1, 1, "2");
+ assertMetadata(2, 3, "3");
}
- public void testGroupingWithExpandedGroupAtTheEnd() {
- buildCursor("1", "2", "3", "3", "3");
- mAdapter.changeCursor(mCursor);
- mAdapter.toggleGroup(2);
-
- assertEquals(6, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 1);
- assertPositionMetadata(2, ITEM_TYPE_GROUP_HEADER, true, 2);
- assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
- assertPositionMetadata(4, ITEM_TYPE_IN_GROUP, false, 3);
- assertPositionMetadata(5, ITEM_TYPE_IN_GROUP, false, 4);
- }
-
- public void testGroupingWithMultipleCollapsedGroups() {
- buildCursor("1", "2", "2", "3", "4", "4", "5", "5", "6");
- mAdapter.changeCursor(mCursor);
-
- assertEquals(6, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
- assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 3);
- assertPositionMetadata(3, ITEM_TYPE_GROUP_HEADER, false, 4);
- assertPositionMetadata(4, ITEM_TYPE_GROUP_HEADER, false, 6);
- assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 8);
- }
-
- public void testGroupingWithMultipleExpandedGroups() {
- buildCursor("1", "2", "2", "3", "4", "4", "5", "5", "6");
- mAdapter.changeCursor(mCursor);
- mAdapter.toggleGroup(1);
-
- // Note that expanding the group of 2's shifted the group of 5's down from the
- // 4th to the 6th position
- mAdapter.toggleGroup(6);
-
- assertEquals(10, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
- assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
- assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
- assertPositionMetadata(4, ITEM_TYPE_STANDALONE, false, 3);
- assertPositionMetadata(5, ITEM_TYPE_GROUP_HEADER, false, 4);
- assertPositionMetadata(6, ITEM_TYPE_GROUP_HEADER, true, 6);
- assertPositionMetadata(7, ITEM_TYPE_IN_GROUP, false, 6);
- assertPositionMetadata(8, ITEM_TYPE_IN_GROUP, false, 7);
- assertPositionMetadata(9, ITEM_TYPE_STANDALONE, false, 8);
- }
-
- public void testPositionCache() {
+ public void testGroupingWithMultipleGroups() {
buildCursor("1", "2", "2", "3", "4", "4", "5", "5", "6");
mAdapter.changeCursor(mCursor);
- // First pass - building up cache
assertEquals(6, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
- assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 3);
- assertPositionMetadata(3, ITEM_TYPE_GROUP_HEADER, false, 4);
- assertPositionMetadata(4, ITEM_TYPE_GROUP_HEADER, false, 6);
- assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 8);
-
- // Second pass - using cache
- assertEquals(6, mAdapter.getItemCount());
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
- assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 3);
- assertPositionMetadata(3, ITEM_TYPE_GROUP_HEADER, false, 4);
- assertPositionMetadata(4, ITEM_TYPE_GROUP_HEADER, false, 6);
- assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 8);
-
- // Invalidate cache by expanding a group
- mAdapter.toggleGroup(1);
-
- // First pass - building up cache
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
- assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
- assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
- assertPositionMetadata(4, ITEM_TYPE_STANDALONE, false, 3);
- assertPositionMetadata(5, ITEM_TYPE_GROUP_HEADER, false, 4);
- assertPositionMetadata(6, ITEM_TYPE_GROUP_HEADER, false, 6);
- assertPositionMetadata(7, ITEM_TYPE_STANDALONE, false, 8);
-
- // Second pass - using cache
- assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
- assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
- assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
- assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
- assertPositionMetadata(4, ITEM_TYPE_STANDALONE, false, 3);
- assertPositionMetadata(5, ITEM_TYPE_GROUP_HEADER, false, 4);
- assertPositionMetadata(6, ITEM_TYPE_GROUP_HEADER, false, 6);
- assertPositionMetadata(7, ITEM_TYPE_STANDALONE, false, 8);
+ assertMetadata(0, 1, "1");
+ assertMetadata(1, 2, "2");
+ assertMetadata(2, 1, "3");
+ assertMetadata(3, 2, "4");
+ assertMetadata(4, 2, "5");
+ assertMetadata(5, 1, "6");
}
public void testGroupDescriptorArrayGrowth() {
@@ -287,14 +158,9 @@ public class GroupingListAdapterTests extends AndroidTestCase {
assertEquals(250, mAdapter.getItemCount());
}
- private void assertPositionMetadata(int position, int itemType, boolean isExpanded,
- int cursorPosition) {
- GroupingListAdapter.PositionMetadata metadata = new GroupingListAdapter.PositionMetadata();
- mAdapter.obtainPositionMetadata(metadata, position);
- assertEquals(itemType, metadata.itemType);
- if (metadata.itemType == ITEM_TYPE_GROUP_HEADER) {
- assertEquals(isExpanded, metadata.isExpanded);
- }
- assertEquals(cursorPosition, metadata.cursorPosition);
+ private void assertMetadata(int listPosition, int groupSize, String objectValue) {
+ assertEquals(groupSize, mAdapter.getGroupSize(listPosition));
+ MatrixCursor cursor = (MatrixCursor) mAdapter.getItem(listPosition);
+ assertEquals(objectValue, (String) cursor.getString(GROUPING_COLUMN_INDEX));
}
}