From 98fc3e5b0b999cda530db8b6447ace306dc23840 Mon Sep 17 00:00:00 2001
From: Alex Hart <alex@signal.org>
Date: Wed, 13 Apr 2022 12:37:24 -0300
Subject: [PATCH] Log warning instead of throwing NPE for voice note
 controller.

---
 .../voice/VoiceNoteMediaController.java       | 55 ++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNoteMediaController.java b/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNoteMediaController.java
index c3fcc70f59..c689171473 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNoteMediaController.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/voice/VoiceNoteMediaController.java
@@ -145,7 +145,7 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
     return playbackStateCompat.getState() <= PlaybackStateCompat.STATE_STOPPED;
   }
 
-  private @NonNull MediaControllerCompat getMediaController() {
+  private @Nullable MediaControllerCompat getMediaController() {
     return MediaControllerCompat.getMediaController(activity);
   }
 
@@ -172,6 +172,11 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
    * @param singlePlayback The player will only play back the specified Uri, and not build a playlist.
    */
   private void startPlayback(@NonNull Uri audioSlideUri, long messageId, long threadId, double progress, boolean singlePlayback) {
+    if (getMediaController() == null) {
+      Log.w(TAG, "Called startPlayback before controller was set. (" + getActivityName() + ")");
+      return;
+    }
+
     if (isCurrentTrack(audioSlideUri)) {
       long duration = getMediaController().getMetadata().getLong(MediaMetadataCompat.METADATA_KEY_DURATION);
 
@@ -196,6 +201,11 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
    * @param messageId      The Message id of the given audio slide
    */
   public void resumePlayback(@NonNull Uri audioSlideUri, long messageId) {
+    if (getMediaController() == null) {
+      Log.w(TAG, "Called resumePlayback before controller was set. (" + getActivityName() + ")");
+      return;
+    }
+
     if (isCurrentTrack(audioSlideUri)) {
       getMediaController().getTransportControls().play();
     } else {
@@ -215,6 +225,11 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
    * @param audioSlideUri The Uri of the audio slide to pause.
    */
   public void pausePlayback(@NonNull Uri audioSlideUri) {
+    if (getMediaController() == null) {
+      Log.w(TAG, "Called pausePlayback(uri) before controller was set. (" + getActivityName() + ")");
+      return;
+    }
+
     if (isCurrentTrack(audioSlideUri)) {
       getMediaController().getTransportControls().pause();
     }
@@ -224,6 +239,11 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
    * Pauses playback regardless of which audio slide is playing.
    */
   public void pausePlayback() {
+    if (getMediaController() == null) {
+      Log.w(TAG, "Called pausePlayback before controller was set. (" + getActivityName() + ")");
+      return;
+    }
+
     getMediaController().getTransportControls().pause();
   }
 
@@ -235,6 +255,11 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
    * @param progress      The progress percentage to seek to.
    */
   public void seekToPosition(@NonNull Uri audioSlideUri, double progress) {
+    if (getMediaController() == null) {
+      Log.w(TAG, "Called seekToPosition before controller was set. (" + getActivityName() + ")");
+      return;
+    }
+
     if (isCurrentTrack(audioSlideUri)) {
       long duration = getMediaController().getMetadata().getLong(MediaMetadataCompat.METADATA_KEY_DURATION);
 
@@ -250,12 +275,22 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
    * @param audioSlideUri The Uri of the audio slide to stop
    */
   public void stopPlaybackAndReset(@NonNull Uri audioSlideUri) {
+    if (getMediaController() == null) {
+      Log.w(TAG, "Called stopPlaybackAndReset before controller was set. (" + getActivityName() + ")");
+      return;
+    }
+
     if (isCurrentTrack(audioSlideUri)) {
       getMediaController().getTransportControls().stop();
     }
   }
 
   public void setPlaybackSpeed(@NonNull Uri audioSlideUri, float playbackSpeed) {
+    if (getMediaController() == null) {
+      Log.w(TAG, "Called setPlaybackSpeed before controller was set. (" + getActivityName() + ")");
+      return;
+    }
+
     if (isCurrentTrack(audioSlideUri)) {
       Bundle bundle = new Bundle();
       bundle.putFloat(VoiceNotePlaybackService.ACTION_NEXT_PLAYBACK_SPEED, playbackSpeed);
@@ -265,12 +300,22 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
   }
 
   private boolean isCurrentTrack(@NonNull Uri uri) {
+    if (getMediaController() == null) {
+      Log.w(TAG, "Called isCurrentTrack before controller was set. (" + getActivityName() + ")");
+      return false;
+    }
+
     MediaMetadataCompat metadataCompat = getMediaController().getMetadata();
 
     return metadataCompat != null && Objects.equals(metadataCompat.getDescription().getMediaUri(), uri);
   }
 
   private void notifyProgressEventHandler() {
+    if (getMediaController() == null) {
+      Log.w(TAG, "Called notifyProgressEventHandler before controller was set. (" + getActivityName() + ")");
+      return;
+    }
+
     if (progressEventHandler == null && activity != null) {
       progressEventHandler = new ProgressEventHandler(getMediaController(), voiceNotePlaybackState);
       progressEventHandler.sendEmptyMessage(0);
@@ -283,6 +328,14 @@ public class VoiceNoteMediaController implements DefaultLifecycleObserver {
     }
   }
 
+  private @NonNull String getActivityName() {
+    if (activity == null) {
+      return "Activity is null";
+    } else {
+      return activity.getLocalClassName();
+    }
+  }
+
   private final class ConnectionCallback extends MediaBrowserCompat.ConnectionCallback {
     @Override
     public void onConnected() {
-- 
GitLab