summaryrefslogtreecommitdiff
path: root/telecomm
diff options
context:
space:
mode:
authorScott Lobdell <slobdell@google.com>2021-03-29 16:12:49 +0000
committerScott Lobdell <slobdell@google.com>2021-04-02 22:35:29 +0000
commit21cdef883cc867db55340b25d5c95e19b12ab383 (patch)
tree93d1444ebe783f53f5f0ae2647592723b27b3fb8 /telecomm
parent7deab3736bb5f3a92be8ac820096926dce2366ad (diff)
parentd1d45f856fdf68835f5b42eacecab44e6dfa8545 (diff)
Merge SP1A.210329.001
Change-Id: I1e21c5890b5b2e2f2855f09960bc8eec8aa922bf
Diffstat (limited to 'telecomm')
-rwxr-xr-xtelecomm/java/android/telecom/Call.java76
-rw-r--r--telecomm/java/android/telecom/CallDiagnosticService.java241
-rw-r--r--telecomm/java/android/telecom/CallDiagnostics.java374
-rw-r--r--telecomm/java/android/telecom/Conference.java2
-rw-r--r--telecomm/java/android/telecom/Connection.java24
-rwxr-xr-xtelecomm/java/android/telecom/ConnectionService.java36
-rw-r--r--telecomm/java/android/telecom/DiagnosticCall.java358
-rw-r--r--telecomm/java/android/telecom/DisconnectCause.java89
-rw-r--r--telecomm/java/android/telecom/ParcelableCall.java2
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java4
-rw-r--r--telecomm/java/com/android/internal/telecom/ICallDiagnosticService.aidl4
11 files changed, 765 insertions, 445 deletions
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 7334013093e2..41d4df43b1da 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -138,6 +138,27 @@ public final class Call {
public static final int STATE_SIMULATED_RINGING = 13;
/**
+ * @hide
+ */
+ @IntDef(prefix = { "STATE_" },
+ value = {
+ STATE_NEW,
+ STATE_DIALING,
+ STATE_RINGING,
+ STATE_HOLDING,
+ STATE_ACTIVE,
+ STATE_DISCONNECTED,
+ STATE_SELECT_PHONE_ACCOUNT,
+ STATE_CONNECTING,
+ STATE_DISCONNECTING,
+ STATE_PULLING_CALL,
+ STATE_AUDIO_PROCESSING,
+ STATE_SIMULATED_RINGING
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallState {};
+
+ /**
* The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
* extras. Used to pass the phone accounts to display on the front end to the user in order to
* select phone accounts to (for example) place a call.
@@ -673,7 +694,11 @@ public final class Call {
public static final int PROPERTY_IS_ADHOC_CONFERENCE = 0x00002000;
/**
- * Connection is using Cross SIM Calling.
+ * Connection is using cross sim technology.
+ * <p>
+ * Indicates that the {@link Connection} is using a cross sim technology which would
+ * register IMS over internet APN of default data subscription.
+ * <p>
*/
public static final int PROPERTY_CROSS_SIM = 0x00004000;
@@ -681,6 +706,7 @@ public final class Call {
// Next PROPERTY value: 0x00004000
//******************************************************************************************
+ private final @CallState int mState;
private final String mTelecomCallId;
private final Uri mHandle;
private final int mHandlePresentation;
@@ -878,6 +904,13 @@ public final class Call {
return builder.toString();
}
+ /**
+ * @return the state of the {@link Call} represented by this {@link Call.Details}.
+ */
+ public final @CallState int getState() {
+ return mState;
+ }
+
/** {@hide} */
@TestApi
public String getTelecomCallId() {
@@ -1079,6 +1112,7 @@ public final class Call {
if (o instanceof Details) {
Details d = (Details) o;
return
+ Objects.equals(mState, d.mState) &&
Objects.equals(mHandle, d.mHandle) &&
Objects.equals(mHandlePresentation, d.mHandlePresentation) &&
Objects.equals(mCallerDisplayName, d.mCallerDisplayName) &&
@@ -1105,7 +1139,8 @@ public final class Call {
@Override
public int hashCode() {
- return Objects.hash(mHandle,
+ return Objects.hash(mState,
+ mHandle,
mHandlePresentation,
mCallerDisplayName,
mCallerDisplayNamePresentation,
@@ -1127,6 +1162,7 @@ public final class Call {
/** {@hide} */
public Details(
+ @CallState int state,
String telecomCallId,
Uri handle,
int handlePresentation,
@@ -1146,6 +1182,7 @@ public final class Call {
String contactDisplayName,
int callDirection,
int callerNumberVerificationStatus) {
+ mState = state;
mTelecomCallId = telecomCallId;
mHandle = handle;
mHandlePresentation = handlePresentation;
@@ -1170,6 +1207,7 @@ public final class Call {
/** {@hide} */
public static Details createFromParcelableCall(ParcelableCall parcelableCall) {
return new Details(
+ parcelableCall.getState(),
parcelableCall.getId(),
parcelableCall.getHandle(),
parcelableCall.getHandlePresentation(),
@@ -1196,6 +1234,8 @@ public final class Call {
StringBuilder sb = new StringBuilder();
sb.append("[id: ");
sb.append(mTelecomCallId);
+ sb.append(", state: ");
+ sb.append(Call.stateToString(mState));
sb.append(", pa: ");
sb.append(mAccountHandle);
sb.append(", hdl: ");
@@ -1312,7 +1352,7 @@ public final class Call {
* @param call The {@code Call} invoking this method.
* @param state The new state of the {@code Call}.
*/
- public void onStateChanged(Call call, int state) {}
+ public void onStateChanged(Call call, @CallState int state) {}
/**
* Invoked when the parent of this {@code Call} has changed. See {@link #getParent()}.
@@ -2181,9 +2221,11 @@ public final class Call {
/**
* Obtains the state of this {@code Call}.
*
- * @return A state value, chosen from the {@code STATE_*} constants.
+ * @return The call state.
+ * @deprecated The call state is available via {@link Call.Details#getState()}.
*/
- public int getState() {
+ @Deprecated
+ public @CallState int getState() {
return mState;
}
@@ -2561,6 +2603,30 @@ public final class Call {
final void internalSetDisconnected() {
if (mState != Call.STATE_DISCONNECTED) {
mState = Call.STATE_DISCONNECTED;
+ if (mDetails != null) {
+ mDetails = new Details(mState,
+ mDetails.getTelecomCallId(),
+ mDetails.getHandle(),
+ mDetails.getHandlePresentation(),
+ mDetails.getCallerDisplayName(),
+ mDetails.getCallerDisplayNamePresentation(),
+ mDetails.getAccountHandle(),
+ mDetails.getCallCapabilities(),
+ mDetails.getCallProperties(),
+ mDetails.getDisconnectCause(),
+ mDetails.getConnectTimeMillis(),
+ mDetails.getGatewayInfo(),
+ mDetails.getVideoState(),
+ mDetails.getStatusHints(),
+ mDetails.getExtras(),
+ mDetails.getIntentExtras(),
+ mDetails.getCreationTimeMillis(),
+ mDetails.getContactDisplayName(),
+ mDetails.getCallDirection(),
+ mDetails.getCallerNumberVerificationStatus()
+ );
+ fireDetailsChanged(mDetails);
+ }
fireStateChanged(mState);
fireCallDestroyed();
}
diff --git a/telecomm/java/android/telecom/CallDiagnosticService.java b/telecomm/java/android/telecom/CallDiagnosticService.java
index 201c5db74e16..011dc17a1c1e 100644
--- a/telecomm/java/android/telecom/CallDiagnosticService.java
+++ b/telecomm/java/android/telecom/CallDiagnosticService.java
@@ -19,17 +19,23 @@ package android.telecom;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.RemoteException;
+
+import android.telephony.CallQuality;
import android.util.ArrayMap;
import com.android.internal.telecom.ICallDiagnosticService;
import com.android.internal.telecom.ICallDiagnosticServiceAdapter;
import java.util.Map;
+import java.util.concurrent.Executor;
/**
* The platform supports a single OEM provided {@link CallDiagnosticService}, as defined by the
@@ -51,6 +57,11 @@ import java.util.Map;
* </service>
* }
* </pre>
+ * <p>
+ * <h2>Threading Model</h2>
+ * By default, all incoming IPC from Telecom in this service and in the {@link CallDiagnostics}
+ * instances will take place on the main thread. You can override {@link #getExecutor()} in your
+ * implementation to provide your own {@link Executor}.
* @hide
*/
@SystemApi
@@ -83,7 +94,7 @@ public abstract class CallDiagnosticService extends Service {
@Override
public void updateCallAudioState(CallAudioState callAudioState) throws RemoteException {
- onCallAudioStateChanged(callAudioState);
+ getExecutor().execute(() -> onCallAudioStateChanged(callAudioState));
}
@Override
@@ -96,29 +107,43 @@ public abstract class CallDiagnosticService extends Service {
throws RemoteException {
handleBluetoothCallQualityReport(qualityReport);
}
+
+ @Override
+ public void notifyCallDisconnected(@NonNull String callId,
+ @NonNull DisconnectCause disconnectCause) throws RemoteException {
+ handleCallDisconnected(callId, disconnectCause);
+ }
+
+ @Override
+ public void callQualityChanged(String callId, CallQuality callQuality)
+ throws RemoteException {
+ handleCallQualityChanged(callId, callQuality);
+ }
}
/**
- * Listens to events raised by a {@link DiagnosticCall}.
+ * Listens to events raised by a {@link CallDiagnostics}.
*/
- private android.telecom.DiagnosticCall.Listener mDiagnosticCallListener =
- new android.telecom.DiagnosticCall.Listener() {
+ private CallDiagnostics.Listener mDiagnosticCallListener =
+ new CallDiagnostics.Listener() {
@Override
- public void onSendDeviceToDeviceMessage(DiagnosticCall diagnosticCall,
- @DiagnosticCall.MessageType int message, int value) {
- handleSendDeviceToDeviceMessage(diagnosticCall, message, value);
+ public void onSendDeviceToDeviceMessage(CallDiagnostics callDiagnostics,
+ @CallDiagnostics.MessageType int message, int value) {
+ handleSendDeviceToDeviceMessage(callDiagnostics, message, value);
}
@Override
- public void onDisplayDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId,
+ public void onDisplayDiagnosticMessage(CallDiagnostics callDiagnostics,
+ int messageId,
CharSequence message) {
- handleDisplayDiagnosticMessage(diagnosticCall, messageId, message);
+ handleDisplayDiagnosticMessage(callDiagnostics, messageId, message);
}
@Override
- public void onClearDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId) {
- handleClearDiagnosticMessage(diagnosticCall, messageId);
+ public void onClearDiagnosticMessage(CallDiagnostics callDiagnostics,
+ int messageId) {
+ handleClearDiagnosticMessage(callDiagnostics, messageId);
}
};
@@ -132,9 +157,19 @@ public abstract class CallDiagnosticService extends Service {
* Map which tracks the Telecom calls received from the Telecom stack.
*/
private final Map<String, Call.Details> mCallByTelecomCallId = new ArrayMap<>();
- private final Map<String, DiagnosticCall> mDiagnosticCallByTelecomCallId = new ArrayMap<>();
+ private final Map<String, CallDiagnostics> mDiagnosticCallByTelecomCallId = new ArrayMap<>();
+ private final Object mLock = new Object();
private ICallDiagnosticServiceAdapter mAdapter;
+ /**
+ * Handles binding to the {@link CallDiagnosticService}.
+ *
+ * @param intent The Intent that was used to bind to this service,
+ * as given to {@link android.content.Context#bindService
+ * Context.bindService}. Note that any extras that were included with
+ * the Intent at that point will <em>not</em> be seen here.
+ * @return
+ */
@Nullable
@Override
public IBinder onBind(@NonNull Intent intent) {
@@ -143,32 +178,57 @@ public abstract class CallDiagnosticService extends Service {
}
/**
+ * Returns the {@link Executor} to use for incoming IPS from Telecom into your service
+ * implementation.
+ * <p>
+ * Override this method in your {@link CallDiagnosticService} implementation to provide the
+ * executor you want to use for incoming IPC.
+ *
+ * @return the {@link Executor} to use for incoming IPC from Telecom to
+ * {@link CallDiagnosticService} and {@link CallDiagnostics}.
+ */
+ @SuppressLint("OnNameExpected")
+ @NonNull public Executor getExecutor() {
+ return new HandlerExecutor(Handler.createAsync(getMainLooper()));
+ }
+
+ /**
* Telecom calls this method on the {@link CallDiagnosticService} with details about a new call
* which was added to Telecom.
* <p>
- * The {@link CallDiagnosticService} returns an implementation of {@link DiagnosticCall} to be
+ * The {@link CallDiagnosticService} returns an implementation of {@link CallDiagnostics} to be
* used for the lifespan of this call.
+ * <p>
+ * Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
+ * {@link CallDiagnosticService#getExecutor()} for more information.
*
* @param call The details of the new call.
- * @return An instance of {@link DiagnosticCall} which the {@link CallDiagnosticService}
+ * @return An instance of {@link CallDiagnostics} which the {@link CallDiagnosticService}
* provides to be used for the lifespan of the call.
- * @throws IllegalArgumentException if a {@code null} {@link DiagnosticCall} is returned.
+ * @throws IllegalArgumentException if a {@code null} {@link CallDiagnostics} is returned.
*/
- public abstract @NonNull DiagnosticCall onInitializeDiagnosticCall(@NonNull
+ public abstract @NonNull CallDiagnostics onInitializeCallDiagnostics(@NonNull
android.telecom.Call.Details call);
/**
- * Telecom calls this method when a previous created {@link DiagnosticCall} is no longer needed.
- * This happens when Telecom is no longer tracking the call in question.
+ * Telecom calls this method when a previous created {@link CallDiagnostics} is no longer
+ * needed. This happens when Telecom is no longer tracking the call in question.
+ * <p>
+ * Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
+ * {@link CallDiagnosticService#getExecutor()} for more information.
+ *
* @param call The diagnostic call which is no longer tracked by Telecom.
*/
- public abstract void onRemoveDiagnosticCall(@NonNull DiagnosticCall call);
+ public abstract void onRemoveCallDiagnostics(@NonNull CallDiagnostics call);
/**
* Telecom calls this method when the audio routing or available audio route information
* changes.
* <p>
* Audio state is common to all calls.
+ * <p>
+ * Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
+ * {@link CallDiagnosticService#getExecutor()} for more information.
*
* @param audioState The new audio state.
*/
@@ -178,6 +238,10 @@ public abstract class CallDiagnosticService extends Service {
/**
* Telecom calls this method when a {@link BluetoothCallQualityReport} is received from the
* bluetooth stack.
+ * <p>
+ * Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
+ * {@link CallDiagnosticService#getExecutor()} for more information.
+ *
* @param qualityReport the {@link BluetoothCallQualityReport}.
*/
public abstract void onBluetoothCallQualityReportReceived(
@@ -199,31 +263,40 @@ public abstract class CallDiagnosticService extends Service {
String telecomCallId = parcelableCall.getId();
Log.i(this, "handleCallAdded: callId=%s - added", telecomCallId);
Call.Details newCallDetails = Call.Details.createFromParcelableCall(parcelableCall);
- mCallByTelecomCallId.put(telecomCallId, newCallDetails);
-
- DiagnosticCall diagnosticCall = onInitializeDiagnosticCall(newCallDetails);
- if (diagnosticCall == null) {
- throw new IllegalArgumentException("A valid DiagnosticCall instance was not provided.");
+ synchronized (mLock) {
+ mCallByTelecomCallId.put(telecomCallId, newCallDetails);
}
- diagnosticCall.setListener(mDiagnosticCallListener);
- diagnosticCall.setCallId(telecomCallId);
- mDiagnosticCallByTelecomCallId.put(telecomCallId, diagnosticCall);
+
+ getExecutor().execute(() -> {
+ CallDiagnostics callDiagnostics = onInitializeCallDiagnostics(newCallDetails);
+ if (callDiagnostics == null) {
+ throw new IllegalArgumentException(
+ "A valid DiagnosticCall instance was not provided.");
+ }
+ synchronized (mLock) {
+ callDiagnostics.setListener(mDiagnosticCallListener);
+ callDiagnostics.setCallId(telecomCallId);
+ mDiagnosticCallByTelecomCallId.put(telecomCallId, callDiagnostics);
+ }
+ });
}
/**
* Handles an update to {@link Call.Details} notified by Telecom.
- * Caches the call details and notifies the {@link DiagnosticCall} of the change via
- * {@link DiagnosticCall#onCallDetailsChanged(Call.Details)}.
+ * Caches the call details and notifies the {@link CallDiagnostics} of the change via
+ * {@link CallDiagnostics#onCallDetailsChanged(Call.Details)}.
* @param parcelableCall the new parceled call details from Telecom.
*/
private void handleCallUpdated(@NonNull ParcelableCall parcelableCall) {
String telecomCallId = parcelableCall.getId();
Log.i(this, "handleCallUpdated: callId=%s - updated", telecomCallId);
Call.Details newCallDetails = Call.Details.createFromParcelableCall(parcelableCall);
-
- DiagnosticCall diagnosticCall = mDiagnosticCallByTelecomCallId.get(telecomCallId);
- mCallByTelecomCallId.put(telecomCallId, newCallDetails);
- diagnosticCall.handleCallUpdated(newCallDetails);
+ CallDiagnostics callDiagnostics;
+ synchronized (mLock) {
+ callDiagnostics = mDiagnosticCallByTelecomCallId.get(telecomCallId);
+ mCallByTelecomCallId.put(telecomCallId, newCallDetails);
+ }
+ getExecutor().execute(() -> callDiagnostics.handleCallUpdated(newCallDetails));
}
/**
@@ -236,24 +309,65 @@ public abstract class CallDiagnosticService extends Service {
if (mCallByTelecomCallId.containsKey(telecomCallId)) {
mCallByTelecomCallId.remove(telecomCallId);
}
- if (mDiagnosticCallByTelecomCallId.containsKey(telecomCallId)) {
- DiagnosticCall call = mDiagnosticCallByTelecomCallId.remove(telecomCallId);
- // Inform the service of the removed call.
- onRemoveDiagnosticCall(call);
+
+ CallDiagnostics callDiagnostics;
+ synchronized (mLock) {
+ if (mDiagnosticCallByTelecomCallId.containsKey(telecomCallId)) {
+ callDiagnostics = mDiagnosticCallByTelecomCallId.remove(telecomCallId);
+ } else {
+ callDiagnostics = null;
+ }
+ }
+
+ // Inform the service of the removed call.
+ if (callDiagnostics != null) {
+ getExecutor().execute(() -> onRemoveCallDiagnostics(callDiagnostics));
}
}
/**
* Handles an incoming device to device message received from Telecom. Notifies the
- * {@link DiagnosticCall} via {@link DiagnosticCall#onReceiveDeviceToDeviceMessage(int, int)}.
+ * {@link CallDiagnostics} via {@link CallDiagnostics#onReceiveDeviceToDeviceMessage(int, int)}.
* @param callId
* @param message
* @param value
*/
private void handleReceivedD2DMessage(@NonNull String callId, int message, int value) {
Log.i(this, "handleReceivedD2DMessage: callId=%s, msg=%d/%d", callId, message, value);
- DiagnosticCall diagnosticCall = mDiagnosticCallByTelecomCallId.get(callId);
- diagnosticCall.onReceiveDeviceToDeviceMessage(message, value);
+ CallDiagnostics callDiagnostics;
+ synchronized (mLock) {
+ callDiagnostics = mDiagnosticCallByTelecomCallId.get(callId);
+ }
+ if (callDiagnostics != null) {
+ getExecutor().execute(
+ () -> callDiagnostics.onReceiveDeviceToDeviceMessage(message, value));
+ }
+ }
+
+ /**
+ * 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);
+ CallDiagnostics callDiagnostics = mDiagnosticCallByTelecomCallId.get(callId);
+ CharSequence message;
+ if (disconnectCause.getImsReasonInfo() != null) {
+ message = callDiagnostics.onCallDisconnected(disconnectCause.getImsReasonInfo());
+ } else {
+ message = callDiagnostics.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);
+ }
}
/**
@@ -265,19 +379,34 @@ public abstract class CallDiagnosticService extends Service {
private void handleBluetoothCallQualityReport(@NonNull BluetoothCallQualityReport
qualityReport) {
Log.i(this, "handleBluetoothCallQualityReport; report=%s", qualityReport);
- onBluetoothCallQualityReportReceived(qualityReport);
+ getExecutor().execute(() -> onBluetoothCallQualityReportReceived(qualityReport));
+ }
+
+ /**
+ * Handles a change reported by Telecom to the call quality for a call.
+ * @param callId the call ID the change applies to.
+ * @param callQuality The new call quality.
+ */
+ private void handleCallQualityChanged(@NonNull String callId,
+ @NonNull CallQuality callQuality) {
+ Log.i(this, "handleCallQualityChanged; call=%s, cq=%s", callId, callQuality);
+ CallDiagnostics callDiagnostics;
+ callDiagnostics = mDiagnosticCallByTelecomCallId.get(callId);
+ if (callDiagnostics != null) {
+ callDiagnostics.onCallQualityReceived(callQuality);
+ }
}
/**
- * Handles a request from a {@link DiagnosticCall} to send a device to device message (received
- * via {@link DiagnosticCall#sendDeviceToDeviceMessage(int, int)}.
- * @param diagnosticCall
+ * Handles a request from a {@link CallDiagnostics} to send a device to device message (received
+ * via {@link CallDiagnostics#sendDeviceToDeviceMessage(int, int)}.
+ * @param callDiagnostics
* @param message
* @param value
*/
- private void handleSendDeviceToDeviceMessage(@NonNull DiagnosticCall diagnosticCall,
+ private void handleSendDeviceToDeviceMessage(@NonNull CallDiagnostics callDiagnostics,
int message, int value) {
- String callId = diagnosticCall.getCallId();
+ String callId = callDiagnostics.getCallId();
try {
mAdapter.sendDeviceToDeviceMessage(callId, message, value);
Log.i(this, "handleSendDeviceToDeviceMessage: call=%s; msg=%d/%d", callId, message,
@@ -289,15 +418,15 @@ public abstract class CallDiagnosticService extends Service {
}
/**
- * Handles a request from a {@link DiagnosticCall} to display an in-call diagnostic message.
- * Originates from {@link DiagnosticCall#displayDiagnosticMessage(int, CharSequence)}.
- * @param diagnosticCall
+ * Handles a request from a {@link CallDiagnostics} to display an in-call diagnostic message.
+ * Originates from {@link CallDiagnostics#displayDiagnosticMessage(int, CharSequence)}.
+ * @param callDiagnostics
* @param messageId
* @param message
*/
- private void handleDisplayDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId,
+ private void handleDisplayDiagnosticMessage(CallDiagnostics callDiagnostics, int messageId,
CharSequence message) {
- String callId = diagnosticCall.getCallId();
+ String callId = callDiagnostics.getCallId();
try {
mAdapter.displayDiagnosticMessage(callId, messageId, message);
Log.i(this, "handleDisplayDiagnosticMessage: call=%s; msg=%d/%s", callId, messageId,
@@ -309,14 +438,14 @@ public abstract class CallDiagnosticService extends Service {
}
/**
- * Handles a request from a {@link DiagnosticCall} to clear a previously shown diagnostic
+ * Handles a request from a {@link CallDiagnostics} to clear a previously shown diagnostic
* message.
- * Originates from {@link DiagnosticCall#clearDiagnosticMessage(int)}.
- * @param diagnosticCall
+ * Originates from {@link CallDiagnostics#clearDiagnosticMessage(int)}.
+ * @param callDiagnostics
* @param messageId
*/
- private void handleClearDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId) {
- String callId = diagnosticCall.getCallId();
+ private void handleClearDiagnosticMessage(CallDiagnostics callDiagnostics, int messageId) {
+ String callId = callDiagnostics.getCallId();
try {
mAdapter.clearDiagnosticMessage(callId, messageId);
Log.i(this, "handleClearDiagnosticMessage: call=%s; msg=%d", callId, messageId);
diff --git a/telecomm/java/android/telecom/CallDiagnostics.java b/telecomm/java/android/telecom/CallDiagnostics.java
new file mode 100644
index 000000000000..3356431f17b1
--- /dev/null
+++ b/telecomm/java/android/telecom/CallDiagnostics.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecom;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.telephony.Annotation;
+import android.telephony.CallQuality;
+import android.telephony.ims.ImsReasonInfo;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * {@link CallDiagnostics} provides a way for a {@link CallDiagnosticService} to receive diagnostic
+ * information about a mobile call on the device. A {@link CallDiagnostics} instance is similar to
+ * a {@link Call}, however it does not expose call control capabilities and exposes extra diagnostic
+ * and messaging capabilities not present on a {@link Call}. The {@link CallDiagnosticService}
+ * creates a {@link CallDiagnostics} for each {@link Call} on the device. This means that for each
+ * in progress call on the device, the {@link CallDiagnosticService} will create an instance of
+ * {@link CallDiagnostics}.
+ * <p>
+ * The {@link CallDiagnosticService} can generate mid-call diagnostic messages using the
+ * {@link #displayDiagnosticMessage(int, CharSequence)} API which provides the user with valuable
+ * information about conditions impacting their call and corrective actions. For example, if the
+ * {@link CallDiagnosticService} determines that conditions on the call are degrading, it can inform
+ * the user that the call may soon drop and that they can try using a different calling method
+ * (e.g. VOIP or WIFI).
+ * <h2>Threading Model</h2>
+ * All incoming IPC from Telecom in this class will use the same {@link Executor} as the
+ * {@link CallDiagnosticService}. See {@link CallDiagnosticService#setExecutor(Executor)} for more
+ * information.
+ * @hide
+ */
+@SystemApi
+public abstract class CallDiagnostics {
+
+ /**
+ * @hide
+ */
+ public interface Listener {
+ /**
+ * Used to inform the {@link CallDiagnosticService} of a request to send a D2d message
+ * @param callDiagnostics the call the message is from.
+ * @param message the message type
+ * @param value the message value
+ */
+ void onSendDeviceToDeviceMessage(CallDiagnostics callDiagnostics, int message, int value);
+
+ /**
+ * Used to inform the {@link CallDiagnosticService} of a request to display a diagnostic
+ * message.
+ * @param callDiagnostics the call the message pertains to.
+ * @param messageId an identifier for the message.
+ * @param message the message to display.
+ */
+ void onDisplayDiagnosticMessage(CallDiagnostics callDiagnostics, int messageId,
+ CharSequence message);
+
+ /**
+ * Used to inform the {@link CallDiagnosticService} that a previously shown message is no
+ * longer pertinent.
+ * @param callDiagnostics the call the message pertains to.
+ * @param messageId the ID of the previously posted message.
+ */
+ void onClearDiagnosticMessage(CallDiagnostics callDiagnostics, int messageId);
+ }
+
+ /**
+ * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via
+ * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the radio access type
+ * used for the current call. The call network type communicated here is an intentional
+ * simplification of the {@link android.telephony.TelephonyManager#getNetworkType(int)} which
+ * removes some of the resolution inherent in those values; the
+ * {@link android.telephony.TelephonyManager#NETWORK_TYPE_LTE_CA} value, for example is
+ * collapsed into the {@link android.telephony.TelephonyManager#NETWORK_TYPE_LTE} value for
+ * efficiency of transport. For a discussion on the necessity of this simplification, see
+ * {@link #sendDeviceToDeviceMessage(int, int)}.
+ * <p>
+ * Valid values are below:
+ * <UL>
+ * <LI>{@link android.telephony.TelephonyManager#NETWORK_TYPE_LTE}</LI>
+ * <LI>{@link android.telephony.TelephonyManager#NETWORK_TYPE_IWLAN}</LI>
+ * <LI>{@link android.telephony.TelephonyManager#NETWORK_TYPE_NR}</LI>
+ * </UL>
+ */
+ public static final int MESSAGE_CALL_NETWORK_TYPE = 1;
+
+ /**
+ * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via
+ * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the call audio codec
+ * used for the current call.
+ * <p>
+ * The audio codec communicated here is an intentional simplification of the
+ * {@link Connection#EXTRA_AUDIO_CODEC} for a call and focuses on communicating the most common
+ * variants of these audio codecs. Other variants of these codecs are reported as the next
+ * closest variant. For example, the {@link Connection#AUDIO_CODEC_EVS_FB} full band codec
+ * is reported via device to device communication as {@link Connection#AUDIO_CODEC_EVS_WB}.
+ * For a discussion on the necessity of this simplification, see
+ * {@link #sendDeviceToDeviceMessage(int, int)}.
+ * <p>
+ * Valid values:
+ * <UL>
+ * <LI>{@link Connection#AUDIO_CODEC_EVS_WB}</LI>
+ * <LI>{@link Connection#AUDIO_CODEC_AMR_WB}</LI>
+ * <LI>{@link Connection#AUDIO_CODEC_AMR}</LI>
+ * </UL>
+ */
+ public static final int MESSAGE_CALL_AUDIO_CODEC = 2;
+
+ /**
+ * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via
+ * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the battery state of
+ * the device. Will typically mirror battery state reported via intents such as
+ * {@link android.content.Intent#ACTION_BATTERY_LOW}.
+ * <p>
+ * Valid values:
+ * <UL>
+ * <LI>{@link #BATTERY_STATE_LOW}</LI>
+ * <LI>{@link #BATTERY_STATE_GOOD}</LI>
+ * <LI>{@link #BATTERY_STATE_CHARGING}</LI>
+ * </UL>
+ */
+ public static final int MESSAGE_DEVICE_BATTERY_STATE = 3;
+
+ /**
+ * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via
+ * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the overall network
+ * coverage as it pertains to the current call. A {@link CallDiagnosticService} should signal
+ * poor coverage if the network coverage reaches a level where there is a high probability of
+ * the call dropping as a result.
+ * <p>
+ * Valid values:
+ * <UL>
+ * <LI>{@link #COVERAGE_POOR}</LI>
+ * <LI>{@link #COVERAGE_GOOD}</LI>
+ * </UL>
+ */
+ public static final int MESSAGE_DEVICE_NETWORK_COVERAGE = 4;
+
+ /**@hide*/
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "MESSAGE_", value = {
+ MESSAGE_CALL_NETWORK_TYPE,
+ MESSAGE_CALL_AUDIO_CODEC,
+ MESSAGE_DEVICE_BATTERY_STATE,
+ MESSAGE_DEVICE_NETWORK_COVERAGE
+ })
+ public @interface MessageType {}
+
+ /**
+ * Used with {@link #MESSAGE_DEVICE_BATTERY_STATE} to indicate that the battery is low.
+ */
+ public static final int BATTERY_STATE_LOW = 1;
+
+ /**
+ * Used with {@link #MESSAGE_DEVICE_BATTERY_STATE} to indicate that the battery is not low.
+ */
+ public static final int BATTERY_STATE_GOOD = 2;
+
+ /**
+ * Used with {@link #MESSAGE_DEVICE_BATTERY_STATE} to indicate that the battery is charging.
+ */
+ public static final int BATTERY_STATE_CHARGING = 3;
+
+ /**
+ * Used with {@link #MESSAGE_DEVICE_NETWORK_COVERAGE} to indicate that the coverage is poor.
+ */
+ public static final int COVERAGE_POOR = 1;
+
+ /**
+ * Used with {@link #MESSAGE_DEVICE_NETWORK_COVERAGE} to indicate that the coverage is good.
+ */
+ public static final int COVERAGE_GOOD = 2;
+
+ private Listener mListener;
+ private String mCallId;
+
+ /**
+ * @hide
+ */
+ public void setListener(@NonNull Listener listener) {
+ mListener = listener;
+ }
+
+ /**
+ * Sets the call ID for this {@link CallDiagnostics}.
+ * @param callId
+ * @hide
+ */
+ public void setCallId(@NonNull String callId) {
+ mCallId = callId;
+ }
+
+ /**
+ * @return the Telecom call ID for this {@link CallDiagnostics}.
+ * @hide
+ */
+ public @NonNull String getCallId() {
+ return mCallId;
+ }
+
+ /**
+ * Telecom calls this method when the details of a call changes.
+ * <p>
+ * Calls to this method will use the same {@link Executor} as the {@link CallDiagnosticService};
+ * see {@link CallDiagnosticService#getExecutor()} for more information.
+ */
+ public abstract void onCallDetailsChanged(@NonNull android.telecom.Call.Details details);
+
+ /**
+ * The {@link CallDiagnosticService} implements this method to handle messages received via
+ * device to device communication.
+ * <p>
+ * See {@link #sendDeviceToDeviceMessage(int, int)} for background on device to device
+ * communication.
+ * <p>
+ * The underlying device to device communication protocol assumes that where there the two
+ * devices communicating are using a different version of the protocol, messages the recipient
+ * are not aware of are silently discarded. This means an older client talking to a new client
+ * will not receive newer messages and values sent by the new client.
+ * <p>
+ * Calls to this method will use the same {@link Executor} as the {@link CallDiagnosticService};
+ * see {@link CallDiagnosticService#getExecutor()} for more information.
+ */
+ public abstract void onReceiveDeviceToDeviceMessage(
+ @MessageType int message,
+ int value);
+
+ /**
+ * Sends a device to device message to the device on the other end of this call.
+ * <p>
+ * Device to device communication is an Android platform feature which supports low bandwidth
+ * communication between Android devices while they are in a call. The device to device
+ * communication leverages DTMF tones or RTP header extensions to pass messages. The
+ * messages are unacknowledged and sent in a best-effort manner. The protocols assume that the
+ * nature of the message are informational only and are used only to convey basic state
+ * information between devices.
+ * <p>
+ * Device to device messages are intentional simplifications of more rich indicators in the
+ * platform due to the extreme bandwidth constraints inherent with underlying device to device
+ * communication transports used by the telephony framework. Device to device communication is
+ * either accomplished by adding RFC8285 compliant RTP header extensions to the audio packets
+ * for a call, or using the DTMF digits A-D as a communication pathway. RTP header extension
+ * packets ride alongside a the audio for a call, and are thus limited to roughly a byte for
+ * a message. Signalling requirements for DTMF digits place even more significant limitations
+ * on the amount of information which can be communicated during a call, offering only a few
+ * bits of potential information per message. The messages and values are constrained in order
+ * to meet the limited bandwidth inherent with DTMF signalling.
+ * <p>
+ * Allowed message types are:
+ * <ul>
+ * <li>{@link #MESSAGE_CALL_NETWORK_TYPE}</LI>
+ * <li>{@link #MESSAGE_CALL_AUDIO_CODEC}</LI>
+ * <li>{@link #MESSAGE_DEVICE_BATTERY_STATE}</LI>
+ * <li>{@link #MESSAGE_DEVICE_NETWORK_COVERAGE}</LI>
+ * </ul>
+ * @param message The message type to send.
+ * @param value The message value corresponding to the type.
+ */
+ public final void sendDeviceToDeviceMessage(int message, int value) {
+ if (mListener != null) {
+ mListener.onSendDeviceToDeviceMessage(this, message, value);
+ }
+ }
+
+ /**
+ * Telecom calls this method when a GSM or CDMA call disconnects.
+ * The CallDiagnosticService can return a human readable disconnect message which will be passed
+ * to the Dialer app as the {@link DisconnectCause#getDescription()}. A dialer app typically
+ * shows this message at the termination of the call. If {@code null} is returned, the
+ * disconnect message generated by the telephony stack will be shown instead.
+ * <p>
+ * @param disconnectCause the disconnect cause for the call.
+ * @param preciseDisconnectCause the precise disconnect cause for the call.
+ * @return the disconnect message to use in place of the default Telephony message, or
+ * {@code null} if the default message will not be overridden.
+ * <p>
+ * Calls to this method will use the same {@link Executor} as the {@link CallDiagnosticService};
+ * see {@link CallDiagnosticService#getExecutor()} for more information.
+ */
+ // TODO: Wire in Telephony support for this.
+ public abstract @Nullable CharSequence onCallDisconnected(
+ @Annotation.DisconnectCauses int disconnectCause,
+ @Annotation.PreciseDisconnectCauses int preciseDisconnectCause);
+
+ /**
+ * Telecom calls this method when an IMS call disconnects and Telephony has already
+ * provided the disconnect reason info and disconnect message for the call. The
+ * {@link CallDiagnosticService} can intercept the raw IMS disconnect reason at this point and
+ * combine it with other call diagnostic information it is aware of to override the disconnect
+ * call message if desired.
+ *
+ * @param disconnectReason The {@link ImsReasonInfo} associated with the call disconnection.
+ * @return A user-readable call disconnect message to use in place of the platform-generated
+ * disconnect message, or {@code null} if the disconnect message should not be overridden.
+ * <p>
+ * Calls to this method will use the same {@link Executor} as the {@link CallDiagnosticService};
+ * see {@link CallDiagnosticService#getExecutor()} for more information.
+ */
+ // TODO: Wire in Telephony support for this.
+ public abstract @Nullable CharSequence onCallDisconnected(
+ @NonNull ImsReasonInfo disconnectReason);
+
+ /**
+ * Telecom calls this method when a {@link CallQuality} report is received from the telephony
+ * stack for a call.
+ * @param callQuality The call quality report for this call.
+ * <p>
+ * Calls to this method will use the same {@link Executor} as the {@link CallDiagnosticService};
+ * see {@link CallDiagnosticService#getExecutor()} for more information.
+ */
+ public abstract void onCallQualityReceived(@NonNull CallQuality callQuality);
+
+ /**
+ * Signals the active default dialer app to display a call diagnostic message. This can be
+ * used to report problems encountered during the span of a call.
+ * <p>
+ * The {@link CallDiagnosticService} provides a unique client-specific identifier used to
+ * identify the specific diagnostic message type.
+ * <p>
+ * The {@link CallDiagnosticService} should call {@link #clearDiagnosticMessage(int)} when the
+ * diagnostic condition has cleared.
+ * @param messageId the unique message identifier.
+ * @param message a human-readable, localized message to be shown to the user indicating a
+ * call issue which has occurred, along with potential mitigating actions.
+ */
+ public final void displayDiagnosticMessage(int messageId, @NonNull
+ CharSequence message) {
+ if (mListener != null) {
+ mListener.onDisplayDiagnosticMessage(this, messageId, message);
+ }
+ }
+
+ /**
+ * Signals to the active default dialer that the diagnostic message previously signalled using
+ * {@link #displayDiagnosticMessage(int, CharSequence)} with the specified messageId is no
+ * longer applicable (e.g. service has improved, for example.
+ * @param messageId the message identifier for a message previously shown via
+ * {@link #displayDiagnosticMessage(int, CharSequence)}.
+ */
+ public final void clearDiagnosticMessage(int messageId) {
+ if (mListener != null) {
+ mListener.onClearDiagnosticMessage(this, messageId);
+ }
+ }
+
+ /**
+ * Called by the {@link CallDiagnosticService} to update the call details for this
+ * {@link CallDiagnostics} based on an update received from Telecom.
+ * @param newDetails the new call details.
+ * @hide
+ */
+ public void handleCallUpdated(@NonNull Call.Details newDetails) {
+ onCallDetailsChanged(newDetails);
+ }
+}
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index dc2fb948fdbe..f84dd7b0bb17 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -338,7 +338,7 @@ public abstract class Conference extends Conferenceable {
*
* @param videoState The video state in which to answer the connection.
*/
- public void onAnswer(int videoState) {}
+ public void onAnswer(@VideoProfile.VideoState int videoState) {}
/**
* Notifies this Conference, which is in {@code STATE_RINGING}, of
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 784a3af75f03..49e89d6fbf40 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -44,6 +44,7 @@ import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.telephony.CallQuality;
import android.telephony.ims.ImsStreamMediaProfile;
import android.util.ArraySet;
import android.view.Surface;
@@ -963,7 +964,7 @@ public abstract class Connection extends Conferenceable {
* {@link CallDiagnosticService} implementation which is active.
* <p>
* Likewise, if a {@link CallDiagnosticService} sends a message using
- * {@link DiagnosticCall#sendDeviceToDeviceMessage(int, int)}, it will be routed to telephony
+ * {@link CallDiagnostics#sendDeviceToDeviceMessage(int, int)}, it will be routed to telephony
* via {@link Connection#onCallEvent(String, Bundle)}. The telephony stack will relay the
* message to the other device.
* @hide
@@ -976,7 +977,7 @@ public abstract class Connection extends Conferenceable {
* Sent along with {@link #EVENT_DEVICE_TO_DEVICE_MESSAGE} to indicate the device to device
* message type.
*
- * See {@link DiagnosticCall} for more information.
+ * See {@link CallDiagnostics} for more information.
* @hide
*/
@SystemApi
@@ -987,13 +988,30 @@ public abstract class Connection extends Conferenceable {
* Sent along with {@link #EVENT_DEVICE_TO_DEVICE_MESSAGE} to indicate the device to device
* message value.
* <p>
- * See {@link DiagnosticCall} for more information.
+ * See {@link CallDiagnostics} for more information.
* @hide
*/
@SystemApi
public static final String EXTRA_DEVICE_TO_DEVICE_MESSAGE_VALUE =
"android.telecom.extra.DEVICE_TO_DEVICE_MESSAGE_VALUE";
+ /**
+ * Connection event used to communicate a {@link android.telephony.CallQuality} report from
+ * telephony to Telecom for relaying to
+ * {@link DiagnosticCall#onCallQualityReceived(CallQuality)}.
+ * @hide
+ */
+ public static final String EVENT_CALL_QUALITY_REPORT =
+ "android.telecom.event.CALL_QUALITY_REPORT";
+
+ /**
+ * Extra sent with {@link #EVENT_CALL_QUALITY_REPORT} containing the
+ * {@link android.telephony.CallQuality} data.
+ * @hide
+ */
+ public static final String EXTRA_CALL_QUALITY_REPORT =
+ "android.telecom.extra.CALL_QUALITY_REPORT";
+
// Flag controlling whether PII is emitted into the logs
private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index bf4d9fb1f6c8..b60f923d7bc7 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -2598,9 +2598,9 @@ public abstract class ConnectionService extends Service {
* @return The {@code Connection} object to satisfy this call, or {@code null} to
* not handle the call.
*/
- public final RemoteConnection createRemoteIncomingConnection(
- PhoneAccountHandle connectionManagerPhoneAccount,
- ConnectionRequest request) {
+ public final @Nullable RemoteConnection createRemoteIncomingConnection(
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
return mRemoteConnectionManager.createRemoteConnection(
connectionManagerPhoneAccount, request, true);
}
@@ -2617,9 +2617,9 @@ public abstract class ConnectionService extends Service {
* @return The {@code Connection} object to satisfy this call, or {@code null} to
* not handle the call.
*/
- public final RemoteConnection createRemoteOutgoingConnection(
- PhoneAccountHandle connectionManagerPhoneAccount,
- ConnectionRequest request) {
+ public final @Nullable RemoteConnection createRemoteOutgoingConnection(
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
return mRemoteConnectionManager.createRemoteConnection(
connectionManagerPhoneAccount, request, false);
}
@@ -2859,12 +2859,14 @@ public abstract class ConnectionService extends Service {
* @param connectionManagerPhoneAccount See description at
* {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
* @param request Details about the incoming conference call.
- * @return The {@code Conference} object to satisfy this call, or {@code null} to
- * not handle the call.
+ * @return The {@code Conference} object to satisfy this call. If the conference attempt is
+ * failed, the return value will be a result of an invocation of
+ * {@link Connection#createFailedConnection(DisconnectCause)}.
+ * Return {@code null} if the {@link ConnectionService} cannot handle the call.
*/
public @Nullable Conference onCreateIncomingConference(
- @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
- @Nullable ConnectionRequest request) {
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
return null;
}
@@ -2967,8 +2969,8 @@ public abstract class ConnectionService extends Service {
* @param request The outgoing connection request.
*/
public void onCreateOutgoingConferenceFailed(
- @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
- @Nullable ConnectionRequest request) {
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
}
@@ -3032,12 +3034,14 @@ public abstract class ConnectionService extends Service {
* a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
* making the connection.
* @param request Details about the outgoing call.
- * @return The {@code Conference} object to satisfy this call, or the result of an invocation
- * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
+ * @return The {@code Conference} object to satisfy this call. If the conference attempt is
+ * failed, the return value will be a result of an invocation of
+ * {@link Connection#createFailedConnection(DisconnectCause)}.
+ * Return {@code null} if the {@link ConnectionService} cannot handle the call.
*/
public @Nullable Conference onCreateOutgoingConference(
- @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
- @Nullable ConnectionRequest request) {
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
return null;
}
diff --git a/telecomm/java/android/telecom/DiagnosticCall.java b/telecomm/java/android/telecom/DiagnosticCall.java
index a4952899eb46..a6b7258052a4 100644
--- a/telecomm/java/android/telecom/DiagnosticCall.java
+++ b/telecomm/java/android/telecom/DiagnosticCall.java
@@ -16,366 +16,12 @@
package android.telecom;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.telephony.Annotation;
-import android.telephony.CallQuality;
-import android.telephony.ims.ImsReasonInfo;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
/**
- * A {@link DiagnosticCall} provides a way for a {@link CallDiagnosticService} to receive diagnostic
- * information about a mobile call on the device. The {@link CallDiagnosticService} can generate
- * mid-call diagnostic messages using the {@link #displayDiagnosticMessage(int, CharSequence)} API
- * which provides the user with valuable information about conditions impacting their call and
- * corrective actions. For example, if the {@link CallDiagnosticService} determines that conditions
- * on the call are degrading, it can inform the user that the call may soon drop and that they
- * can try using a different calling method (e.g. VOIP or WIFI).
+ * @deprecated use {@link CallDiagnostics} instead.
* @hide
*/
@SystemApi
-public abstract class DiagnosticCall {
-
- /**
- * @hide
- */
- public interface Listener {
- void onSendDeviceToDeviceMessage(DiagnosticCall diagnosticCall, int message, int value);
- void onDisplayDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId,
- CharSequence message);
- void onClearDiagnosticMessage(DiagnosticCall diagnosticCall, int messageId);
- }
-
- /**
- * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via
- * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the radio access type
- * used for the current call. Based loosely on the
- * {@link android.telephony.TelephonyManager#getNetworkType(int)} for the call, provides a
- * high level summary of the call radio access type.
- * <p>
- * Valid values:
- * <UL>
- * <LI>{@link #NETWORK_TYPE_LTE}</LI>
- * <LI>{@link #NETWORK_TYPE_IWLAN}</LI>
- * <LI>{@link #NETWORK_TYPE_NR}</LI>
- * </UL>
- */
- public static final int MESSAGE_CALL_NETWORK_TYPE = 1;
-
- /**
- * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via
- * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the call audio codec
- * used for the current call. Based loosely on the {@link Connection#EXTRA_AUDIO_CODEC} for a
- * call.
- * <p>
- * Valid values:
- * <UL>
- * <LI>{@link #AUDIO_CODEC_EVS}</LI>
- * <LI>{@link #AUDIO_CODEC_AMR_WB}</LI>
- * <LI>{@link #AUDIO_CODEC_AMR_NB}</LI>
- * </UL>
- */
- public static final int MESSAGE_CALL_AUDIO_CODEC = 2;
-
- /**
- * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via
- * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the battery state of
- * the device. Will typically mirror battery state reported via intents such as
- * {@link android.content.Intent#ACTION_BATTERY_LOW}.
- * <p>
- * Valid values:
- * <UL>
- * <LI>{@link #BATTERY_STATE_LOW}</LI>
- * <LI>{@link #BATTERY_STATE_GOOD}</LI>
- * <LI>{@link #BATTERY_STATE_CHARGING}</LI>
- * </UL>
- */
- public static final int MESSAGE_DEVICE_BATTERY_STATE = 3;
-
- /**
- * Device to device message sent via {@link #sendDeviceToDeviceMessage(int, int)} (received via
- * {@link #onReceiveDeviceToDeviceMessage(int, int)}) which communicates the overall network
- * coverage as it pertains to the current call. A {@link CallDiagnosticService} should signal
- * poor coverage if the network coverage reaches a level where there is a high probability of
- * the call dropping as a result.
- * <p>
- * Valid values:
- * <UL>
- * <LI>{@link #COVERAGE_POOR}</LI>
- * <LI>{@link #COVERAGE_GOOD}</LI>
- * </UL>
- */
- public static final int MESSAGE_DEVICE_NETWORK_COVERAGE = 4;
-
- /**@hide*/
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = "MESSAGE_", value = {
- MESSAGE_CALL_NETWORK_TYPE,
- MESSAGE_CALL_AUDIO_CODEC,
- MESSAGE_DEVICE_BATTERY_STATE,
- MESSAGE_DEVICE_NETWORK_COVERAGE
- })
- public @interface MessageType {}
-
- /**
- * Used with {@link #MESSAGE_CALL_NETWORK_TYPE} to indicate an LTE network is being used for the
- * call.
- */
- public static final int NETWORK_TYPE_LTE = 1;
-
- /**
- * Used with {@link #MESSAGE_CALL_NETWORK_TYPE} to indicate WIFI calling is in use for the call.
- */
- public static final int NETWORK_TYPE_IWLAN = 2;
-
- /**
- * Used with {@link #MESSAGE_CALL_NETWORK_TYPE} to indicate a 5G NR (new radio) network is in
- * used for the call.
- */
- public static final int NETWORK_TYPE_NR = 3;
-
- /**
- * Used with {@link #MESSAGE_CALL_AUDIO_CODEC} to indicate call audio is using the
- * Enhanced Voice Services (EVS) codec for the call.
- */
- public static final int AUDIO_CODEC_EVS = 1;
-
- /**
- * Used with {@link #MESSAGE_CALL_AUDIO_CODEC} to indicate call audio is using the AMR
- * (adaptive multi-rate) WB (wide band) audio codec.
- */
- public static final int AUDIO_CODEC_AMR_WB = 2;
-
- /**
- * Used with {@link #MESSAGE_CALL_AUDIO_CODEC} to indicate call audio is using the AMR
- * (adaptive multi-rate) NB (narrow band) audio codec.
- */
- public static final int AUDIO_CODEC_AMR_NB = 3;
-
- /**
- * Used with {@link #MESSAGE_DEVICE_BATTERY_STATE} to indicate that the battery is low.
- */
- public static final int BATTERY_STATE_LOW = 1;
-
- /**
- * Used with {@link #MESSAGE_DEVICE_BATTERY_STATE} to indicate that the battery is not low.
- */
- public static final int BATTERY_STATE_GOOD = 2;
-
- /**
- * Used with {@link #MESSAGE_DEVICE_BATTERY_STATE} to indicate that the battery is charging.
- */
- public static final int BATTERY_STATE_CHARGING = 3;
-
- /**
- * Used with {@link #MESSAGE_DEVICE_NETWORK_COVERAGE} to indicate that the coverage is poor.
- */
- public static final int COVERAGE_POOR = 1;
-
- /**
- * Used with {@link #MESSAGE_DEVICE_NETWORK_COVERAGE} to indicate that the coverage is good.
- */
- public static final int COVERAGE_GOOD = 2;
-
- private Listener mListener;
- private String mCallId;
- private Call.Details mCallDetails;
-
- /**
- * @hide
- */
- public void setListener(@NonNull Listener listener) {
- mListener = listener;
- }
-
- /**
- * Sets the call ID for this {@link DiagnosticCall}.
- * @param callId
- * @hide
- */
- public void setCallId(@NonNull String callId) {
- mCallId = callId;
- }
-
- /**
- * @return the Telecom call ID for this {@link DiagnosticCall}.
- * @hide
- */
- public @NonNull String getCallId() {
- return mCallId;
- }
-
- /**
- * Returns the latest {@link Call.Details} associated with this {@link DiagnosticCall} as
- * reported by {@link #onCallDetailsChanged(Call.Details)}.
- * @return The latest {@link Call.Details}.
- */
- public @NonNull Call.Details getCallDetails() {
- return mCallDetails;
- }
-
- /**
- * Telecom calls this method when the details of a call changes.
- */
- public abstract void onCallDetailsChanged(@NonNull android.telecom.Call.Details details);
-
- /**
- * The {@link CallDiagnosticService} implements this method to handle messages received via
- * device to device communication.
- * <p>
- * See {@link #sendDeviceToDeviceMessage(int, int)} for background on device to device
- * communication.
- * <p>
- * The underlying device to device communication protocol assumes that where there the two
- * devices communicating are using a different version of the protocol, messages the recipient
- * are not aware of are silently discarded. This means an older client talking to a new client
- * will not receive newer messages and values sent by the new client.
- */
- public abstract void onReceiveDeviceToDeviceMessage(
- @MessageType int message,
- int value);
-
- /**
- * Sends a device to device message to the device on the other end of this call.
- * <p>
- * Device to device communication is an Android platform feature which supports low bandwidth
- * communication between Android devices while they are in a call. The device to device
- * communication leverages DTMF tones or RTP header extensions to pass messages. The
- * messages are unacknowledged and sent in a best-effort manner. The protocols assume that the
- * nature of the message are informational only and are used only to convey basic state
- * information between devices.
- * <p>
- * Device to device messages are intentional simplifications of more rich indicators in the
- * platform due to the extreme bandwidth constraints inherent with underlying device to device
- * communication transports used by the telephony framework. Device to device communication is
- * either accomplished by adding RFC8285 compliant RTP header extensions to the audio packets
- * for a call, or using the DTMF digits A-D as a communication pathway. Signalling requirements
- * for DTMF digits place a significant limitation on the amount of information which can be
- * communicated during a call.
- * <p>
- * Allowed message types and values are:
- * <ul>
- * <li>{@link #MESSAGE_CALL_NETWORK_TYPE}
- * <ul>
- * <li>{@link #NETWORK_TYPE_LTE}</li>
- * <li>{@link #NETWORK_TYPE_IWLAN}</li>
- * <li>{@link #NETWORK_TYPE_NR}</li>
- * </ul>
- * </li>
- * <li>{@link #MESSAGE_CALL_AUDIO_CODEC}
- * <ul>
- * <li>{@link #AUDIO_CODEC_EVS}</li>
- * <li>{@link #AUDIO_CODEC_AMR_WB}</li>
- * <li>{@link #AUDIO_CODEC_AMR_NB}</li>
- * </ul>
- * </li>
- * <li>{@link #MESSAGE_DEVICE_BATTERY_STATE}
- * <ul>
- * <li>{@link #BATTERY_STATE_LOW}</li>
- * <li>{@link #BATTERY_STATE_GOOD}</li>
- * <li>{@link #BATTERY_STATE_CHARGING}</li>
- * </ul>
- * </li>
- * <li>{@link #MESSAGE_DEVICE_NETWORK_COVERAGE}
- * <ul>
- * <li>{@link #COVERAGE_POOR}</li>
- * <li>{@link #COVERAGE_GOOD}</li>
- * </ul>
- * </li>
- * </ul>
- * @param message The message type to send.
- * @param value The message value corresponding to the type.
- */
- public final void sendDeviceToDeviceMessage(int message, int value) {
- if (mListener != null) {
- mListener.onSendDeviceToDeviceMessage(this, message, value);
- }
- }
-
- /**
- * Telecom calls this method when a GSM or CDMA call disconnects.
- * The CallDiagnosticService can return a human readable disconnect message which will be passed
- * to the Dialer app as the {@link DisconnectCause#getDescription()}. A dialer app typically
- * shows this message at the termination of the call. If {@code null} is returned, the
- * disconnect message generated by the telephony stack will be shown instead.
- * <p>
- * @param disconnectCause the disconnect cause for the call.
- * @param preciseDisconnectCause the precise disconnect cause for the call.
- * @return the disconnect message to use in place of the default Telephony message, or
- * {@code null} if the default message will not be overridden.
- */
- // TODO: Wire in Telephony support for this.
- public abstract @Nullable CharSequence onCallDisconnected(
- @Annotation.DisconnectCauses int disconnectCause,
- @Annotation.PreciseDisconnectCauses int preciseDisconnectCause);
-
- /**
- * Telecom calls this method when an IMS call disconnects and Telephony has already
- * provided the disconnect reason info and disconnect message for the call. The
- * {@link CallDiagnosticService} can intercept the raw IMS disconnect reason at this point and
- * combine it with other call diagnostic information it is aware of to override the disconnect
- * call message if desired.
- *
- * @param disconnectReason The {@link ImsReasonInfo} associated with the call disconnection.
- * @return A user-readable call disconnect message to use in place of the platform-generated
- * disconnect message, or {@code null} if the disconnect message should not be overridden.
- */
- // TODO: Wire in Telephony support for this.
- public abstract @Nullable CharSequence onCallDisconnected(
- @NonNull ImsReasonInfo disconnectReason);
-
- /**
- * Telecom calls this method when a {@link CallQuality} report is received from the telephony
- * stack for a call.
- * @param callQuality The call quality report for this call.
- */
- public abstract void onCallQualityReceived(@NonNull CallQuality callQuality);
-
- /**
- * Signals the active default dialer app to display a call diagnostic message. This can be
- * used to report problems encountered during the span of a call.
- * <p>
- * The {@link CallDiagnosticService} provides a unique client-specific identifier used to
- * identify the specific diagnostic message type.
- * <p>
- * The {@link CallDiagnosticService} should call {@link #clearDiagnosticMessage(int)} when the
- * diagnostic condition has cleared.
- * @param messageId the unique message identifier.
- * @param message a human-readable, localized message to be shown to the user indicating a
- * call issue which has occurred, along with potential mitigating actions.
- */
- public final void displayDiagnosticMessage(int messageId, @NonNull
- CharSequence message) {
- if (mListener != null) {
- mListener.onDisplayDiagnosticMessage(this, messageId, message);
- }
- }
-
- /**
- * Signals to the active default dialer that the diagnostic message previously signalled using
- * {@link #displayDiagnosticMessage(int, CharSequence)} with the specified messageId is no
- * longer applicable (e.g. service has improved, for example.
- * @param messageId the message identifier for a message previously shown via
- * {@link #displayDiagnosticMessage(int, CharSequence)}.
- */
- public final void clearDiagnosticMessage(int messageId) {
- if (mListener != null) {
- mListener.onClearDiagnosticMessage(this, messageId);
- }
- }
-
- /**
- * Called by the {@link CallDiagnosticService} to update the call details for this
- * {@link DiagnosticCall} based on an update received from Telecom.
- * @param newDetails the new call details.
- * @hide
- */
- public void handleCallUpdated(@NonNull Call.Details newDetails) {
- mCallDetails = newDetails;
- onCallDetailsChanged(newDetails);
- }
+public abstract class DiagnosticCall extends CallDiagnostics {
}
diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java
index 1472a4ac27bc..ed7b79f62753 100644
--- a/telecomm/java/android/telecom/DisconnectCause.java
+++ b/telecomm/java/android/telecom/DisconnectCause.java
@@ -16,9 +16,13 @@
package android.telecom;
+import android.annotation.Nullable;
import android.media.ToneGenerator;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.Annotation;
+import android.telephony.PreciseDisconnectCause;
+import android.telephony.ims.ImsReasonInfo;
import android.text.TextUtils;
import java.util.Objects;
@@ -112,6 +116,9 @@ public final class DisconnectCause implements Parcelable {
private CharSequence mDisconnectDescription;
private String mDisconnectReason;
private int mToneToPlay;
+ private int mTelephonyDisconnectCause;
+ private int mTelephonyPreciseDisconnectCause;
+ private ImsReasonInfo mImsReasonInfo;
/**
* Creates a new DisconnectCause.
@@ -155,11 +162,36 @@ public final class DisconnectCause implements Parcelable {
*/
public DisconnectCause(int code, CharSequence label, CharSequence description, String reason,
int toneToPlay) {
+ this(code, label, description, reason, toneToPlay,
+ android.telephony.DisconnectCause.ERROR_UNSPECIFIED,
+ PreciseDisconnectCause.ERROR_UNSPECIFIED,
+ null /* imsReasonInfo */);
+ }
+
+ /**
+ * Creates a new DisconnectCause instance.
+ * @param code The code for the disconnect cause.
+ * @param label The localized label to show to the user to explain the disconnect.
+ * @param description The localized description to show to the user to explain the disconnect.
+ * @param reason The reason for the disconnect.
+ * @param toneToPlay The tone to play on disconnect, as defined in {@link ToneGenerator}.
+ * @param telephonyDisconnectCause The Telephony disconnect cause.
+ * @param telephonyPreciseDisconnectCause The Telephony precise disconnect cause.
+ * @param imsReasonInfo The relevant {@link ImsReasonInfo}, or {@code null} if not available.
+ * @hide
+ */
+ public DisconnectCause(int code, CharSequence label, CharSequence description, String reason,
+ int toneToPlay, @Annotation.DisconnectCauses int telephonyDisconnectCause,
+ @Annotation.PreciseDisconnectCauses int telephonyPreciseDisconnectCause,
+ @Nullable ImsReasonInfo imsReasonInfo) {
mDisconnectCode = code;
mDisconnectLabel = label;
mDisconnectDescription = description;
mDisconnectReason = reason;
mToneToPlay = toneToPlay;
+ mTelephonyDisconnectCause = telephonyDisconnectCause;
+ mTelephonyPreciseDisconnectCause = telephonyPreciseDisconnectCause;
+ mImsReasonInfo = imsReasonInfo;
}
/**
@@ -209,6 +241,33 @@ public final class DisconnectCause implements Parcelable {
}
/**
+ * Returns the telephony {@link android.telephony.DisconnectCause} for the call.
+ * @return The disconnect cause.
+ * @hide
+ */
+ public @Annotation.DisconnectCauses int getTelephonyDisconnectCause() {
+ return mTelephonyDisconnectCause;
+ }
+
+ /**
+ * Returns the telephony {@link android.telephony.PreciseDisconnectCause} for the call.
+ * @return The precise disconnect cause.
+ * @hide
+ */
+ public @Annotation.PreciseDisconnectCauses int getTelephonyPreciseDisconnectCause() {
+ return mTelephonyPreciseDisconnectCause;
+ }
+
+ /**
+ * Returns the telephony {@link ImsReasonInfo} associated with the call disconnection.
+ * @return The {@link ImsReasonInfo} or {@code null} if not known.
+ * @hide
+ */
+ public @Nullable ImsReasonInfo getImsReasonInfo() {
+ return mImsReasonInfo;
+ }
+
+ /**
* Returns the tone to play when disconnected.
*
* @return the tone as defined in {@link ToneGenerator} to play when disconnected.
@@ -217,7 +276,8 @@ public final class DisconnectCause implements Parcelable {
return mToneToPlay;
}
- public static final @android.annotation.NonNull Creator<DisconnectCause> CREATOR = new Creator<DisconnectCause>() {
+ public static final @android.annotation.NonNull Creator<DisconnectCause> CREATOR
+ = new Creator<DisconnectCause>() {
@Override
public DisconnectCause createFromParcel(Parcel source) {
int code = source.readInt();
@@ -225,7 +285,11 @@ public final class DisconnectCause implements Parcelable {
CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
String reason = source.readString();
int tone = source.readInt();
- return new DisconnectCause(code, label, description, reason, tone);
+ int telephonyDisconnectCause = source.readInt();
+ int telephonyPreciseDisconnectCause = source.readInt();
+ ImsReasonInfo imsReasonInfo = source.readParcelable(null);
+ return new DisconnectCause(code, label, description, reason, tone,
+ telephonyDisconnectCause, telephonyPreciseDisconnectCause, imsReasonInfo);
}
@Override
@@ -241,6 +305,9 @@ public final class DisconnectCause implements Parcelable {
TextUtils.writeToParcel(mDisconnectDescription, destination, flags);
destination.writeString(mDisconnectReason);
destination.writeInt(mToneToPlay);
+ destination.writeInt(mTelephonyDisconnectCause);
+ destination.writeInt(mTelephonyPreciseDisconnectCause);
+ destination.writeParcelable(mImsReasonInfo, 0);
}
@Override
@@ -254,7 +321,10 @@ public final class DisconnectCause implements Parcelable {
+ Objects.hashCode(mDisconnectLabel)
+ Objects.hashCode(mDisconnectDescription)
+ Objects.hashCode(mDisconnectReason)
- + Objects.hashCode(mToneToPlay);
+ + Objects.hashCode(mToneToPlay)
+ + Objects.hashCode(mTelephonyDisconnectCause)
+ + Objects.hashCode(mTelephonyPreciseDisconnectCause)
+ + Objects.hashCode(mImsReasonInfo);
}
@Override
@@ -265,7 +335,11 @@ public final class DisconnectCause implements Parcelable {
&& Objects.equals(mDisconnectLabel, d.getLabel())
&& Objects.equals(mDisconnectDescription, d.getDescription())
&& Objects.equals(mDisconnectReason, d.getReason())
- && Objects.equals(mToneToPlay, d.getTone());
+ && Objects.equals(mToneToPlay, d.getTone())
+ && Objects.equals(mTelephonyDisconnectCause, d.getTelephonyDisconnectCause())
+ && Objects.equals(mTelephonyPreciseDisconnectCause,
+ d.getTelephonyPreciseDisconnectCause())
+ && Objects.equals(mImsReasonInfo, d.getImsReasonInfo());
}
return false;
}
@@ -325,6 +399,11 @@ public final class DisconnectCause implements Parcelable {
+ " Label: (" + label + ")"
+ " Description: (" + description + ")"
+ " Reason: (" + reason + ")"
- + " Tone: (" + mToneToPlay + ") ]";
+ + " Tone: (" + mToneToPlay + ") "
+ + " TelephonyCause: " + mTelephonyDisconnectCause + "/"
+ + mTelephonyPreciseDisconnectCause
+ + " ImsReasonInfo: "
+ + mImsReasonInfo
+ + "]";
}
}
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 182dc8bb8325..320308c9e926 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -399,7 +399,7 @@ public final class ParcelableCall implements Parcelable {
}
/** The current state of the call. */
- public int getState() {
+ public @Call.CallState int getState() {
return mState;
}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 99e4571e937c..3421c6311c11 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -325,8 +325,8 @@ public class TelecomManager {
public static final String EXTRA_HAS_PICTURE = "android.telecom.extra.HAS_PICTURE";
/**
- * A URI representing the picture that was downloaded when a call is received or uploaded
- * when a call is placed.
+ * A {@link Uri} representing the picture that was downloaded when a call is received or
+ * uploaded when a call is placed.
*
* This is a content URI within the call log provider which can be used to open a file
* descriptor. This could be set a short time after a call is added to the Dialer app if the
diff --git a/telecomm/java/com/android/internal/telecom/ICallDiagnosticService.aidl b/telecomm/java/com/android/internal/telecom/ICallDiagnosticService.aidl
index 65b4d19b3d9b..4bd369f2c556 100644
--- a/telecomm/java/com/android/internal/telecom/ICallDiagnosticService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallDiagnosticService.aidl
@@ -18,7 +18,9 @@ package com.android.internal.telecom;
import android.telecom.BluetoothCallQualityReport;
import android.telecom.CallAudioState;
+import android.telecom.DisconnectCause;
import android.telecom.ParcelableCall;
+import android.telephony.CallQuality;
import com.android.internal.telecom.ICallDiagnosticServiceAdapter;
/**
@@ -33,5 +35,7 @@ oneway interface ICallDiagnosticService {
void updateCallAudioState(in CallAudioState callAudioState);
void removeDiagnosticCall(in String callId);
void receiveDeviceToDeviceMessage(in String callId, int message, int value);
+ void callQualityChanged(in String callId, in CallQuality callQuality);
void receiveBluetoothCallQualityReport(in BluetoothCallQualityReport qualityReport);
+ void notifyCallDisconnected(in String callId, in DisconnectCause disconnectCause);
}