Add support for sending and syncing viewed receipts behind a feature flag.

This commit is contained in:
Alex Hart
2021-04-28 16:21:34 -03:00
parent cdc7f1565e
commit ab44d608d2
16 changed files with 425 additions and 44 deletions

View File

@@ -99,7 +99,7 @@ public class ConversationItemFooter extends LinearLayout {
presentTimer(messageRecord);
presentInsecureIndicator(messageRecord);
presentDeliveryStatus(messageRecord);
hideAudioDurationViews();
presentAudioDuration(messageRecord);
}
public void setAudioDuration(long totalDurationMillis, long currentPostionMillis) {
@@ -259,6 +259,12 @@ public class ConversationItemFooter extends LinearLayout {
moveAudioViewsForIncoming();
}
showAudioDurationViews();
if (messageRecord.getViewedReceiptCount() > 0) {
revealDot.setProgress(1f);
} else {
revealDot.setProgress(0f);
}
} else {
hideAudioDurationViews();
}
@@ -295,7 +301,7 @@ public class ConversationItemFooter extends LinearLayout {
private void showAudioDurationViews() {
audioSpace.setVisibility(View.VISIBLE);
audioDuration.setVisibility(View.VISIBLE);
audioDuration.setVisibility(View.GONE);
if (FeatureFlags.viewedReceipts()) {
revealDot.setVisibility(View.VISIBLE);

View File

@@ -33,7 +33,17 @@ import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessageDatabase;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobs.MultiDeviceViewedUpdateJob;
import org.thoughtcrime.securesms.jobs.SendViewedReceiptJob;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.video.exo.AttachmentMediaSourceFactory;
import java.util.Collections;
@@ -48,10 +58,10 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
private static final String EMPTY_ROOT_ID = "empty-root-id";
private static final int LOAD_MORE_THRESHOLD = 2;
private static final long SUPPORTED_ACTIONS = PlaybackStateCompat.ACTION_PLAY |
PlaybackStateCompat.ACTION_PAUSE |
PlaybackStateCompat.ACTION_SEEK_TO |
PlaybackStateCompat.ACTION_STOP |
private static final long SUPPORTED_ACTIONS = PlaybackStateCompat.ACTION_PLAY |
PlaybackStateCompat.ACTION_PAUSE |
PlaybackStateCompat.ACTION_SEEK_TO |
PlaybackStateCompat.ACTION_STOP |
PlaybackStateCompat.ACTION_PLAY_PAUSE;
private MediaSessionCompat mediaSession;
@@ -152,6 +162,7 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
becomingNoisyReceiver.unregister();
voiceNoteProximityManager.onPlayerEnded();
} else {
sendViewedReceiptForCurrentWindowIndex();
becomingNoisyReceiver.register();
voiceNoteProximityManager.onPlayerReady();
}
@@ -172,11 +183,12 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
if (reason == Player.DISCONTINUITY_REASON_PERIOD_TRANSITION) {
MediaDescriptionCompat mediaDescriptionCompat = queueDataAdapter.getMediaDescription(currentWindowIndex);
sendViewedReceiptForCurrentWindowIndex();
Log.d(TAG, "onPositionDiscontinuity: current window uri: " + mediaDescriptionCompat.getMediaUri());
}
boolean isWithinThreshold = currentWindowIndex < LOAD_MORE_THRESHOLD ||
currentWindowIndex + LOAD_MORE_THRESHOLD >= queueDataAdapter.size();
boolean isWithinThreshold = currentWindowIndex < LOAD_MORE_THRESHOLD ||
currentWindowIndex + LOAD_MORE_THRESHOLD >= queueDataAdapter.size();
if (isWithinThreshold && currentWindowIndex % 2 == 0) {
voiceNotePlaybackPreparer.loadMoreVoiceNotes();
@@ -190,6 +202,36 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
}
}
private void sendViewedReceiptForCurrentWindowIndex() {
if (player.getPlaybackState() == Player.STATE_READY &&
player.getPlayWhenReady() &&
player.getCurrentWindowIndex() != C.INDEX_UNSET &&
FeatureFlags.sendViewedReceipts()) {
final MediaDescriptionCompat descriptionCompat = queueDataAdapter.getMediaDescription(player.getCurrentWindowIndex());
if (!descriptionCompat.getMediaUri().getScheme().equals("content")) {
return;
}
SignalExecutors.BOUNDED.execute(() -> {
Bundle extras = descriptionCompat.getExtras();
long messageId = extras.getLong(VoiceNoteMediaDescriptionCompatFactory.EXTRA_MESSAGE_ID);
RecipientId recipientId = RecipientId.from(extras.getString(VoiceNoteMediaDescriptionCompatFactory.EXTRA_THREAD_RECIPIENT_ID));
MessageDatabase messageDatabase = DatabaseFactory.getMmsDatabase(this);
MessageDatabase.MarkedMessageInfo markedMessageInfo = messageDatabase.setIncomingMessageViewed(messageId);
if (markedMessageInfo != null) {
ApplicationDependencies.getJobManager().add(new SendViewedReceiptJob(markedMessageInfo.getThreadId(),
recipientId,
markedMessageInfo.getSyncMessageId().getTimetamp()));
MultiDeviceViewedUpdateJob.enqueue(Collections.singletonList(markedMessageInfo.getSyncMessageId()));
}
});
}
}
private class VoiceNoteNotificationManagerListener implements PlayerNotificationManager.NotificationListener {
@Override