mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 18:30:20 +01:00
Voice Note Beta Feedback fixes.
This commit is contained in:
@@ -14,7 +14,6 @@ import android.support.v4.media.session.MediaSessionCompat;
|
||||
import android.support.v4.media.session.PlaybackStateCompat;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
@@ -22,7 +21,6 @@ import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -38,6 +36,7 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
|
||||
|
||||
public static final String EXTRA_MESSAGE_ID = "voice.note.message_id";
|
||||
public static final String EXTRA_PLAYHEAD = "voice.note.playhead";
|
||||
public static final String EXTRA_PLAY_SINGLE = "voice.note.play.single";
|
||||
|
||||
private static final String TAG = Log.tag(VoiceNoteMediaController.class);
|
||||
|
||||
@@ -97,15 +96,25 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
|
||||
return MediaControllerCompat.getMediaController(activity);
|
||||
}
|
||||
|
||||
|
||||
public void startConsecutivePlayback(@NonNull Uri audioSlideUri, long messageId, long position) {
|
||||
startPlayback(audioSlideUri, messageId, position, false);
|
||||
}
|
||||
|
||||
public void startSinglePlayback(@NonNull Uri audioSlideUri, long messageId, long position) {
|
||||
startPlayback(audioSlideUri, messageId, position, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the Media service to begin playback of a given audio slide. If the audio
|
||||
* slide is currently playing, we jump to the desired position and then begin playback.
|
||||
*
|
||||
* @param audioSlideUri The Uri of the desired audio slide
|
||||
* @param messageId The Message id of the given audio slide
|
||||
* @param position The desired position in milliseconds at which to start playback.
|
||||
* @param audioSlideUri The Uri of the desired audio slide
|
||||
* @param messageId The Message id of the given audio slide
|
||||
* @param position The desired position in milliseconds at which to start playback.
|
||||
* @param singlePlayback The player will only play back the specified Uri, and not build a playlist.
|
||||
*/
|
||||
public void startPlayback(@NonNull Uri audioSlideUri, long messageId, long position) {
|
||||
private void startPlayback(@NonNull Uri audioSlideUri, long messageId, long position, boolean singlePlayback) {
|
||||
if (isCurrentTrack(audioSlideUri)) {
|
||||
getMediaController().getTransportControls().seekTo(position);
|
||||
getMediaController().getTransportControls().play();
|
||||
@@ -113,6 +122,7 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putLong(EXTRA_MESSAGE_ID, messageId);
|
||||
extras.putLong(EXTRA_PLAYHEAD, position);
|
||||
extras.putBoolean(EXTRA_PLAY_SINGLE, singlePlayback);
|
||||
|
||||
getMediaController().getTransportControls().playFromUri(audioSlideUri, extras);
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ class VoiceNoteNotificationManager {
|
||||
}
|
||||
|
||||
notificationManager = PlayerNotificationManager.createWithNotificationChannel(context,
|
||||
NotificationChannels.OTHER,
|
||||
R.string.NotificationChannel_other,
|
||||
NotificationChannels.VOICE_NOTES,
|
||||
R.string.NotificationChannel_voice_notes,
|
||||
NOW_PLAYING_NOTIFICATION_ID,
|
||||
new DescriptionAdapter());
|
||||
|
||||
|
||||
@@ -88,8 +88,9 @@ final class VoiceNotePlaybackPreparer implements MediaSessionConnector.PlaybackP
|
||||
|
||||
@Override
|
||||
public void onPrepareFromUri(final Uri uri, Bundle extras) {
|
||||
long messageId = extras.getLong(VoiceNoteMediaController.EXTRA_MESSAGE_ID);
|
||||
long position = extras.getLong(VoiceNoteMediaController.EXTRA_PLAYHEAD, 0);
|
||||
long messageId = extras.getLong(VoiceNoteMediaController.EXTRA_MESSAGE_ID);
|
||||
long position = extras.getLong(VoiceNoteMediaController.EXTRA_PLAYHEAD, 0);
|
||||
boolean singlePlayback = extras.getBoolean(VoiceNoteMediaController.EXTRA_PLAY_SINGLE, false);
|
||||
|
||||
canLoadMore = false;
|
||||
latestUri = uri;
|
||||
@@ -98,7 +99,13 @@ final class VoiceNotePlaybackPreparer implements MediaSessionConnector.PlaybackP
|
||||
dataSource.clear();
|
||||
|
||||
SimpleTask.run(EXECUTOR,
|
||||
() -> loadMediaDescriptions(messageId),
|
||||
() -> {
|
||||
if (singlePlayback) {
|
||||
return loadMediaDescriptionForSinglePlayback(messageId);
|
||||
} else {
|
||||
return loadMediaDescriptionsForConsecutivePlayback(messageId);
|
||||
}
|
||||
},
|
||||
descriptions -> {
|
||||
if (Util.hasItems(descriptions) && Objects.equals(latestUri, uri)) {
|
||||
applyDescriptionsToQueue(descriptions);
|
||||
@@ -116,7 +123,7 @@ final class VoiceNotePlaybackPreparer implements MediaSessionConnector.PlaybackP
|
||||
});
|
||||
|
||||
player.prepare(dataSource);
|
||||
canLoadMore = true;
|
||||
canLoadMore = !singlePlayback;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -203,7 +210,7 @@ final class VoiceNotePlaybackPreparer implements MediaSessionConnector.PlaybackP
|
||||
long messageId = mediaDescriptionCompat.getExtras().getLong(VoiceNoteMediaDescriptionCompatFactory.EXTRA_MESSAGE_ID);
|
||||
|
||||
SimpleTask.run(EXECUTOR,
|
||||
() -> loadMediaDescriptions(messageId),
|
||||
() -> loadMediaDescriptionsForConsecutivePlayback(messageId),
|
||||
descriptions -> {
|
||||
if (Util.hasItems(descriptions) && canLoadMore) {
|
||||
applyDescriptionsToQueue(descriptions);
|
||||
@@ -211,8 +218,24 @@ final class VoiceNotePlaybackPreparer implements MediaSessionConnector.PlaybackP
|
||||
});
|
||||
}
|
||||
|
||||
private @NonNull List<MediaDescriptionCompat> loadMediaDescriptionForSinglePlayback(long messageId) {
|
||||
try {
|
||||
MessageRecord messageRecord = DatabaseFactory.getMmsDatabase(context).getMessageRecord(messageId);
|
||||
|
||||
if (!MessageRecordUtil.hasAudio(messageRecord)) {
|
||||
Log.w(TAG, "Message does not contain audio.");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Collections.singletonList(VoiceNoteMediaDescriptionCompatFactory.buildMediaDescription(context ,messageRecord));
|
||||
} catch (NoSuchMessageException e) {
|
||||
Log.w(TAG, "Could not find message.", e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private @NonNull List<MediaDescriptionCompat> loadMediaDescriptions(long messageId) {
|
||||
private @NonNull List<MediaDescriptionCompat> loadMediaDescriptionsForConsecutivePlayback(long messageId) {
|
||||
try {
|
||||
List<MessageRecord> recordsBefore = DatabaseFactory.getMmsSmsDatabase(context).getMessagesBeforeVoiceNoteExclusive(messageId, LIMIT);
|
||||
List<MessageRecord> recordsAfter = DatabaseFactory.getMmsSmsDatabase(context).getMessagesAfterVoiceNoteInclusive(messageId, LIMIT);
|
||||
|
||||
@@ -28,6 +28,7 @@ import androidx.media.session.MediaButtonReceiver;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.DefaultLoadControl;
|
||||
import com.google.android.exoplayer2.DefaultRenderersFactory;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
import com.google.android.exoplayer2.LoadControl;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
@@ -179,6 +180,11 @@ public class VoiceNotePlaybackService extends MediaBrowserServiceCompat {
|
||||
voiceNotePlaybackPreparer.loadMoreVoiceNotes();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerError(ExoPlaybackException error) {
|
||||
Log.w(TAG, "ExoPlayer error occurred:", error);
|
||||
}
|
||||
}
|
||||
|
||||
private class VoiceNoteNotificationManagerListener implements PlayerNotificationManager.NotificationListener {
|
||||
|
||||
Reference in New Issue
Block a user