From 6b0056f348e1f9ecf0f91b53b51d240961bc8313 Mon Sep 17 00:00:00 2001 From: Sarmad Hashmi Date: Wed, 17 Feb 2016 17:20:36 -0800 Subject: Update call log adapter and related files for archived voicemails. + Populate CallLogAdapter items with different data depending on whether it is in the voicemail archive activity or not + Added addVoicemailGroups method to CallLogGroupBuilder so that every voicemail is put into an individual group + Voicemails grouped differently than regular calls, so added changeCursorVoicemail in GroupingListAdapter +Fix CallLogAdapter tests and add test for archive adapter BUG=22797391 Change-Id: Ib8387c5b3ab8c5e39876cfaf20fde5a44295f152 --- src/com/android/dialer/calllog/CallLogAdapter.java | 61 ++++++++++++++++------ .../android/dialer/calllog/CallLogFragment.java | 12 +++-- .../dialer/calllog/CallLogGroupBuilder.java | 27 ++++++++++ .../dialer/calllog/CallLogListItemViewHolder.java | 32 +++++++++--- .../dialer/calllog/CallLogQueryHandler.java | 16 +++++- .../dialer/calllog/GroupingListAdapter.java | 16 +++++- src/com/android/dialerbind/ObjectFactory.java | 4 +- 7 files changed, 136 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index 6f96ee529..e97f8e235 100644 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -16,7 +16,10 @@ package com.android.dialer.calllog; +import com.android.contacts.common.util.PermissionsUtil; + import com.android.dialer.DialtactsActivity; +import com.android.dialer.database.VoicemailArchiveContract; import com.google.common.annotations.VisibleForTesting; import android.content.Context; @@ -72,6 +75,11 @@ public class CallLogAdapter extends GroupingListAdapter VoicemailPlaybackPresenter.OnVoicemailDeletedListener, ExtendedBlockingButtonRenderer.Listener { + // Types of activities the call log adapter is used for + public static final int ACTIVITY_TYPE_CALL_LOG = 1; + public static final int ACTIVITY_TYPE_ARCHIVE = 2; + public static final int ACTIVITY_TYPE_DIALTACTS = 3; + /** Interface used to initiate a refresh of the content. */ public interface CallFetcher { public void fetchCalls(); @@ -102,7 +110,7 @@ public class CallLogAdapter extends GroupingListAdapter protected ContactInfoCache mContactInfoCache; - private boolean mIsCallLogActivity; + private final int mActivityType; private static final String KEY_EXPANDED_POSITION = "expanded_position"; private static final String KEY_EXPANDED_ROW_ID = "expanded_row_id"; @@ -172,7 +180,7 @@ public class CallLogAdapter extends GroupingListAdapter } else { if (viewHolder.callType == CallLog.Calls.MISSED_TYPE) { CallLogAsyncTaskUtil.markCallAsRead(mContext, viewHolder.callIds); - if (!mIsCallLogActivity) { + if (mActivityType == ACTIVITY_TYPE_DIALTACTS) { ((DialtactsActivity) v.getContext()).updateTabUnreadCounts(); } } @@ -255,7 +263,7 @@ public class CallLogAdapter extends GroupingListAdapter CallFetcher callFetcher, ContactInfoHelper contactInfoHelper, VoicemailPlaybackPresenter voicemailPlaybackPresenter, - boolean isCallLogActivity) { + int activityType) { super(context); mContext = context; @@ -265,7 +273,8 @@ public class CallLogAdapter extends GroupingListAdapter if (mVoicemailPlaybackPresenter != null) { mVoicemailPlaybackPresenter.setOnVoicemailDeletedListener(this); } - mIsCallLogActivity = isCallLogActivity; + + mActivityType = activityType; mContactInfoCache = new ContactInfoCache( mContactInfoHelper, mOnContactInfoChangedListener); @@ -374,6 +383,11 @@ public class CallLogAdapter extends GroupingListAdapter mCallLogGroupBuilder.addGroups(cursor); } + @Override + public void addVoicemailGroups(Cursor cursor) { + mCallLogGroupBuilder.addVoicemailGroups(cursor); + } + @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_VOICEMAIL_PROMO_CARD) { @@ -415,7 +429,7 @@ public class CallLogAdapter extends GroupingListAdapter @Override public void onChangeFilteredNumberUndo() {} - }); + }, mActivityType == ACTIVITY_TYPE_ARCHIVE); viewHolder.callLogEntryView.setTag(viewHolder); viewHolder.callLogEntryView.setAccessibilityDelegate(mAccessibilityDelegate); @@ -479,7 +493,8 @@ public class CallLogAdapter extends GroupingListAdapter final String number = c.getString(CallLogQuery.NUMBER); final String postDialDigits = PhoneNumberDisplayUtil.canShowPostDial() - ? c.getString(CallLogQuery.POST_DIAL_DIGITS) : ""; + && mActivityType != ACTIVITY_TYPE_ARCHIVE ? + c.getString(CallLogQuery.POST_DIAL_DIGITS) : ""; final int numberPresentation = c.getInt(CallLogQuery.NUMBER_PRESENTATION); final PhoneAccountHandle accountHandle = PhoneAccountUtils.getAccount( @@ -506,17 +521,13 @@ public class CallLogAdapter extends GroupingListAdapter mContext, number, numberPresentation, formattedNumber, postDialDigits, isVoicemailNumber); details.accountHandle = accountHandle; - details.callTypes = getCallTypes(c, count); details.countryIso = countryIso; details.date = c.getLong(CallLogQuery.DATE); details.duration = c.getLong(CallLogQuery.DURATION); details.features = getCallFeatures(c, count); details.geocode = c.getString(CallLogQuery.GEOCODED_LOCATION); details.transcription = c.getString(CallLogQuery.TRANSCRIPTION); - if (details.callTypes[0] == CallLog.Calls.VOICEMAIL_TYPE || - details.callTypes[0] == CallLog.Calls.MISSED_TYPE) { - details.isRead = c.getInt(CallLogQuery.IS_READ) == 1; - } + details.callTypes = getCallTypes(c, count); if (!c.isNull(CallLogQuery.DATA_USAGE)) { details.dataUsage = c.getLong(CallLogQuery.DATA_USAGE); @@ -543,9 +554,8 @@ public class CallLogAdapter extends GroupingListAdapter views.postDialDigits = details.postDialDigits; views.displayNumber = details.displayNumber; views.numberPresentation = numberPresentation; - views.callType = c.getInt(CallLogQuery.CALL_TYPE); + views.accountHandle = accountHandle; - views.voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI); // Stash away the Ids of the calls so that we can support deleting a row in the call log. views.callIds = getCallIds(c, count); views.isBusiness = mContactInfoHelper.isBusiness(info.sourceType); @@ -566,6 +576,21 @@ public class CallLogAdapter extends GroupingListAdapter views.dayGroupHeader.setVisibility(View.GONE); } + if (mActivityType == ACTIVITY_TYPE_ARCHIVE) { + views.callType = CallLog.Calls.VOICEMAIL_TYPE; + views.voicemailUri = VoicemailArchiveContract.VoicemailArchive.buildWithId(c.getInt( + c.getColumnIndex(VoicemailArchiveContract.VoicemailArchive._ID))) + .toString(); + + } else { + if (details.callTypes[0] == CallLog.Calls.VOICEMAIL_TYPE || + details.callTypes[0] == CallLog.Calls.MISSED_TYPE) { + details.isRead = c.getInt(CallLogQuery.IS_READ) == 1; + } + views.callType = c.getInt(CallLogQuery.CALL_TYPE); + views.voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI); + } + mCallLogListItemHelper.setPhoneCallDetails(views, details); if (mCurrentlyExpandedRowId == views.rowId) { @@ -613,7 +638,7 @@ public class CallLogAdapter extends GroupingListAdapter public Object getItem(int position) { return super.getItem(position - (mShowVoicemailPromoCard ? 1 : 0) + ((mHiddenPosition != RecyclerView.NO_POSITION && position >= mHiddenPosition) - ? 1 : 0)); + ? 1 : 0)); } @Override @@ -622,7 +647,7 @@ public class CallLogAdapter extends GroupingListAdapter } protected boolean isCallLogActivity() { - return mIsCallLogActivity; + return mActivityType == ACTIVITY_TYPE_CALL_LOG; } /** @@ -740,6 +765,9 @@ public class CallLogAdapter extends GroupingListAdapter * It position in the cursor is unchanged by this function. */ private int[] getCallTypes(Cursor cursor, int count) { + if (mActivityType == ACTIVITY_TYPE_ARCHIVE) { + return new int[] {CallLog.Calls.VOICEMAIL_TYPE}; + } int position = cursor.getPosition(); int[] callTypes = new int[count]; for (int index = 0; index < count; ++index) { @@ -851,7 +879,8 @@ public class CallLogAdapter extends GroupingListAdapter private void maybeShowVoicemailPromoCard() { boolean showPromoCard = mPrefs.getBoolean(SHOW_VOICEMAIL_PROMO_CARD, SHOW_VOICEMAIL_PROMO_CARD_DEFAULT); - mShowVoicemailPromoCard = (mVoicemailPlaybackPresenter != null) && showPromoCard; + mShowVoicemailPromoCard = mActivityType != ACTIVITY_TYPE_ARCHIVE && + (mVoicemailPlaybackPresenter != null) && showPromoCard; } /** diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java index 9cd1359c7..07299a2fb 100644 --- a/src/com/android/dialer/calllog/CallLogFragment.java +++ b/src/com/android/dialer/calllog/CallLogFragment.java @@ -300,13 +300,15 @@ public class CallLogFragment extends Fragment implements CallLogQueryHandler.Lis mEmptyListView.setImage(R.drawable.empty_call_log); mEmptyListView.setActionClickedListener(this); + int activityType = mIsCallLogActivity ? CallLogAdapter.ACTIVITY_TYPE_CALL_LOG : + CallLogAdapter.ACTIVITY_TYPE_DIALTACTS; String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity()); mAdapter = ObjectFactory.newCallLogAdapter( - getActivity(), - this, - new ContactInfoHelper(getActivity(), currentCountryIso), - voicemailPlaybackPresenter, - mIsCallLogActivity); + getActivity(), + this, + new ContactInfoHelper(getActivity(), currentCountryIso), + voicemailPlaybackPresenter, + activityType); mRecyclerView.setAdapter(mAdapter); fetchCalls(); } diff --git a/src/com/android/dialer/calllog/CallLogGroupBuilder.java b/src/com/android/dialer/calllog/CallLogGroupBuilder.java index 194231b90..950f63471 100644 --- a/src/com/android/dialer/calllog/CallLogGroupBuilder.java +++ b/src/com/android/dialer/calllog/CallLogGroupBuilder.java @@ -187,6 +187,33 @@ public class CallLogGroupBuilder { mGroupCreator.addGroup(count - groupSize, groupSize); } + /** + * Group cursor entries by date, with only one entry per group. This is used for listing + * voicemails in the archive tab. + */ + public void addVoicemailGroups(Cursor cursor) { + if (cursor.getCount() == 0) { + return; + } + + // Clear any previous day grouping information. + mGroupCreator.clearDayGroups(); + + // Get current system time, used for calculating which day group calls belong to. + long currentTime = System.currentTimeMillis(); + + // Reset cursor to start before the first row + cursor.moveToPosition(-1); + + // Create an individual group for each voicemail + while (cursor.moveToNext()) { + mGroupCreator.addGroup(cursor.getPosition(), 1); + mGroupCreator.setDayGroup(cursor.getLong(CallLogQuery.ID), + getDayGroup(cursor.getLong(CallLogQuery.DATE), currentTime)); + + } + } + @VisibleForTesting boolean equalNumbers(String number1, String number2) { if (PhoneNumberHelper.isUriNumber(number1) || PhoneNumberHelper.isUriNumber(number2)) { diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java index 6c252758a..392672fec 100644 --- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java +++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java @@ -34,6 +34,7 @@ import android.view.ContextMenu; import android.view.MenuItem; import android.view.View; import android.view.ViewStub; +import android.widget.ImageButton; import android.widget.ImageView; import android.widget.QuickContactBadge; import android.widget.TextView; @@ -200,6 +201,11 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder */ public boolean isBlocked; + /** + * Whether this is the archive tab or not. + */ + public final boolean isArchiveTab; + private final Context mContext; private final CallLogCache mCallLogCache; private final CallLogListItemHelper mCallLogListItemHelper; @@ -230,7 +236,8 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder PhoneCallDetailsViews phoneCallDetailsViews, CardView callLogEntryView, TextView dayGroupHeader, - ImageView primaryActionButtonView) { + ImageView primaryActionButtonView, + boolean isArchiveTab) { super(rootView); mContext = context; @@ -249,6 +256,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder this.dayGroupHeader = dayGroupHeader; this.primaryActionButtonView = primaryActionButtonView; this.workIconView = (ImageView) rootView.findViewById(R.id.work_profile_icon); + this.isArchiveTab = isArchiveTab; Resources resources = mContext.getResources(); mPhotoSize = mContext.getResources().getDimensionPixelSize(R.dimen.contact_photo_size); @@ -276,7 +284,9 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder CallLogListItemHelper callLogListItemHelper, VoicemailPlaybackPresenter voicemailPlaybackPresenter, FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler, - BlockNumberDialogFragment.Callback filteredNumberDialogCallback) { + BlockNumberDialogFragment.Callback filteredNumberDialogCallback, + boolean isArchiveTab) { + return new CallLogListItemViewHolder( context, eventListener, @@ -292,7 +302,8 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder PhoneCallDetailsViews.fromView(view), (CardView) view.findViewById(R.id.call_log_row), (TextView) view.findViewById(R.id.call_log_day_group_label), - (ImageView) view.findViewById(R.id.primary_action_button)); + (ImageView) view.findViewById(R.id.primary_action_button), + isArchiveTab); } @Override @@ -397,6 +408,10 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder voicemailPlaybackView = (VoicemailPlaybackLayout) actionsView .findViewById(R.id.voicemail_playback_layout); + if (isArchiveTab) { + voicemailPlaybackView.hideArchiveButton(); + } + callButtonView = actionsView.findViewById(R.id.call_action); callButtonView.setOnClickListener(this); @@ -509,8 +524,10 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder mVoicemailPlaybackPresenter.setPlaybackView( voicemailPlaybackView, uri, mVoicemailPrimaryActionButtonClicked); mVoicemailPrimaryActionButtonClicked = false; - - CallLogAsyncTaskUtil.markVoicemailAsRead(mContext, uri); + // Only mark voicemail as read when not in archive tab + if (!isArchiveTab) { + CallLogAsyncTaskUtil.markVoicemailAsRead(mContext, uri); + } } else { voicemailPlaybackView.setVisibility(View.GONE); } @@ -705,11 +722,12 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder PhoneCallDetailsViews.createForTest(context), new CardView(context), new TextView(context), - new ImageView(context)); + new ImageView(context), + false); viewHolder.detailsButtonView = new TextView(context); viewHolder.actionsView = new View(context); viewHolder.voicemailPlaybackView = new VoicemailPlaybackLayout(context); - + viewHolder.workIconView = new ImageButton(context); return viewHolder; } } \ No newline at end of file diff --git a/src/com/android/dialer/calllog/CallLogQueryHandler.java b/src/com/android/dialer/calllog/CallLogQueryHandler.java index 3b493cf77..d1591e1f2 100644 --- a/src/com/android/dialer/calllog/CallLogQueryHandler.java +++ b/src/com/android/dialer/calllog/CallLogQueryHandler.java @@ -38,6 +38,7 @@ import android.util.Log; import com.android.contacts.common.compat.SdkVersionOverride; import com.android.contacts.common.database.NoNullCursorAsyncQueryHandler; import com.android.contacts.common.util.PermissionsUtil; +import com.android.dialer.database.VoicemailArchiveContract; import com.android.dialer.util.AppCompatConstants; import com.android.dialer.util.TelecomUtil; import com.android.dialer.voicemail.VoicemailStatusHelperImpl; @@ -64,6 +65,8 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { private static final int QUERY_VOICEMAIL_UNREAD_COUNT_TOKEN = 58; /** The token for the query to fetch the number of missed calls. */ private static final int QUERY_MISSED_CALLS_UNREAD_COUNT_TOKEN = 59; + /** The oken for the query to fetch the archived voicemails. */ + private static final int QUERY_VOICEMAIL_ARCHIVE = 60; private final int mLogLimit; @@ -126,6 +129,17 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { mLogLimit = limit; } + /** + * Fetch all the voicemails in the voicemail archive. + */ + public void fetchVoicemailArchive() { + startQuery(QUERY_VOICEMAIL_ARCHIVE, null, + VoicemailArchiveContract.VoicemailArchive.CONTENT_URI, + null, VoicemailArchiveContract.VoicemailArchive.ARCHIVED + " = 1", null, + VoicemailArchiveContract.VoicemailArchive.DATE + " DESC"); + } + + /** * Fetches the list of calls from the call log for a given type. * This call ignores the new or old state. @@ -253,7 +267,7 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { return; } try { - if (token == QUERY_CALLLOG_TOKEN) { + if (token == QUERY_CALLLOG_TOKEN || token == QUERY_VOICEMAIL_ARCHIVE) { if (updateAdapterData(cursor)) { cursor = null; } diff --git a/src/com/android/dialer/calllog/GroupingListAdapter.java b/src/com/android/dialer/calllog/GroupingListAdapter.java index 70190df30..0d06298e7 100644 --- a/src/com/android/dialer/calllog/GroupingListAdapter.java +++ b/src/com/android/dialer/calllog/GroupingListAdapter.java @@ -73,9 +73,19 @@ abstract class GroupingListAdapter extends RecyclerView.Adapter { */ protected abstract void addGroups(Cursor cursor); + protected abstract void addVoicemailGroups(Cursor cursor); + protected abstract void onContentChanged(); public void changeCursor(Cursor cursor) { + changeCursor(cursor, false); + } + + public void changeCursorVoicemail(Cursor cursor) { + changeCursor(cursor, true); + } + + public void changeCursor(Cursor cursor, boolean voicemail) { if (cursor == mCursor) { return; } @@ -91,7 +101,11 @@ abstract class GroupingListAdapter extends RecyclerView.Adapter { mCursor = cursor; if (cursor != null) { - addGroups(mCursor); + if (voicemail) { + addVoicemailGroups(mCursor); + } else { + addGroups(mCursor); + } // Calculate the item count by subtracting group child counts from the cursor count. mItemCount = mGroupMetadata.size(); diff --git a/src/com/android/dialerbind/ObjectFactory.java b/src/com/android/dialerbind/ObjectFactory.java index 31255a26d..4568c1b35 100644 --- a/src/com/android/dialerbind/ObjectFactory.java +++ b/src/com/android/dialerbind/ObjectFactory.java @@ -62,13 +62,13 @@ public class ObjectFactory { CallFetcher callFetcher, ContactInfoHelper contactInfoHelper, VoicemailPlaybackPresenter voicemailPlaybackPresenter, - boolean isCallLogActivity) { + int activityType) { return new CallLogAdapter( context, callFetcher, contactInfoHelper, voicemailPlaybackPresenter, - isCallLogActivity); + activityType); } public static Logger getLoggerInstance() { -- cgit v1.2.3