Allow (silence rather than reject) the incoming call if it has a
 different source (connection service) from the existing ringing call
 when reaching maximum ringing calls.

b/31911886

Change-Id: If01a31763c16d8835583c70cb9f297c0c189a80e
diff --git a/res/values/config.xml b/res/values/config.xml
index be0f72a..4e86503 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -45,4 +45,9 @@
 
     <!-- Flag indicating whether audio should be routed to speaker when docked -->
     <bool name="use_speaker_when_docked">true</bool>
+
+    <!-- Flag indicating whether allow (silence rather than reject) the incoming call if it has a
+         different source (connection service) from the existing ringing call when reaching
+         maximum ringing calls. -->
+    <bool name="silence_incoming_when_different_service_and_maximum_ringing">false</bool>
 </resources>
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index fefca78..18539c0 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -386,9 +386,13 @@
 
         if (result.shouldAllowCall) {
             if (hasMaximumRingingCalls()) {
-                Log.i(this, "onCallFilteringCompleted: Call rejected! Exceeds maximum number of " +
-                        "ringing calls.");
-                rejectCallAndLog(incomingCall);
+                if (shouldSilenceInsteadOfReject(incomingCall)) {
+                    incomingCall.silence();
+                } else {
+                    Log.i(this, "onCallFilteringCompleted: Call rejected! " +
+                            "Exceeds maximum number of ringing calls.");
+                    rejectCallAndLog(incomingCall);
+                }
             } else if (hasMaximumDialingCalls()) {
                 Log.i(this, "onCallFilteringCompleted: Call rejected! Exceeds maximum number of " +
                         "dialing calls.");
@@ -415,6 +419,37 @@
         }
     }
 
+    /**
+     * Whether allow (silence rather than reject) the incoming call if it has a different source
+     * (connection service) from the existing ringing call when reaching maximum ringing calls.
+     */
+    private boolean shouldSilenceInsteadOfReject(Call incomingCall) {
+        if (!mContext.getResources().getBoolean(
+                R.bool.silence_incoming_when_different_service_and_maximum_ringing)) {
+            return false;
+        }
+
+        Call ringingCall = null;
+
+        for (Call call : mCalls) {
+            // Only operate on top-level calls
+            if (call.getParentCall() != null) {
+                continue;
+            }
+
+            if (call.isExternalCall()) {
+                continue;
+            }
+
+            if (CallState.RINGING == call.getState() &&
+                    call.getConnectionService() == incomingCall.getConnectionService()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
     @Override
     public void onFailedIncomingCall(Call call) {
         setCallState(call, CallState.DISCONNECTED, "failed incoming call");