Prevent Remote Connection Services from unbinding when conference merges.

When a remote connection service conference call is initiated (such as a Fi conference call), two instances of ConnectionServiceWrapper are created (TelephonyConnectionService (which is the RCS) and the primary connectiong service (such as Fi)). When CSW#addConferenceCall and CSW#addExistingConnection invoked Call#replaceConnectionService for the RCS instance of CSW, it would occasionally decrement the associated call count below 0 and cause the ServiceBinder to unbind, dropping all calls.

This CL ensures invocations of CSW#addConferenceCall and CSW#addExistingConnection by a remote connection service are ignored and thus no errant unbinding can occur.

Fixes: 271631732
Test: manually merge a conference call via Tycho; ensure no calls drop
Change-Id: I3cab8afb4505a0a7826831e16d89a4216940a408
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index cc5932c..a046ceb 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -504,6 +504,8 @@
             Log.startSession(sessionInfo, LogUtils.Sessions.CSW_ADD_CONFERENCE_CALL,
                     mPackageAbbreviation);
 
+            if (ConnectionServiceWrapper.this.mIsRemoteConnectionService) return;
+
             if (parcelableConference.getConnectElapsedTimeMillis() != 0
                     && mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
                             != PackageManager.PERMISSION_GRANTED) {
@@ -911,6 +913,9 @@
         public void addExistingConnection(String callId, ParcelableConnection connection,
                 Session.Info sessionInfo) {
             Log.startSession(sessionInfo, "CSW.aEC", mPackageAbbreviation);
+
+            if (ConnectionServiceWrapper.this.mIsRemoteConnectionService) return;
+
             UserHandle userHandle = Binder.getCallingUserHandle();
             // Check that the Calling Package matches PhoneAccountHandle's Component Package
             PhoneAccountHandle callingPhoneAccountHandle = connection.getPhoneAccount();
@@ -1316,6 +1321,7 @@
     private final CallsManager mCallsManager;
     private final AppOpsManager mAppOpsManager;
     private final Context mContext;
+    public boolean mIsRemoteConnectionService = false;
 
     private ConnectionServiceFocusManager.ConnectionServiceFocusListener mConnSvrFocusListener;
 
@@ -2472,13 +2478,13 @@
     private void logIncoming(String msg, Object... params) {
         // Keep these as debug; the incoming logging is traced on a package level through the
         // session logging.
-        Log.d(this, "CS -> TC[" + Log.getPackageAbbreviation(mComponentName) + "]: "
-                + msg, params);
+        Log.i(this, "CS -> TC[" + Log.getPackageAbbreviation(mComponentName) + "]:"
+                + " isRCS = " + this.mIsRemoteConnectionService + ": " + msg, params);
     }
 
     private void logOutgoing(String msg, Object... params) {
-        Log.d(this, "TC -> CS[" + Log.getPackageAbbreviation(mComponentName) + "]: "
-                + msg, params);
+        Log.i(this, "TC -> CS[" + Log.getPackageAbbreviation(mComponentName) + "]:"
+                + " isRCS = " + this.mIsRemoteConnectionService + ": " + msg, params);
     }
 
     private void queryRemoteConnectionServices(final UserHandle userHandle,
@@ -2505,6 +2511,7 @@
             ConnectionServiceWrapper service = mConnectionServiceRepository.getService(
                     handle.getComponentName(), handle.getUserHandle());
             if (service != null && service != this) {
+                service.mIsRemoteConnectionService = true;
                 simServices.add(service);
             } else {
                 // This is unexpected, normally PhoneAccounts with CAPABILITY_CALL_PROVIDER are not