Merge "Add option to use Ringtone looping API in Telecom config.xml"
diff --git a/res/values/config.xml b/res/values/config.xml
index 3e02505..b07962d 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -55,4 +55,9 @@
          When false, a fancy vibration pattern which ramps up and down will be used.
          Devices should overlay this value based on the type of vibration hardware they employ. -->
     <bool name="use_simple_vibration_pattern">false</bool>
+
+    <!-- When true, if Telecom is playing the ringtone, it will attempt to pause for some time
+         between repeats of the ringtone.
+         When false, the ringtone will be looping with no pause. -->
+    <bool name="should_pause_between_ringtone_repeats">true</bool>
 </resources>
diff --git a/src/com/android/server/telecom/AsyncRingtonePlayer.java b/src/com/android/server/telecom/AsyncRingtonePlayer.java
index 7ed1c85..fe15525 100644
--- a/src/com/android/server/telecom/AsyncRingtonePlayer.java
+++ b/src/com/android/server/telecom/AsyncRingtonePlayer.java
@@ -47,6 +47,26 @@
     /** The current ringtone. Only used by the ringtone thread. */
     private Ringtone mRingtone;
 
+    /**
+     * Determines if the {@link AsyncRingtonePlayer} should pause between repeats of the ringtone.
+     * When {@code true}, the system will check if the ringtone has stopped every
+     * {@link #RESTART_RINGER_MILLIS} and restart the ringtone if it has stopped.  This does not
+     * guarantee that there is {@link #RESTART_RINGER_MILLIS} between each repeat of the ringtone,
+     * rather it ensures that for short ringtones, or ringtones which are not a multiple of
+     * {@link #RESTART_RINGER_MILLIS} in duration that there will be some pause between repetitions.
+     * When {@code false}, the ringtone will be looped continually with no attempt to pause between
+     * repeats.
+     */
+    private boolean mShouldPauseBetweenRepeat = true;
+
+    public AsyncRingtonePlayer() {
+        // Empty
+    }
+
+    public AsyncRingtonePlayer(boolean shouldPauseBetweenRepeat) {
+        mShouldPauseBetweenRepeat = shouldPauseBetweenRepeat;
+    }
+
     /** Plays the ringtone. */
     public void play(RingtoneFactory factory, Call incomingCall) {
         Log.d(this, "Posting play.");
@@ -144,7 +164,15 @@
             }
         }
 
-        handleRepeat();
+        if (mShouldPauseBetweenRepeat) {
+            // We're trying to pause between repeats, so the ringtone will not intentionally loop.
+            // Instead, we'll use a handler message to perform repeats.
+            handleRepeat();
+        } else {
+            mRingtone.setLooping(true);
+            mRingtone.play();
+            Log.i(this, "Play ringtone, looping.");
+        }
     }
 
     private void handleRepeat() {
diff --git a/src/com/android/server/telecom/components/TelecomService.java b/src/com/android/server/telecom/components/TelecomService.java
index dbae50d..153ddc4 100644
--- a/src/com/android/server/telecom/components/TelecomService.java
+++ b/src/com/android/server/telecom/components/TelecomService.java
@@ -49,6 +49,7 @@
 import com.android.server.telecom.ProximitySensorManagerFactory;
 import com.android.server.telecom.InCallWakeLockController;
 import com.android.server.telecom.ProximitySensorManager;
+import com.android.server.telecom.R;
 import com.android.server.telecom.TelecomSystem;
 import com.android.server.telecom.TelecomWakeLock;
 import com.android.server.telecom.Timeouts;
@@ -85,6 +86,9 @@
             NotificationChannelManager notificationChannelManager =
                     new NotificationChannelManager();
             notificationChannelManager.createChannels(context);
+
+            boolean shouldPauseBetweenRingtoneRepeat = context.getResources().getBoolean(
+                    R.bool.should_pause_between_ringtone_repeats);
             TelecomSystem.setInstance(
                     new TelecomSystem(
                             context,
@@ -166,7 +170,7 @@
                             },
                             ConnectionServiceFocusManager::new,
                             new Timeouts.Adapter(),
-                            new AsyncRingtonePlayer(),
+                            new AsyncRingtonePlayer(shouldPauseBetweenRingtoneRepeat),
                             new PhoneNumberUtilsAdapterImpl(),
                             new IncomingCallNotifier(context),
                             ToneGenerator::new,