Support for InCallServices receiving self-managed calls.

Also adding isInManagedCall telecomManager API.

Test: Manual, CTS
Bug: 34159263
Change-Id: I2e30cf2800b7febf56566755f7b97e4ad46ec1ad
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 95d152c..2da8bc5 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -2045,7 +2045,7 @@
     }
 
     /**
-     * Given a {@link PhoneAccountHandle} determines if there are and managed calls.
+     * Determines if there are any managed calls.
      * @return {@code true} if there are managed calls, {@code false} otherwise.
      */
     public boolean hasManagedCalls() {
@@ -2053,6 +2053,17 @@
                 !call.isExternalCall()).count() > 0;
     }
 
+    /**
+     * Determines if there are any ongoing managed calls.
+     * @return {@code true} if there are ongoing managed calls, {@code false} otherwise.
+     */
+    public boolean hasOngoingManagedCalls() {
+        return getNumCallsWithState(
+                false /* isSelfManaged */, null /* excludeCall */,
+                null /* phoneAccountHandle */,
+                LIVE_CALL_STATES) > 0;
+    }
+
     private boolean makeRoomForOutgoingCall(Call call, boolean isEmergency) {
         if (hasMaximumManagedLiveCalls(call)) {
             // NOTE: If the amount of live calls changes beyond 1, this logic will probably
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index dce4364..85b5e70 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -84,13 +84,16 @@
     private class InCallServiceInfo {
         private final ComponentName mComponentName;
         private boolean mIsExternalCallsSupported;
+        private boolean mIsSelfManagedCallsSupported;
         private final int mType;
 
         public InCallServiceInfo(ComponentName componentName,
                 boolean isExternalCallsSupported,
+                boolean isSelfManageCallsSupported,
                 int type) {
             mComponentName = componentName;
             mIsExternalCallsSupported = isExternalCallsSupported;
+            mIsSelfManagedCallsSupported = isSelfManageCallsSupported;
             mType = type;
         }
 
@@ -102,6 +105,10 @@
             return mIsExternalCallsSupported;
         }
 
+        public boolean isSelfManagedCallsSupported() {
+            return mIsSelfManagedCallsSupported;
+        }
+
         public int getType() {
             return mType;
         }
@@ -120,18 +127,23 @@
             if (mIsExternalCallsSupported != that.mIsExternalCallsSupported) {
                 return false;
             }
+            if (mIsSelfManagedCallsSupported != that.mIsExternalCallsSupported) {
+                return false;
+            }
             return mComponentName.equals(that.mComponentName);
 
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(mComponentName, mIsExternalCallsSupported);
+            return Objects.hash(mComponentName, mIsExternalCallsSupported,
+                    mIsSelfManagedCallsSupported);
         }
 
         @Override
         public String toString() {
-            return "[" + mComponentName + " supportsExternal? " + mIsExternalCallsSupported + "]";
+            return "[" + mComponentName + " supportsExternal? " + mIsExternalCallsSupported +
+                    " supportsSelfMg?" + mIsSelfManagedCallsSupported + "]";
         }
     }
 
@@ -658,11 +670,6 @@
 
     @Override
     public void onCallAdded(Call call) {
-        if (call.isSelfManaged()) {
-            Log.i(this, "onCallAdded: skipped self-managed %s", call);
-            return;
-        }
-
         if (!isBoundToServices()) {
             bindToServices(call);
         } else {
@@ -700,11 +707,6 @@
 
     @Override
     public void onCallRemoved(Call call) {
-        if (call.isSelfManaged()) {
-            Log.i(this, "onCallRemoved: skipped self-managed %s", call);
-            return;
-        }
-
         Log.i(this, "onCallRemoved: %s", call);
         if (mCallsManager.getCalls().isEmpty()) {
             /** Let's add a 2 second delay before we send unbind to the services to hopefully
@@ -728,11 +730,6 @@
 
     @Override
     public void onExternalCallChanged(Call call, boolean isExternalCall) {
-        if (call.isSelfManaged()) {
-            Log.i(this, "onExternalCallChanged: skipped self-managed %s", call);
-            return;
-        }
-
         Log.i(this, "onExternalCallChanged: %s -> %b", call, isExternalCall);
 
         List<ComponentName> componentsUpdated = new ArrayList<>();
@@ -748,6 +745,10 @@
                     continue;
                 }
 
+                if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
+                    continue;
+                }
+
                 componentsUpdated.add(info.getComponentName());
                 IInCallService inCallService = entry.getValue();
 
@@ -798,11 +799,6 @@
 
     @Override
     public void onCallStateChanged(Call call, int oldState, int newState) {
-        if (call.isSelfManaged()) {
-            Log.i(this, "onExternalCallChanged: skipped self-managed %s", call);
-            return;
-        }
-
         updateCall(call);
     }
 
@@ -811,11 +807,6 @@
             Call call,
             ConnectionServiceWrapper oldService,
             ConnectionServiceWrapper newService) {
-        if (call.isSelfManaged()) {
-            Log.i(this, "onConnectionServiceChanged: skipped self-managed %s", call);
-            return;
-        }
-
         updateCall(call);
     }
 
@@ -861,11 +852,6 @@
 
     @Override
     public void onIsConferencedChanged(Call call) {
-        if (call.isSelfManaged()) {
-            Log.i(this, "onIsConferencedChanged: skipped self-managed %s", call);
-            return;
-        }
-
         Log.d(this, "onIsConferencedChanged %s", call);
         updateCall(call);
     }
@@ -992,7 +978,7 @@
             // Last Resort: Try to bind to the ComponentName given directly.
             Log.e(this, new Exception(), "Package Manager could not find ComponentName: "
                     + componentName +". Trying to bind anyway.");
-            return new InCallServiceInfo(componentName, false, type);
+            return new InCallServiceInfo(componentName, false, false, type);
         }
     }
 
@@ -1041,12 +1027,15 @@
                 boolean isExternalCallsSupported = serviceInfo.metaData != null &&
                         serviceInfo.metaData.getBoolean(
                                 TelecomManager.METADATA_INCLUDE_EXTERNAL_CALLS, false);
+                boolean isSelfManageCallsSupported = serviceInfo.metaData != null &&
+                        serviceInfo.metaData.getBoolean(
+                                TelecomManager.METADATA_INCLUDE_SELF_MANAGED_CALLS, false);
                 if (requestedType == 0 || requestedType == getInCallServiceType(entry.serviceInfo,
                         packageManager)) {
 
                     retval.add(new InCallServiceInfo(
                             new ComponentName(serviceInfo.packageName, serviceInfo.name),
-                            isExternalCallsSupported, requestedType));
+                            isExternalCallsSupported, isSelfManageCallsSupported, requestedType));
                 }
             }
         }
@@ -1160,7 +1149,7 @@
         int numCallsSent = 0;
         for (Call call : calls) {
             try {
-                if (call.isSelfManaged() ||
+                if ((call.isSelfManaged() && !info.isSelfManagedCallsSupported()) ||
                         (call.isExternalCall() && !info.isExternalCallsSupported())) {
                     continue;
                 }
@@ -1229,6 +1218,10 @@
                     continue;
                 }
 
+                if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
+                    continue;
+                }
+
                 ParcelableCall parcelableCall = ParcelableCallUtils.toParcelableCall(
                         call,
                         videoProviderChanged /* includeVideoProvider */,
diff --git a/src/com/android/server/telecom/ParcelableCallUtils.java b/src/com/android/server/telecom/ParcelableCallUtils.java
index e855549..cbe3676 100644
--- a/src/com/android/server/telecom/ParcelableCallUtils.java
+++ b/src/com/android/server/telecom/ParcelableCallUtils.java
@@ -332,7 +332,10 @@
         android.telecom.Call.Details.PROPERTY_IS_EXTERNAL_CALL,
 
         Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY,
-        android.telecom.Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY
+        android.telecom.Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY,
+
+        Connection.PROPERTY_SELF_MANAGED,
+        android.telecom.Call.Details.PROPERTY_SELF_MANAGED
     };
 
     private static int convertConnectionToCallProperties(int connectionProperties) {
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 51f11d7..74eb8bc 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -648,6 +648,26 @@
         }
 
         /**
+         * @see android.telecom.TelecomManager#isInManagedCall
+         */
+        @Override
+        public boolean isInManagedCall(String callingPackage) {
+            try {
+                Log.startSession("TSI.iIMC");
+                if (!canReadPhoneState(callingPackage, "isInManagedCall")) {
+                    throw new SecurityException("Only the default dialer or caller with " +
+                            "READ_PHONE_STATE permission can use this method.");
+                }
+
+                synchronized (mLock) {
+                    return mCallsManager.hasOngoingManagedCalls();
+                }
+            } finally {
+                Log.endSession();
+            }
+        }
+
+        /**
          * @see android.telecom.TelecomManager#isRinging
          */
         @Override