Pipe through Call Quality reports to CallDiagnosticService

Receive connection event with call quality report and relay to the
CallDiagnosticService.

Test: Added CTS test.
Test: Manual test with test implementation of CDS.
Bug: 163085177
Change-Id: I97de7f88761d5c246edd46675da461fba52acc3c
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index b011879..7ba7a09 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -57,6 +57,7 @@
 import android.telecom.StatusHints;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
+import android.telephony.CallQuality;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
@@ -162,6 +163,7 @@
         void onHandoverComplete(Call call);
         void onBluetoothCallQualityReport(Call call, BluetoothCallQualityReport report);
         void onReceivedDeviceToDeviceMessage(Call call, int messageType, int messageValue);
+        void onReceivedCallQualityReport(Call call, CallQuality callQuality);
     }
 
     public abstract static class ListenerBase implements Listener {
@@ -254,6 +256,8 @@
         public void onBluetoothCallQualityReport(Call call, BluetoothCallQualityReport report) {}
         @Override
         public void onReceivedDeviceToDeviceMessage(Call call, int messageType, int messageValue) {}
+        @Override
+        public void onReceivedCallQualityReport(Call call, CallQuality callQuality) {}
     }
 
     private final CallerInfoLookupHelper.OnQueryCompleteListener mCallerInfoQueryListener =
@@ -3790,6 +3794,12 @@
             for (Listener l : mListeners) {
                 l.onReceivedDeviceToDeviceMessage(this, messageType, messageValue);
             }
+        } else if (Connection.EVENT_CALL_QUALITY_REPORT.equals(event)
+                && extras != null && extras.containsKey(Connection.EXTRA_CALL_QUALITY_REPORT)) {
+            CallQuality callQuality = extras.getParcelable(Connection.EXTRA_CALL_QUALITY_REPORT);
+            for (Listener l : mListeners) {
+                l.onReceivedCallQualityReport(this, callQuality);
+            }
         } else {
             for (Listener l : mListeners) {
                 l.onConnectionEvent(this, event, extras);
@@ -4154,7 +4164,10 @@
             mDisconnectFuture.thenRunAsync(() -> {
                 if (!mReceivedCallDiagnosticPostCallResponse) {
                     Log.addEvent(this, LogUtils.Events.CALL_DIAGNOSTIC_SERVICE_TIMEOUT);
-                }},
+                }
+                // Clear the future as a final step.
+                mDisconnectFuture = null;
+                },
                 new LoggedHandlerExecutor(mHandler, "C.iDF", mLock))
                     .exceptionally((throwable) -> {
                         Log.e(this, throwable, "Error while executing disconnect future");
@@ -4176,7 +4189,7 @@
      * if this is handled immediately.
      */
     public boolean isDisconnectHandledViaFuture() {
-        return mDisconnectFuture != null && !mDisconnectFuture.isDone();
+        return mDisconnectFuture != null;
     }
 
     /**
diff --git a/src/com/android/server/telecom/CallDiagnosticServiceController.java b/src/com/android/server/telecom/CallDiagnosticServiceController.java
index 7737a44..30c6f93 100644
--- a/src/com/android/server/telecom/CallDiagnosticServiceController.java
+++ b/src/com/android/server/telecom/CallDiagnosticServiceController.java
@@ -40,6 +40,7 @@
 import android.telecom.InCallService;
 import android.telecom.Log;
 import android.telecom.ParcelableCall;
+import android.telephony.CallQuality;
 import android.telephony.ims.ImsReasonInfo;
 import android.text.TextUtils;
 
@@ -154,6 +155,16 @@
         public void onReceivedDeviceToDeviceMessage(Call call, int messageType, int messageValue) {
             handleReceivedDeviceToDeviceMessage(call, messageType, messageValue);
         }
+
+        /**
+         * Handles an incoming {@link CallQuality} report from a {@link android.telecom.Connection}.
+         * @param call The call.
+         * @param callQualityReport The call quality report.
+         */
+        @Override
+        public void onReceivedCallQualityReport(Call call, CallQuality callQualityReport) {
+            handleCallQualityReport(call, callQualityReport);
+        }
     };
 
     /**
@@ -651,6 +662,23 @@
     }
 
     /**
+     * Handles a reported {@link CallQuality} report from a {@link android.telecom.Connection}.
+     * @param call The call the report originated from.
+     * @param callQualityReport The {@link CallQuality} report.
+     */
+    private void handleCallQualityReport(@NonNull Call call,
+            @NonNull CallQuality callQualityReport) {
+        try {
+            if (isConnected()) {
+                mCallDiagnosticService.callQualityChanged(call.getId(), callQualityReport);
+            }
+        } catch (RemoteException e) {
+            Log.w(this, "handleCallQualityReport: callId=%s, exception=%s",
+                    call.getId(), e);
+        }
+    }
+
+    /**
      * Get a parcelled representation of a call for transport to the service.
      * @param call The call.
      * @return The parcelled call.