play ringback sound on android 6/7

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/services/AppRTCAudioManager.java | 28 
src/main/java/eu/siacs/conversations/services/CallIntegration.java    | 10 
2 files changed, 36 insertions(+), 2 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/services/AppRTCAudioManager.java 🔗

@@ -16,6 +16,7 @@ import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.media.AudioDeviceInfo;
 import android.media.AudioManager;
+import android.media.ToneGenerator;
 import android.util.Log;
 
 import androidx.annotation.Nullable;
@@ -25,11 +26,14 @@ import com.google.common.collect.ImmutableSet;
 
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.utils.AppRTCUtils;
+import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
 
 import org.webrtc.ThreadUtils;
 
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
 
 /** AppRTCAudioManager manages all audio related parts of the AppRTC demo. */
 public class AppRTCAudioManager {
@@ -66,6 +70,7 @@ public class AppRTCAudioManager {
     private final BroadcastReceiver wiredHeadsetReceiver;
     // Callback method for changes in audio focus.
     @Nullable private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener;
+    private ScheduledFuture<?> ringBackFuture;
 
     public AppRTCAudioManager(final Context context) {
         apprtcContext = context;
@@ -454,6 +459,29 @@ public class AppRTCAudioManager {
         ContextCompat.getMainExecutor(apprtcContext).execute(runnable);
     }
 
+    public void startRingBack() {
+        this.ringBackFuture =
+                JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate(
+                        () -> {
+                            final var toneGenerator =
+                                    new ToneGenerator(
+                                            AudioManager.STREAM_MUSIC,
+                                            CallIntegration.DEFAULT_VOLUME);
+                            toneGenerator.startTone(ToneGenerator.TONE_CDMA_DIAL_TONE_LITE, 750);
+                        },
+                        0,
+                        3,
+                        TimeUnit.SECONDS);
+    }
+
+    public void stopRingBack() {
+        final var future = this.ringBackFuture;
+        if (future == null || future.isDone()) {
+            return;
+        }
+        future.cancel(true);
+    }
+
     /** AudioManager state. */
     public enum AudioManagerState {
         UNINITIALIZED,

src/main/java/eu/siacs/conversations/services/CallIntegration.java 🔗

@@ -34,7 +34,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 public class CallIntegration extends Connection {
 
-    private static final int DEFAULT_VOLUME = 80;
+    public static final int DEFAULT_VOLUME = 80;
 
     private final Context context;
 
@@ -309,7 +309,13 @@ public class CallIntegration extends Connection {
     @Override
     public void onStateChanged(final int state) {
         Log.d(Config.LOGTAG, "onStateChanged(" + state + ")");
-        // TODO devices before selfManaged() will likely have to play their own ringback sound
+        if (notSelfManaged()) {
+            if (state == STATE_DIALING) {
+                requireAppRtcAudioManager().startRingBack();
+            } else {
+                requireAppRtcAudioManager().stopRingBack();
+            }
+        }
         if (state == STATE_ACTIVE) {
             playConnectedSound();
         } else if (state == STATE_DISCONNECTED) {