Add connection properties to analytics

Adds a record of which android.telecom.Connection properties were set on
a call during its lifetime. Also adds a test to verify that this behaves
correctly.

Change-Id: I1a5bc61228cbd676b8de218d503b30e8a76bfce2
Fix: 31395995
diff --git a/proto/telecom.proto b/proto/telecom.proto
index 9786934..06dd394 100644
--- a/proto/telecom.proto
+++ b/proto/telecom.proto
@@ -273,4 +273,8 @@
 
   // A list of the in-call services bound during the call.
   repeated InCallServiceInfo in_call_services = 16;
+
+  // A bitmask of the properties that were set at any point during the call.
+  // Bits are defined by android.telecom.Connection.PROPERTY_* constants.
+  optional int32 connection_properties = 17;
 }
diff --git a/src/com/android/server/telecom/Analytics.java b/src/com/android/server/telecom/Analytics.java
index 7c384e6..4456734 100644
--- a/src/com/android/server/telecom/Analytics.java
+++ b/src/com/android/server/telecom/Analytics.java
@@ -16,6 +16,7 @@
 
 package com.android.server.telecom;
 
+import android.telecom.Connection;
 import android.telecom.DisconnectCause;
 import android.telecom.ParcelableCallAnalytics;
 import android.telecom.TelecomAnalytics;
@@ -179,6 +180,9 @@
 
         public void addInCallService(String serviceName, int type) {
         }
+
+        public void addCallProperties(int properties) {
+        }
     }
 
     /**
@@ -211,6 +215,8 @@
         public boolean isVideo = false;
         public List<TelecomLogClass.VideoEvent> videoEvents;
         public List<TelecomLogClass.InCallServiceInfo> inCallServiceInfos;
+        public int callProperties = 0;
+
         private long mTimeOfLastVideoEvent = -1;
 
         CallInfoImpl(String callId, int callDirection) {
@@ -238,6 +244,7 @@
             this.callEvents = other.callEvents;
             this.isVideo = other.isVideo;
             this.videoEvents = other.videoEvents;
+            this.callProperties = other.callProperties;
 
             if (other.callTerminationReason != null) {
                 this.callTerminationReason = new DisconnectCause(
@@ -336,6 +343,11 @@
         }
 
         @Override
+        public void addCallProperties(int properties) {
+            this.callProperties |= properties;
+        }
+
+        @Override
         public String toString() {
             return "{\n"
                     + "    startTime: " + startTime + '\n'
@@ -348,6 +360,8 @@
                     + "    connectionService: " + connectionService + '\n'
                     + "    isVideoCall: " + isVideo + '\n'
                     + "    inCallServices: " + getInCallServicesString() + '\n'
+                    + "    callProperties: " + Connection.propertiesToStringShort(callProperties)
+                    + '\n'
                     + "}\n";
         }
 
@@ -415,7 +429,8 @@
                     .setIsEmergencyCall(isEmergency)
                     .setIsCreatedFromExistingConnection(createdFromExistingConnection)
                     .setIsEmergencyCall(isEmergency)
-                    .setIsVideoCall(isVideo);
+                    .setIsVideoCall(isVideo)
+                    .setConnectionProperties(callProperties);
 
             result.connectionService = new String[] {connectionService};
             if (callEvents != null) {
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index b76d4e0..5a0e9c0 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -1052,6 +1052,8 @@
 
             }
 
+            mAnalytics.addCallProperties(mConnectionProperties);
+
             int xorProps = previousProperties ^ mConnectionProperties;
             Log.event(this, Log.Events.PROPERTY_CHANGE,
                     "Current: [%s], Removed [%s], Added [%s]",
diff --git a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
index eeb92c6..81d4aa5 100644
--- a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
+++ b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
@@ -17,6 +17,7 @@
 package com.android.server.telecom.tests;
 
 import android.content.Context;
+import android.telecom.Connection;
 import android.telecom.DisconnectCause;
 import android.telecom.InCallService;
 import android.telecom.ParcelableCallAnalytics;
@@ -54,6 +55,7 @@
                 "650-555-1212",
                 mPhoneAccountA0.getAccountHandle(),
                 mConnectionServiceFixtureA);
+
         Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
 
         assertTrue(analyticsMap.containsKey(testCall.mCallId));
@@ -300,6 +302,41 @@
                 ParcelableCallAnalytics.AnalyticsEvent.FILTERING_INITIATED));
     }
 
+    @MediumTest
+    public void testAnalyticsConnectionProperties() throws Exception {
+        Analytics.reset();
+        IdPair testCall = startAndMakeActiveIncomingCall(
+                "650-555-1212",
+                mPhoneAccountA0.getAccountHandle(),
+                mConnectionServiceFixtureA);
+
+        int properties1 = Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE
+                | Connection.PROPERTY_WIFI
+                | Connection.PROPERTY_EMERGENCY_CALLBACK_MODE;
+        int properties2 = Connection.PROPERTY_HIGH_DEF_AUDIO
+                | Connection.PROPERTY_WIFI;
+        int expectedProperties = properties1 | properties2;
+
+        mConnectionServiceFixtureA.mConnectionById.get(testCall.mConnectionId).properties =
+                properties1;
+        mConnectionServiceFixtureA.sendSetConnectionProperties(testCall.mConnectionId);
+        mConnectionServiceFixtureA.mConnectionById.get(testCall.mConnectionId).properties =
+                properties2;
+        mConnectionServiceFixtureA.sendSetConnectionProperties(testCall.mConnectionId);
+
+        mConnectionServiceFixtureA.
+                sendSetDisconnected(testCall.mConnectionId, DisconnectCause.ERROR);
+
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        Analytics.dumpToEncodedProto(pw, new String[]{});
+        TelecomLogClass.TelecomLog analyticsProto =
+                TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
+
+        assertEquals(expectedProperties,
+                analyticsProto.callLogs[0].getConnectionProperties() & expectedProperties);
+    }
+
     private void assertIsRoundedToOneSigFig(long x) {
         assertEquals(x, Analytics.roundToOneSigFig(x));
     }
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index 962ab10..255f3ea 100644
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -434,6 +434,11 @@
         }
     }
 
+    public void sendSetConnectionProperties(String id) throws Exception {
+        for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
+            a.setConnectionProperties(id, mConnectionById.get(id).properties);
+        }
+    }
     public void sendSetIsConferenced(String id) throws Exception {
         for (IConnectionServiceAdapter a : mConnectionServiceAdapters) {
             a.setIsConferenced(id, mConnectionById.get(id).conferenceId);