Propagate Telephony disconnect cause to Telecom.

Propagate telephony disconnect causes and imsreasoninfo to Telecom for
propagation to CAllDiagnosticService.

Plumb through disconnect message override in CallDiagnosticService.

Test: Added new CTS test coverage for these APIs.
Test: Manual test with telecom test app; verify the disconnect message is
overridden.
Bug: 163085177

Change-Id: I0c6938f2d0a46d535ae201364193ef58e07ec488
diff --git a/telecomm/java/android/telecom/CallDiagnosticService.java b/telecomm/java/android/telecom/CallDiagnosticService.java
index 201c5db..a5f7729 100644
--- a/telecomm/java/android/telecom/CallDiagnosticService.java
+++ b/telecomm/java/android/telecom/CallDiagnosticService.java
@@ -24,6 +24,8 @@
 import android.content.Intent;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.telephony.Annotation;
+import android.telephony.ims.ImsReasonInfo;
 import android.util.ArrayMap;
 
 import com.android.internal.telecom.ICallDiagnosticService;
@@ -96,6 +98,12 @@
                 throws RemoteException {
             handleBluetoothCallQualityReport(qualityReport);
         }
+
+        @Override
+        public void notifyCallDisconnected(@NonNull String callId,
+                @NonNull DisconnectCause disconnectCause) throws RemoteException {
+            handleCallDisconnected(callId, disconnectCause);
+        }
     }
 
     /**
@@ -257,6 +265,32 @@
     }
 
     /**
+     * Handles a request from the Telecom framework to get a disconnect message from the
+     * {@link CallDiagnosticService}.
+     * @param callId The ID of the call.
+     * @param disconnectCause The telecom disconnect cause.
+     */
+    private void handleCallDisconnected(@NonNull String callId,
+            @NonNull DisconnectCause disconnectCause) {
+        Log.i(this, "handleCallDisconnected: call=%s; cause=%s", callId, disconnectCause);
+        DiagnosticCall diagnosticCall = mDiagnosticCallByTelecomCallId.get(callId);
+        CharSequence message;
+        if (disconnectCause.getImsReasonInfo() != null) {
+            message = diagnosticCall.onCallDisconnected(disconnectCause.getImsReasonInfo());
+        } else {
+            message = diagnosticCall.onCallDisconnected(
+                    disconnectCause.getTelephonyDisconnectCause(),
+                    disconnectCause.getTelephonyPreciseDisconnectCause());
+        }
+        try {
+            mAdapter.overrideDisconnectMessage(callId, message);
+        } catch (RemoteException e) {
+            Log.w(this, "handleCallDisconnected: call=%s; cause=%s; %s",
+                    callId, disconnectCause, e);
+        }
+    }
+
+    /**
      * Handles an incoming bluetooth call quality report from Telecom.  Notifies via
      * {@link CallDiagnosticService#onBluetoothCallQualityReportReceived(
      * BluetoothCallQualityReport)}.