summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java')
-rw-r--r--java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java258
1 files changed, 236 insertions, 22 deletions
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
index f08e6bfd7..02b05db03 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
@@ -15,17 +15,22 @@
*/
package com.android.dialer.voicemail.listui;
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
import android.app.FragmentManager;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
-import android.support.annotation.VisibleForTesting;
+import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.QuickContactBadge;
import android.widget.TextView;
+import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog;
+import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.contactphoto.ContactPhotoManager;
import com.android.dialer.lettertile.LetterTileDrawable;
@@ -44,6 +49,8 @@ final class NewVoicemailViewHolder extends RecyclerView.ViewHolder implements On
private final Clock clock;
private boolean isViewHolderExpanded;
private int viewHolderId;
+ private VoicemailEntry voicemailEntryOfViewHolder;
+ @NonNull private Uri viewHolderVoicemailUri;
private final NewVoicemailViewHolderListener voicemailViewHolderListener;
NewVoicemailViewHolder(
@@ -58,19 +65,45 @@ final class NewVoicemailViewHolder extends RecyclerView.ViewHolder implements On
mediaPlayerView = view.findViewById(R.id.new_voicemail_media_player);
this.clock = clock;
voicemailViewHolderListener = newVoicemailViewHolderListener;
+
+ viewHolderId = -1;
+ isViewHolderExpanded = false;
+ viewHolderVoicemailUri = null;
}
- void bind(Cursor cursor, FragmentManager fragmentManager) {
- VoicemailEntry voicemailEntry = VoicemailCursorLoader.toVoicemailEntry(cursor);
- viewHolderId = voicemailEntry.id();
- primaryTextView.setText(VoicemailEntryText.buildPrimaryVoicemailText(context, voicemailEntry));
+ /**
+ * When the {@link RecyclerView} displays voicemail entries, it might recycle the views upon
+ * scrolling. In that case we need to ensure that the member variables of this {@link
+ * NewVoicemailViewHolder} and its views are correctly set, especially when this {@link
+ * NewVoicemailViewHolder} is recycled.
+ *
+ * @param cursor the voicemail data from {@link AnnotatedCallLog} generated by the {@link
+ * VoicemailCursorLoader} related
+ * @param fragmentManager FragmentManager retrieved from {@link
+ * NewVoicemailFragment#getActivity()}
+ * @param mediaPlayer
+ * @param position the position of the item within the adapter's data set.
+ * @param currentlyExpandedViewHolderId the value the adapter keeps track of which viewholder if
+ */
+ void bindViewHolderValuesFromAdapter(
+ Cursor cursor,
+ FragmentManager fragmentManager,
+ NewVoicemailMediaPlayer mediaPlayer,
+ int position,
+ int currentlyExpandedViewHolderId) {
+
+ voicemailEntryOfViewHolder = VoicemailCursorLoader.toVoicemailEntry(cursor);
+ viewHolderId = voicemailEntryOfViewHolder.id();
+ viewHolderVoicemailUri = Uri.parse(voicemailEntryOfViewHolder.voicemailUri());
+ primaryTextView.setText(
+ VoicemailEntryText.buildPrimaryVoicemailText(context, voicemailEntryOfViewHolder));
secondaryTextView.setText(
- VoicemailEntryText.buildSecondaryVoicemailText(context, clock, voicemailEntry));
+ VoicemailEntryText.buildSecondaryVoicemailText(context, clock, voicemailEntryOfViewHolder));
- String voicemailTranscription = voicemailEntry.transcription();
+ String voicemailTranscription = voicemailEntryOfViewHolder.transcription();
if (TextUtils.isEmpty(voicemailTranscription)) {
- transcriptionTextView.setVisibility(View.GONE);
+ transcriptionTextView.setVisibility(GONE);
transcriptionTextView.setText(null);
} else {
transcriptionTextView.setVisibility(View.VISIBLE);
@@ -78,9 +111,49 @@ final class NewVoicemailViewHolder extends RecyclerView.ViewHolder implements On
}
itemView.setOnClickListener(this);
- setPhoto(voicemailEntry);
- mediaPlayerView.setVoicemailEntryValues(voicemailEntry);
- mediaPlayerView.setFragmentManager(fragmentManager);
+ setPhoto(voicemailEntryOfViewHolder);
+
+ // Update the expanded/collapsed state of this view holder
+ // Only update the binding of the mediaPlayerView of the expanded view holder
+ if (viewHolderId == currentlyExpandedViewHolderId) {
+ LogUtil.i(
+ "NewVoicemailViewHolder.bindViewHolderValuesFromAdapter",
+ "viewHolderId:%d is expanded, update its mediaplayer view",
+ viewHolderId);
+ expandAndBindViewHolderAndMediaPlayerViewWithAdapterValues(
+ voicemailEntryOfViewHolder, fragmentManager, mediaPlayer, voicemailViewHolderListener);
+ LogUtil.i(
+ "NewVoicemailViewHolder.bindViewHolderValuesFromAdapter",
+ "After 2nd updating the MPPlayerView: viewHolderId:%d, uri:%s, MediaplayerView(after "
+ + "updated):%s, adapter position passed down:%d, getAdapterPos:%d",
+ viewHolderId,
+ String.valueOf(viewHolderVoicemailUri),
+ String.valueOf(mediaPlayerView.getVoicemailUri()),
+ position,
+ getAdapterPosition());
+ Assert.checkArgument(
+ mediaPlayerView.getVisibility() == VISIBLE,
+ "a expanded viewholder should have its media player view visible");
+ } else {
+ LogUtil.i(
+ "NewVoicemailViewHolder.bindViewHolderValuesFromAdapter",
+ "viewHolderId:%d is not the expanded one, collapse it and don't update the MpView",
+ viewHolderId);
+ collapseViewHolder();
+ Assert.checkArgument(
+ mediaPlayerView.getVisibility() == GONE,
+ "a collapsed viewholder should not have its media player view visible");
+ }
+ LogUtil.i(
+ "NewVoicemailViewHolder.bindViewHolderValuesFromAdapter",
+ "Final value after updating: viewHolderId:%d, uri:%s, MediaplayerView(not updated):%s,"
+ + " adapter position passed down:%d, getAdapterPos:%d, MPPlayerVisibility:%b",
+ viewHolderId,
+ String.valueOf(viewHolderVoicemailUri),
+ String.valueOf(mediaPlayerView.getVoicemailUri()),
+ position,
+ getAdapterPosition(),
+ mediaPlayerView.getVisibility() == VISIBLE);
}
// TODO(uabdullah): Consider/Implement TYPE (e.g Spam, TYPE_VOICEMAIL)
@@ -96,19 +169,148 @@ final class NewVoicemailViewHolder extends RecyclerView.ViewHolder implements On
}
void collapseViewHolder() {
+ LogUtil.i(
+ "NewVoicemailViewHolder.collapseViewHolder",
+ "viewHolderId:%d is being collapsed, its MPViewUri:%s, its Uri is :%s",
+ viewHolderId,
+ String.valueOf(mediaPlayerView.getVoicemailUri()),
+ String.valueOf(viewHolderVoicemailUri));
transcriptionTextView.setMaxLines(1);
isViewHolderExpanded = false;
- mediaPlayerView.setVisibility(View.GONE);
+ mediaPlayerView.setVisibility(GONE);
+ }
+
+ // When we are recycling the views ensure that we reset the viewHolder, as if its brand new
+ public void reset() {
+ LogUtil.i(
+ "NewVoicemailViewHolder.reset()",
+ "Reset the viewholder, currently viewHolderId:%d, uri:%s, isViewHolderExpanded:%b, "
+ + "its MediaPlayerViewUri:%s",
+ viewHolderId,
+ String.valueOf(viewHolderVoicemailUri),
+ isViewHolderExpanded,
+ String.valueOf(mediaPlayerView.getVoicemailUri()));
+
+ viewHolderId = -1;
+ isViewHolderExpanded = false;
+ viewHolderVoicemailUri = null;
+
+ mediaPlayerView.reset();
+
+ LogUtil.i(
+ "NewVoicemailViewHolder.reset()",
+ "Reset the viewholder, after resetting viewHolderId:%d, uri:%s, isViewHolderExpanded:%b",
+ viewHolderId,
+ String.valueOf(viewHolderVoicemailUri),
+ isViewHolderExpanded);
}
- void expandViewHolder() {
- LogUtil.i("NewVoicemailViewHolder.expandViewHolder", "voicemail id: %d", viewHolderId);
+ /**
+ * Is only called when a user either clicks a {@link NewVoicemailViewHolder} to expand it or if
+ * the user had already expanded, then scrolled the {@link NewVoicemailViewHolder} out of view and
+ * then scrolled it back into view, and during the binding (as the views are recyled in {@link
+ * RecyclerView}) we restore the expanded state of the {@link NewVoicemailViewHolder}.
+ *
+ * <p>This function also tracks if the state of this viewholder is expanded.
+ *
+ * @param voicemailEntry are the voicemail related values from the {@link AnnotatedCallLog}
+ * @param fragmentManager FragmentManager retrieved from {@link
+ * NewVoicemailFragment#getActivity()}
+ * @param mediaPlayer there should only be one instance of this passed down from the {@link
+ * NewVoicemailAdapter}
+ * @param voicemailViewHolderListener
+ */
+ void expandAndBindViewHolderAndMediaPlayerViewWithAdapterValues(
+ VoicemailEntry voicemailEntry,
+ FragmentManager fragmentManager,
+ NewVoicemailMediaPlayer mediaPlayer,
+ NewVoicemailViewHolderListener voicemailViewHolderListener) {
+
+ Assert.isNotNull(voicemailViewHolderListener);
+ Assert.checkArgument(
+ voicemailEntry.id() == viewHolderId, "ensure that the adapter binding has taken place");
+ Assert.checkArgument(
+ Uri.parse(voicemailEntry.voicemailUri()).equals(viewHolderVoicemailUri),
+ "ensure that the adapter binding has taken place");
+ LogUtil.i(
+ "NewVoicemailViewHolder.expandAndBindViewHolderAndMediaPlayerViewWithAdapterValues",
+ "voicemail id: %d, value of isViewHolderExpanded:%b, before setting it to be true, and"
+ + " value of ViewholderUri:%s, MPView:%s, before updating it",
+ viewHolderId,
+ isViewHolderExpanded,
+ String.valueOf(viewHolderVoicemailUri),
+ String.valueOf(mediaPlayerView.getVoicemailUri()));
+
transcriptionTextView.setMaxLines(999);
isViewHolderExpanded = true;
+ // Once the media player is visible update its state
mediaPlayerView.setVisibility(View.VISIBLE);
+ mediaPlayerView.bindValuesFromAdapterOfExpandedViewHolderMediaPlayerView(
+ this, voicemailEntry, fragmentManager, mediaPlayer, voicemailViewHolderListener);
+ LogUtil.i(
+ "NewVoicemailViewHolder.expandAndBindViewHolderAndMediaPlayerViewWithAdapterValues",
+ "voicemail id: %d, value of isViewHolderExpanded:%b, after setting it to be true, and"
+ + " value of ViewholderUri:%s, MPView:%s, after updating it",
+ viewHolderId,
+ isViewHolderExpanded,
+ String.valueOf(viewHolderVoicemailUri),
+ String.valueOf(mediaPlayerView.getVoicemailUri()));
+ }
+
+ /**
+ * Called when we want to update the voicemail that is currently playing Updates the Seekbar,
+ * duration timer and the play/pause button visibility when the expanded voicemail is being
+ * played.
+ */
+ public void updateMediaPlayerViewWithPlayingState(
+ NewVoicemailViewHolder newVoicemailViewHolder, NewVoicemailMediaPlayer mp) {
+
+ LogUtil.i(
+ "NewVoicemailViewHolder.updateMediaPlayerViewWithPlayingState",
+ "viewholderUri:%s, mediaPlayerViewUri:%s, MPPosition:%d, MpDuration:%d, MpIsPlaying:%b",
+ newVoicemailViewHolder.getViewHolderVoicemailUri().toString(),
+ mediaPlayerView.getVoicemailUri().toString(),
+ mp.getCurrentPosition(),
+ mp.getDuration(),
+ mp.isPlaying());
+
+ Assert.checkArgument(
+ mp.isPlaying(),
+ "this method is only called when we are certain that the media player is playing");
+
+ LogUtil.i(
+ "NewVoicemailViewHolder.updateMediaPlayerViewWithPlayingState",
+ "viewholderUri:%s, mediaPlayerViewUri:%s",
+ newVoicemailViewHolder.getViewHolderVoicemailUri().toString(),
+ mediaPlayerView.getVoicemailUri().toString());
+ Assert.checkArgument(
+ newVoicemailViewHolder
+ .getViewHolderVoicemailUri()
+ .equals(mediaPlayerView.getVoicemailUri()),
+ "the mediaplayer view must be that of the viewholder we are updating");
+ Assert.checkArgument(
+ mp.getLastPlayedOrPlayingVoicemailUri()
+ .equals(mp.getLastPreparedOrPreparingToPlayVoicemailUri()),
+ "the media player view we are attempting to update should be of the "
+ + "currently prepared and playing voicemail");
+
+ mediaPlayerView.updateSeekBarDurationAndShowPlayButton(mp);
+ }
+
+ public void setMediaPlayerViewToResetState(
+ NewVoicemailViewHolder currentlyExpandedViewHolderOnScreen,
+ NewVoicemailMediaPlayer mediaPlayer) {
+ Assert.isNotNull(currentlyExpandedViewHolderOnScreen);
+ mediaPlayerView.setToResetState(currentlyExpandedViewHolderOnScreen, mediaPlayer);
+ }
+
+ public void setPausedStateOfMediaPlayerView(Uri uri, NewVoicemailMediaPlayer mediaPlayer) {
+ Assert.checkArgument(viewHolderVoicemailUri.equals(uri));
+ Assert.checkArgument(mediaPlayerView.getVoicemailUri().equals(uri));
+ Assert.checkArgument(mediaPlayerView.getVoicemailUri().equals(viewHolderVoicemailUri));
+ mediaPlayerView.setToPausedState(uri, mediaPlayer);
}
- @VisibleForTesting(otherwise = VisibleForTesting.NONE)
boolean isViewHolderExpanded() {
return isViewHolderExpanded;
}
@@ -117,25 +319,37 @@ final class NewVoicemailViewHolder extends RecyclerView.ViewHolder implements On
return viewHolderId;
}
+ public Uri getViewHolderVoicemailUri() {
+ return viewHolderVoicemailUri;
+ }
+
interface NewVoicemailViewHolderListener {
- void onViewHolderExpanded(NewVoicemailViewHolder expandedViewHolder);
+ void expandViewHolderFirstTimeAndCollapseAllOtherVisibleViewHolders(
+ NewVoicemailViewHolder expandedViewHolder,
+ VoicemailEntry voicemailEntryOfViewHolder,
+ NewVoicemailViewHolderListener listener);
+
+ void collapseExpandedViewHolder(NewVoicemailViewHolder expandedViewHolder);
- void onViewHolderCollapsed(NewVoicemailViewHolder expandedViewHolder);
+ void pauseViewHolder(NewVoicemailViewHolder expandedViewHolder);
+
+ void resumePausedViewHolder(NewVoicemailViewHolder expandedViewHolder);
}
@Override
public void onClick(View v) {
LogUtil.i(
"NewVoicemailViewHolder.onClick",
- "voicemail id: %d, isViewHolderExpanded:%b",
+ "voicemail id: %d, isViewHolderCurrentlyExpanded:%b",
viewHolderId,
isViewHolderExpanded);
if (isViewHolderExpanded) {
- collapseViewHolder();
- voicemailViewHolderListener.onViewHolderCollapsed(this);
+ voicemailViewHolderListener.collapseExpandedViewHolder(this);
} else {
- expandViewHolder();
- voicemailViewHolderListener.onViewHolderExpanded(this);
+ voicemailViewHolderListener.expandViewHolderFirstTimeAndCollapseAllOtherVisibleViewHolders(
+ this,
+ Assert.isNotNull(voicemailEntryOfViewHolder),
+ Assert.isNotNull(voicemailViewHolderListener));
}
}
}