Add In-call services to Analytics

Add a repeated field to the analytics proto containing the name of the
in-call service and the type, and adds code to populate the field from
InCallController.

Fix: 29228080
Change-Id: Ic57cd220e7f5ce1409516e520380f635c54d3013
diff --git a/proto/telecom.proto b/proto/telecom.proto
index f0b3d02..9786934 100644
--- a/proto/telecom.proto
+++ b/proto/telecom.proto
@@ -149,6 +149,23 @@
   optional int64 time_millis = 2;
 }
 
+message InCallServiceInfo {
+  // Keep this up-to-date with com.android.server.telecom.InCallController.
+  enum InCallServiceType {
+    IN_CALL_SERVICE_TYPE_INVALID = 0;
+    IN_CALL_SERVICE_TYPE_DIALER_UI = 1;
+    IN_CALL_SERVICE_TYPE_SYSTEM_UI = 2;
+    IN_CALL_SERVICE_TYPE_CAR_MODE_UI = 3;
+    IN_CALL_SERVICE_TYPE_NON_UI = 4;
+  }
+
+  // The shortened component name of the in-call service.
+  optional string in_call_service_name = 1;
+
+  // The type of the in-call service
+  optional InCallServiceType in_call_service_type = 2;
+}
+
 // Information about each call.
 message CallLog {
 
@@ -227,7 +244,7 @@
   // A bitmask with bits corresponding to call technologies that were used
   // during the call. The ones that we will record are CDMA, GSM, IMS, SIP,
   // and third-party.
-  // https://googleplex-android-review.git.corp.google.com/#/c/816516/6/src/com/android/server/telecom/Analytics.java
+  // See the com.android.server.telecom.Analytics.*_PHONE constants.
   optional int32 call_technologies = 6;
 
   // Indicates the call termination code.
@@ -253,4 +270,7 @@
 
   // A list of the video events during the call.
   repeated VideoEvent video_events = 15;
+
+  // A list of the in-call services bound during the call.
+  repeated InCallServiceInfo in_call_services = 16;
 }
diff --git a/src/com/android/server/telecom/Analytics.java b/src/com/android/server/telecom/Analytics.java
index 0ad130b..7c384e6 100644
--- a/src/com/android/server/telecom/Analytics.java
+++ b/src/com/android/server/telecom/Analytics.java
@@ -176,6 +176,9 @@
 
         public void addVideoEvent(int eventId, int videoState) {
         }
+
+        public void addInCallService(String serviceName, int type) {
+        }
     }
 
     /**
@@ -207,6 +210,7 @@
 
         public boolean isVideo = false;
         public List<TelecomLogClass.VideoEvent> videoEvents;
+        public List<TelecomLogClass.InCallServiceInfo> inCallServiceInfos;
         private long mTimeOfLastVideoEvent = -1;
 
         CallInfoImpl(String callId, int callDirection) {
@@ -217,6 +221,7 @@
             callTechnologies = 0;
             connectionService = "";
             videoEvents = new LinkedList<>();
+            inCallServiceInfos = new LinkedList<>();
         }
 
         CallInfoImpl(CallInfoImpl other) {
@@ -324,6 +329,13 @@
         }
 
         @Override
+        public void addInCallService(String serviceName, int type) {
+            inCallServiceInfos.add(new TelecomLogClass.InCallServiceInfo()
+                    .setInCallServiceName(serviceName)
+                    .setInCallServiceType(type));
+        }
+
+        @Override
         public String toString() {
             return "{\n"
                     + "    startTime: " + startTime + '\n'
@@ -335,6 +347,7 @@
                     + "    callTerminationReason: " + getCallDisconnectReasonString() + '\n'
                     + "    connectionService: " + connectionService + '\n'
                     + "    isVideoCall: " + isVideo + '\n'
+                    + "    inCallServices: " + getInCallServicesString() + '\n'
                     + "}\n";
         }
 
@@ -413,6 +426,9 @@
             }
             result.videoEvents =
                     videoEvents.toArray(new TelecomLogClass.VideoEvent[videoEvents.size()]);
+            result.inCallServices = inCallServiceInfos.toArray(
+                    new TelecomLogClass.InCallServiceInfo[inCallServiceInfos.size()]);
+
             return result;
         }
 
@@ -448,6 +464,21 @@
                 return "NOT SET";
             }
         }
+
+        private String getInCallServicesString() {
+            StringBuilder s = new StringBuilder();
+            s.append("[\n");
+            for (TelecomLogClass.InCallServiceInfo service : inCallServiceInfos) {
+                s.append("    ");
+                s.append("name: ");
+                s.append(service.getInCallServiceName());
+                s.append(" type: ");
+                s.append(service.getInCallServiceType());
+                s.append("\n");
+            }
+            s.append("]");
+            return s.toString();
+        }
     }
     public static final String TAG = "TelecomAnalytics";
 
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index f24ffc0..2157bf3 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -79,12 +79,16 @@
     }
 
     private class InCallServiceInfo {
-        private ComponentName mComponentName;
+        private final ComponentName mComponentName;
         private boolean mIsExternalCallsSupported;
+        private final int mType;
 
-        public InCallServiceInfo(ComponentName componentName, boolean isExternalCallsSupported) {
+        public InCallServiceInfo(ComponentName componentName,
+                boolean isExternalCallsSupported,
+                int type) {
             mComponentName = componentName;
             mIsExternalCallsSupported = isExternalCallsSupported;
+            mType = type;
         }
 
         public ComponentName getComponentName() {
@@ -95,6 +99,10 @@
             return mIsExternalCallsSupported;
         }
 
+        public int getType() {
+            return mType;
+        }
+
         @Override
         public boolean equals(Object o) {
             if (this == o) {
@@ -192,6 +200,12 @@
                 mIsConnected = false;
             }
 
+            if (call != null && mIsConnected) {
+                call.getAnalytics().addInCallService(
+                        mInCallServiceInfo.getComponentName().flattenToShortString(),
+                        mInCallServiceInfo.getType());
+            }
+
             return mIsConnected;
         }
 
@@ -920,7 +934,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);
+            return new InCallServiceInfo(componentName, false, type);
         }
     }
 
@@ -974,7 +988,7 @@
 
                     retval.add(new InCallServiceInfo(
                             new ComponentName(serviceInfo.packageName, serviceInfo.name),
-                            isExternalCallsSupported));
+                            isExternalCallsSupported, requestedType));
                 }
             }
         }