Loading src/com/android/server/telecom/Call.java +103 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.provider.CallLog; import android.provider.ContactsContract.Contacts; import android.telecom.BluetoothCallQualityReport; import android.telecom.CallAudioState; import android.telecom.CallDiagnosticService; import android.telecom.CallerInfo; import android.telecom.Conference; import android.telecom.Connection; Loading @@ -60,6 +61,7 @@ import android.telecom.VideoProfile; import android.telephony.PhoneNumberUtils; import android.telephony.TelephonyManager; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; import android.text.TextUtils; import android.util.ArrayMap; import android.widget.Toast; Loading @@ -81,7 +83,9 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** * Encapsulates all aspects of a given phone call throughout its lifecycle, starting Loading Loading @@ -661,6 +665,22 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, */ private boolean mIsSimCall; /** * Set to {@code true} if we received a valid response ({@code null} or otherwise) from * the {@link DiagnosticCall#onCallDisconnected(ImsReasonInfo)} or * {@link DiagnosticCall#onCallDisconnected(int, int)} calls. This is used to detect a timeout * when awaiting a response from the call diagnostic service. */ private boolean mReceivedCallDiagnosticPostCallResponse = false; /** * {@link CompletableFuture} used to delay posting disconnection and removal to a call until * after a {@link CallDiagnosticService} is able to handle the disconnection and provide a * disconnect message via {@link DiagnosticCall#onCallDisconnected(ImsReasonInfo)} or * {@link DiagnosticCall#onCallDisconnected(int, int)}. */ private CompletableFuture<Boolean> mDisconnectFuture; /** * Persists the specified parameters and initializes the new instance. * @param context The context. Loading Loading @@ -1092,8 +1112,29 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, } } /** * Handles an incoming overridden disconnect message for this call. * * We only care if the disconnect is handled via a future. * @param message the overridden disconnect message. */ public void handleOverrideDisconnectMessage(@Nullable CharSequence message) { Log.i(this, "handleOverrideDisconnectMessage; callid=%s, msg=%s", getId(), message); if (isDisconnectHandledViaFuture()) { mReceivedCallDiagnosticPostCallResponse = true; if (message != null) { Log.addEvent(this, LogUtils.Events.OVERRIDE_DISCONNECT_MESSAGE, message); // Replace the existing disconnect cause in this call setOverrideDisconnectCauseCode(new DisconnectCause(DisconnectCause.ERROR, message, message, null)); } mDisconnectFuture.complete(true); } else { Log.w(this, "handleOverrideDisconnectMessage; callid=%s - got override when unbound", getId()); } } /** Loading Loading @@ -4088,4 +4129,66 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, public boolean isSimCall() { return mIsSimCall; } /** * Sets whether this is a sim call or not. * @param isSimCall {@code true} if this is a SIM call, {@code false} otherwise. */ public void setIsSimCall(boolean isSimCall) { mIsSimCall = isSimCall; } /** * Initializes a disconnect future which is used to chain up pending operations which take * place when the {@link CallDiagnosticService} returns the result of the * {@link DiagnosticCall#onCallDisconnected(int, int)} or * {@link DiagnosticCall#onCallDisconnected(ImsReasonInfo)} invocation via * {@link CallDiagnosticServiceAdapter}. If no {@link CallDiagnosticService} is in use, we * would not try to make a disconnect future. * @param timeoutMillis Timeout we use for waiting for the response. * @return the {@link CompletableFuture}. */ public CompletableFuture<Boolean> initializeDisconnectFuture(long timeoutMillis) { if (mDisconnectFuture == null) { mDisconnectFuture = new CompletableFuture<Boolean>() .completeOnTimeout(false, timeoutMillis, TimeUnit.MILLISECONDS); // After all the chained stuff we will report where the CDS timed out. mDisconnectFuture.thenRunAsync(() -> { if (!mReceivedCallDiagnosticPostCallResponse) { Log.addEvent(this, LogUtils.Events.CALL_DIAGNOSTIC_SERVICE_TIMEOUT); }}, new LoggedHandlerExecutor(mHandler, "C.iDF", mLock)) .exceptionally((throwable) -> { Log.e(this, throwable, "Error while executing disconnect future"); return null; }); } return mDisconnectFuture; } /** * @return the disconnect future, if initialized. Used for chaining operations after creation. */ public CompletableFuture<Boolean> getDisconnectFuture() { return mDisconnectFuture; } /** * @return {@code true} if disconnection and removal is handled via a future, or {@code false} * if this is handled immediately. */ public boolean isDisconnectHandledViaFuture() { return mDisconnectFuture != null && !mDisconnectFuture.isDone(); } /** * Perform any cleanup on this call as a result of a {@link TelecomServiceImpl} * {@code cleanupStuckCalls} request. */ public void cleanup() { if (mDisconnectFuture != null) { mDisconnectFuture.complete(false); mDisconnectFuture = null; } } } src/com/android/server/telecom/CallDiagnosticServiceController.java +28 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.telecom.CallAudioState; import android.telecom.CallDiagnosticService; import android.telecom.ConnectionService; import android.telecom.DiagnosticCall; import android.telecom.DisconnectCause; import android.telecom.InCallService; import android.telecom.Log; import android.telecom.ParcelableCall; Loading Loading @@ -254,6 +255,32 @@ public class CallDiagnosticServiceController extends CallsManagerListenerBase { } } /** * Handles a newly disconnected call signalled from {@link CallsManager}. * @param call The call * @param disconnectCause The disconnect cause * @return {@code true} if the {@link CallDiagnosticService} was sent the call, {@code false} * if the call was not applicable to the CDS or if there was an issue sending it. */ public boolean onCallDisconnected(@NonNull Call call, @NonNull DisconnectCause disconnectCause) { if (!call.isSimCall() || call.isExternalCall()) { Log.i(this, "onCallDisconnected: skipping call %s as non-sim or external.", call.getId()); return false; } String callId = mCallIdMapper.getCallId(call); try { if (isConnected()) { mCallDiagnosticService.notifyCallDisconnected(callId, disconnectCause); return true; } } catch (RemoteException e) { Log.w(this, "onCallDisconnected: callId=%s, exception=%s", call.getId(), e); } return false; } /** * Handles Telecom removal of calls; will remove the call from the bound service and if the * number of tracked calls falls to zero, unbind from the service. Loading Loading @@ -569,7 +596,7 @@ public class CallDiagnosticServiceController extends CallsManagerListenerBase { /** * @return {@code true} if the call diagnostic service is bound/connected. */ private boolean isConnected() { public boolean isConnected() { return mCallDiagnosticService != null; } Loading src/com/android/server/telecom/CallsManager.java +63 −7 Original line number Diff line number Diff line Loading @@ -3099,27 +3099,82 @@ public class CallsManager extends Call.ListenerBase // be marked as missed. call.setOverrideDisconnectCauseCode(new DisconnectCause(DisconnectCause.MISSED)); } // If a call diagnostic service is in use, we will log the original telephony-provided // disconnect cause, inform the CDS of the disconnection, and then chain the update of the // call state until AFTER the CDS reports it's result back. if (oldState == CallState.ACTIVE && disconnectCause.getCode() != DisconnectCause.MISSED && mCallDiagnosticServiceController.isConnected() && mCallDiagnosticServiceController.onCallDisconnected(call, disconnectCause)) { Log.i(this, "markCallAsDisconnected; callid=%s, postingToFuture.", call.getId()); // Log the original disconnect reason prior to calling into the // CallDiagnosticService. Log.addEvent(call, LogUtils.Events.SET_DISCONNECTED_ORIG, disconnectCause); // Setup the future with a timeout so that the CDS is time boxed. CompletableFuture<Boolean> future = call.initializeDisconnectFuture( mTimeoutsAdapter.getCallDiagnosticServiceTimeoutMillis( mContext.getContentResolver())); // Post the disconnection updates to the future for completion once the CDS returns // with it's overridden disconnect message. future.thenRunAsync(() -> { call.setDisconnectCause(disconnectCause); setCallState(call, CallState.DISCONNECTED, "disconnected set explicitly"); }, new LoggedHandlerExecutor(mHandler, "CM.mCAD", mLock)) .exceptionally((throwable) -> { Log.e(TAG, throwable, "Error while executing disconnect future."); return null; }); } else { // No CallDiagnosticService, or it doesn't handle this call, so just do this // synchronously as always. call.setDisconnectCause(disconnectCause); setCallState(call, CallState.DISCONNECTED, "disconnected set explicitly"); } if (oldState == CallState.NEW && disconnectCause.getCode() == DisconnectCause.MISSED) { Log.i(this, "markCallAsDisconnected: logging missed call "); mCallLogManager.logCall(call, Calls.MISSED_TYPE, true, null); } } /** * Removes an existing disconnected call, and notifies the in-call app. */ void markCallAsRemoved(Call call) { if (call.isDisconnectHandledViaFuture()) { Log.i(this, "markCallAsRemoved; callid=%s, postingToFuture.", call.getId()); // A future is being used due to a CallDiagnosticService handling the call. We will // chain the removal operation to the end of any outstanding disconnect work. call.getDisconnectFuture().thenRunAsync(() -> { performRemoval(call); }, new LoggedHandlerExecutor(mHandler, "CM.mCAR", mLock)) .exceptionally((throwable) -> { Log.e(TAG, throwable, "Error while executing disconnect future"); return null; }); } else { Log.i(this, "markCallAsRemoved; callid=%s, immediate.", call.getId()); performRemoval(call); } } /** * Work which is completed when a call is to be removed. Can either be be run synchronously or * posted to a {@link Call#getDisconnectFuture()}. * @param call The call. */ private void performRemoval(Call call) { mInCallController.getBindingFuture().thenRunAsync(() -> { call.maybeCleanupHandover(); removeCall(call); Call foregroundCall = mCallAudioManager.getPossiblyHeldForegroundCall(); if (mLocallyDisconnectingCalls.contains(call)) { boolean isDisconnectingChildCall = call.isDisconnectingChildCall(); Log.v(this, "markCallAsRemoved: isDisconnectingChildCall = " Log.v(this, "performRemoval: isDisconnectingChildCall = " + isDisconnectingChildCall + "call -> %s", call); mLocallyDisconnectingCalls.remove(call); // Auto-unhold the foreground call due to a locally disconnected call, except if the Loading @@ -3136,10 +3191,11 @@ public class CallsManager extends Call.ListenerBase // The new foreground call is on hold, however the carrier does not display the hold // button in the UI. Therefore, we need to auto unhold the held call since the user // has no means of unholding it themselves. Log.i(this, "Auto-unholding held foreground call (call doesn't support hold)"); Log.i(this, "performRemoval: Auto-unholding held foreground call (call doesn't " + "support hold)"); foregroundCall.unhold(); } }, new LoggedHandlerExecutor(mHandler, "CM.mCAR", mLock)) }, new LoggedHandlerExecutor(mHandler, "CM.pR", mLock)) .exceptionally((throwable) -> { Log.e(TAG, throwable, "Error while executing call removal"); return null; Loading src/com/android/server/telecom/ConnectionServiceWrapper.java +1 −1 Original line number Diff line number Diff line Loading @@ -352,7 +352,7 @@ public class ConnectionServiceWrapper extends ServiceBinder implements logIncoming("removeCall %s", callId); Call call = mCallIdMapper.getCall(callId); if (call != null) { if (call.isAlive()) { if (call.isAlive() && !call.isDisconnectHandledViaFuture()) { mCallsManager.markCallAsDisconnected( call, new DisconnectCause(DisconnectCause.REMOTE)); } else { Loading src/com/android/server/telecom/LogUtils.java +4 −0 Original line number Diff line number Diff line Loading @@ -197,6 +197,10 @@ public class LogUtils { public static final String REDIRECTION_USER_CONFIRMED = "REDIRECTION_USER_CONFIRMED"; public static final String REDIRECTION_USER_CANCELLED = "REDIRECTION_USER_CANCELLED"; public static final String BT_QUALITY_REPORT = "BT_QUALITY_REPORT"; public static final String SET_DISCONNECTED_ORIG = "SET_DISCONNECTED_ORIG"; public static final String OVERRIDE_DISCONNECT_MESSAGE = "OVERRIDE_DISCONNECT_MSG"; public static final String CALL_DIAGNOSTIC_SERVICE_TIMEOUT = "CALL_DIAGNOSTIC_SERVICE_TIMEOUT"; public static class Timings { public static final String ACCEPT_TIMING = "accept"; Loading Loading
src/com/android/server/telecom/Call.java +103 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.provider.CallLog; import android.provider.ContactsContract.Contacts; import android.telecom.BluetoothCallQualityReport; import android.telecom.CallAudioState; import android.telecom.CallDiagnosticService; import android.telecom.CallerInfo; import android.telecom.Conference; import android.telecom.Connection; Loading @@ -60,6 +61,7 @@ import android.telecom.VideoProfile; import android.telephony.PhoneNumberUtils; import android.telephony.TelephonyManager; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; import android.text.TextUtils; import android.util.ArrayMap; import android.widget.Toast; Loading @@ -81,7 +83,9 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** * Encapsulates all aspects of a given phone call throughout its lifecycle, starting Loading Loading @@ -661,6 +665,22 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, */ private boolean mIsSimCall; /** * Set to {@code true} if we received a valid response ({@code null} or otherwise) from * the {@link DiagnosticCall#onCallDisconnected(ImsReasonInfo)} or * {@link DiagnosticCall#onCallDisconnected(int, int)} calls. This is used to detect a timeout * when awaiting a response from the call diagnostic service. */ private boolean mReceivedCallDiagnosticPostCallResponse = false; /** * {@link CompletableFuture} used to delay posting disconnection and removal to a call until * after a {@link CallDiagnosticService} is able to handle the disconnection and provide a * disconnect message via {@link DiagnosticCall#onCallDisconnected(ImsReasonInfo)} or * {@link DiagnosticCall#onCallDisconnected(int, int)}. */ private CompletableFuture<Boolean> mDisconnectFuture; /** * Persists the specified parameters and initializes the new instance. * @param context The context. Loading Loading @@ -1092,8 +1112,29 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, } } /** * Handles an incoming overridden disconnect message for this call. * * We only care if the disconnect is handled via a future. * @param message the overridden disconnect message. */ public void handleOverrideDisconnectMessage(@Nullable CharSequence message) { Log.i(this, "handleOverrideDisconnectMessage; callid=%s, msg=%s", getId(), message); if (isDisconnectHandledViaFuture()) { mReceivedCallDiagnosticPostCallResponse = true; if (message != null) { Log.addEvent(this, LogUtils.Events.OVERRIDE_DISCONNECT_MESSAGE, message); // Replace the existing disconnect cause in this call setOverrideDisconnectCauseCode(new DisconnectCause(DisconnectCause.ERROR, message, message, null)); } mDisconnectFuture.complete(true); } else { Log.w(this, "handleOverrideDisconnectMessage; callid=%s - got override when unbound", getId()); } } /** Loading Loading @@ -4088,4 +4129,66 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, public boolean isSimCall() { return mIsSimCall; } /** * Sets whether this is a sim call or not. * @param isSimCall {@code true} if this is a SIM call, {@code false} otherwise. */ public void setIsSimCall(boolean isSimCall) { mIsSimCall = isSimCall; } /** * Initializes a disconnect future which is used to chain up pending operations which take * place when the {@link CallDiagnosticService} returns the result of the * {@link DiagnosticCall#onCallDisconnected(int, int)} or * {@link DiagnosticCall#onCallDisconnected(ImsReasonInfo)} invocation via * {@link CallDiagnosticServiceAdapter}. If no {@link CallDiagnosticService} is in use, we * would not try to make a disconnect future. * @param timeoutMillis Timeout we use for waiting for the response. * @return the {@link CompletableFuture}. */ public CompletableFuture<Boolean> initializeDisconnectFuture(long timeoutMillis) { if (mDisconnectFuture == null) { mDisconnectFuture = new CompletableFuture<Boolean>() .completeOnTimeout(false, timeoutMillis, TimeUnit.MILLISECONDS); // After all the chained stuff we will report where the CDS timed out. mDisconnectFuture.thenRunAsync(() -> { if (!mReceivedCallDiagnosticPostCallResponse) { Log.addEvent(this, LogUtils.Events.CALL_DIAGNOSTIC_SERVICE_TIMEOUT); }}, new LoggedHandlerExecutor(mHandler, "C.iDF", mLock)) .exceptionally((throwable) -> { Log.e(this, throwable, "Error while executing disconnect future"); return null; }); } return mDisconnectFuture; } /** * @return the disconnect future, if initialized. Used for chaining operations after creation. */ public CompletableFuture<Boolean> getDisconnectFuture() { return mDisconnectFuture; } /** * @return {@code true} if disconnection and removal is handled via a future, or {@code false} * if this is handled immediately. */ public boolean isDisconnectHandledViaFuture() { return mDisconnectFuture != null && !mDisconnectFuture.isDone(); } /** * Perform any cleanup on this call as a result of a {@link TelecomServiceImpl} * {@code cleanupStuckCalls} request. */ public void cleanup() { if (mDisconnectFuture != null) { mDisconnectFuture.complete(false); mDisconnectFuture = null; } } }
src/com/android/server/telecom/CallDiagnosticServiceController.java +28 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.telecom.CallAudioState; import android.telecom.CallDiagnosticService; import android.telecom.ConnectionService; import android.telecom.DiagnosticCall; import android.telecom.DisconnectCause; import android.telecom.InCallService; import android.telecom.Log; import android.telecom.ParcelableCall; Loading Loading @@ -254,6 +255,32 @@ public class CallDiagnosticServiceController extends CallsManagerListenerBase { } } /** * Handles a newly disconnected call signalled from {@link CallsManager}. * @param call The call * @param disconnectCause The disconnect cause * @return {@code true} if the {@link CallDiagnosticService} was sent the call, {@code false} * if the call was not applicable to the CDS or if there was an issue sending it. */ public boolean onCallDisconnected(@NonNull Call call, @NonNull DisconnectCause disconnectCause) { if (!call.isSimCall() || call.isExternalCall()) { Log.i(this, "onCallDisconnected: skipping call %s as non-sim or external.", call.getId()); return false; } String callId = mCallIdMapper.getCallId(call); try { if (isConnected()) { mCallDiagnosticService.notifyCallDisconnected(callId, disconnectCause); return true; } } catch (RemoteException e) { Log.w(this, "onCallDisconnected: callId=%s, exception=%s", call.getId(), e); } return false; } /** * Handles Telecom removal of calls; will remove the call from the bound service and if the * number of tracked calls falls to zero, unbind from the service. Loading Loading @@ -569,7 +596,7 @@ public class CallDiagnosticServiceController extends CallsManagerListenerBase { /** * @return {@code true} if the call diagnostic service is bound/connected. */ private boolean isConnected() { public boolean isConnected() { return mCallDiagnosticService != null; } Loading
src/com/android/server/telecom/CallsManager.java +63 −7 Original line number Diff line number Diff line Loading @@ -3099,27 +3099,82 @@ public class CallsManager extends Call.ListenerBase // be marked as missed. call.setOverrideDisconnectCauseCode(new DisconnectCause(DisconnectCause.MISSED)); } // If a call diagnostic service is in use, we will log the original telephony-provided // disconnect cause, inform the CDS of the disconnection, and then chain the update of the // call state until AFTER the CDS reports it's result back. if (oldState == CallState.ACTIVE && disconnectCause.getCode() != DisconnectCause.MISSED && mCallDiagnosticServiceController.isConnected() && mCallDiagnosticServiceController.onCallDisconnected(call, disconnectCause)) { Log.i(this, "markCallAsDisconnected; callid=%s, postingToFuture.", call.getId()); // Log the original disconnect reason prior to calling into the // CallDiagnosticService. Log.addEvent(call, LogUtils.Events.SET_DISCONNECTED_ORIG, disconnectCause); // Setup the future with a timeout so that the CDS is time boxed. CompletableFuture<Boolean> future = call.initializeDisconnectFuture( mTimeoutsAdapter.getCallDiagnosticServiceTimeoutMillis( mContext.getContentResolver())); // Post the disconnection updates to the future for completion once the CDS returns // with it's overridden disconnect message. future.thenRunAsync(() -> { call.setDisconnectCause(disconnectCause); setCallState(call, CallState.DISCONNECTED, "disconnected set explicitly"); }, new LoggedHandlerExecutor(mHandler, "CM.mCAD", mLock)) .exceptionally((throwable) -> { Log.e(TAG, throwable, "Error while executing disconnect future."); return null; }); } else { // No CallDiagnosticService, or it doesn't handle this call, so just do this // synchronously as always. call.setDisconnectCause(disconnectCause); setCallState(call, CallState.DISCONNECTED, "disconnected set explicitly"); } if (oldState == CallState.NEW && disconnectCause.getCode() == DisconnectCause.MISSED) { Log.i(this, "markCallAsDisconnected: logging missed call "); mCallLogManager.logCall(call, Calls.MISSED_TYPE, true, null); } } /** * Removes an existing disconnected call, and notifies the in-call app. */ void markCallAsRemoved(Call call) { if (call.isDisconnectHandledViaFuture()) { Log.i(this, "markCallAsRemoved; callid=%s, postingToFuture.", call.getId()); // A future is being used due to a CallDiagnosticService handling the call. We will // chain the removal operation to the end of any outstanding disconnect work. call.getDisconnectFuture().thenRunAsync(() -> { performRemoval(call); }, new LoggedHandlerExecutor(mHandler, "CM.mCAR", mLock)) .exceptionally((throwable) -> { Log.e(TAG, throwable, "Error while executing disconnect future"); return null; }); } else { Log.i(this, "markCallAsRemoved; callid=%s, immediate.", call.getId()); performRemoval(call); } } /** * Work which is completed when a call is to be removed. Can either be be run synchronously or * posted to a {@link Call#getDisconnectFuture()}. * @param call The call. */ private void performRemoval(Call call) { mInCallController.getBindingFuture().thenRunAsync(() -> { call.maybeCleanupHandover(); removeCall(call); Call foregroundCall = mCallAudioManager.getPossiblyHeldForegroundCall(); if (mLocallyDisconnectingCalls.contains(call)) { boolean isDisconnectingChildCall = call.isDisconnectingChildCall(); Log.v(this, "markCallAsRemoved: isDisconnectingChildCall = " Log.v(this, "performRemoval: isDisconnectingChildCall = " + isDisconnectingChildCall + "call -> %s", call); mLocallyDisconnectingCalls.remove(call); // Auto-unhold the foreground call due to a locally disconnected call, except if the Loading @@ -3136,10 +3191,11 @@ public class CallsManager extends Call.ListenerBase // The new foreground call is on hold, however the carrier does not display the hold // button in the UI. Therefore, we need to auto unhold the held call since the user // has no means of unholding it themselves. Log.i(this, "Auto-unholding held foreground call (call doesn't support hold)"); Log.i(this, "performRemoval: Auto-unholding held foreground call (call doesn't " + "support hold)"); foregroundCall.unhold(); } }, new LoggedHandlerExecutor(mHandler, "CM.mCAR", mLock)) }, new LoggedHandlerExecutor(mHandler, "CM.pR", mLock)) .exceptionally((throwable) -> { Log.e(TAG, throwable, "Error while executing call removal"); return null; Loading
src/com/android/server/telecom/ConnectionServiceWrapper.java +1 −1 Original line number Diff line number Diff line Loading @@ -352,7 +352,7 @@ public class ConnectionServiceWrapper extends ServiceBinder implements logIncoming("removeCall %s", callId); Call call = mCallIdMapper.getCall(callId); if (call != null) { if (call.isAlive()) { if (call.isAlive() && !call.isDisconnectHandledViaFuture()) { mCallsManager.markCallAsDisconnected( call, new DisconnectCause(DisconnectCause.REMOTE)); } else { Loading
src/com/android/server/telecom/LogUtils.java +4 −0 Original line number Diff line number Diff line Loading @@ -197,6 +197,10 @@ public class LogUtils { public static final String REDIRECTION_USER_CONFIRMED = "REDIRECTION_USER_CONFIRMED"; public static final String REDIRECTION_USER_CANCELLED = "REDIRECTION_USER_CANCELLED"; public static final String BT_QUALITY_REPORT = "BT_QUALITY_REPORT"; public static final String SET_DISCONNECTED_ORIG = "SET_DISCONNECTED_ORIG"; public static final String OVERRIDE_DISCONNECT_MESSAGE = "OVERRIDE_DISCONNECT_MSG"; public static final String CALL_DIAGNOSTIC_SERVICE_TIMEOUT = "CALL_DIAGNOSTIC_SERVICE_TIMEOUT"; public static class Timings { public static final String ACCEPT_TIMING = "accept"; Loading