2021-02-05 11:12:57 -08:00
|
|
|
/*
|
|
|
|
* 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.NonNull;
|
|
|
|
import android.annotation.Nullable;
|
|
|
|
import android.annotation.SdkConstant;
|
2021-03-11 22:43:09 -08:00
|
|
|
import android.annotation.SuppressLint;
|
2021-02-05 11:12:57 -08:00
|
|
|
import android.annotation.SystemApi;
|
|
|
|
import android.app.Service;
|
|
|
|
import android.content.Intent;
|
2021-03-11 22:43:09 -08:00
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.HandlerExecutor;
|
2021-02-05 11:12:57 -08:00
|
|
|
import android.os.IBinder;
|
|
|
|
import android.os.RemoteException;
|
2021-03-12 15:44:08 -08:00
|
|
|
|
|
|
|
import android.telephony.CallQuality;
|
2021-02-05 11:12:57 -08:00
|
|
|
import android.util.ArrayMap;
|
|
|
|
|
|
|
|
import com.android.internal.telecom.ICallDiagnosticService;
|
|
|
|
import com.android.internal.telecom.ICallDiagnosticServiceAdapter;
|
|
|
|
|
|
|
|
import java.util.Map;
|
2021-03-11 22:43:09 -08:00
|
|
|
import java.util.concurrent.Executor;
|
2021-02-05 11:12:57 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The platform supports a single OEM provided {@link CallDiagnosticService}, as defined by the
|
|
|
|
* {@code call_diagnostic_service_package_name} key in the
|
|
|
|
* {@code packages/services/Telecomm/res/values/config.xml} file. An OEM can use this API to help
|
|
|
|
* provide more actionable information about calling issues the user encounters during and after
|
|
|
|
* a call.
|
|
|
|
*
|
|
|
|
* <h1>Manifest Declaration</h1>
|
|
|
|
* The following is an example of how to declare the service entry in the
|
|
|
|
* {@link CallDiagnosticService} manifest file:
|
|
|
|
* <pre>
|
|
|
|
* {@code
|
|
|
|
* <service android:name="your.package.YourCallDiagnosticServiceImplementation"
|
|
|
|
* android:permission="android.permission.BIND_CALL_DIAGNOSTIC_SERVICE">
|
|
|
|
* <intent-filter>
|
|
|
|
* <action android:name="android.telecom.CallDiagnosticService"/>
|
|
|
|
* </intent-filter>
|
|
|
|
* </service>
|
|
|
|
* }
|
|
|
|
* </pre>
|
2021-03-11 22:43:09 -08:00
|
|
|
* <p>
|
|
|
|
* <h2>Threading Model</h2>
|
2021-03-16 09:58:07 -07:00
|
|
|
* By default, all incoming IPC from Telecom in this service and in the {@link CallDiagnostics}
|
2021-03-11 22:43:09 -08:00
|
|
|
* instances will take place on the main thread. You can override {@link #getExecutor()} in your
|
|
|
|
* implementation to provide your own {@link Executor}.
|
2021-02-05 11:12:57 -08:00
|
|
|
* @hide
|
|
|
|
*/
|
|
|
|
@SystemApi
|
|
|
|
public abstract class CallDiagnosticService extends Service {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Binder stub implementation which handles incoming requests from Telecom.
|
|
|
|
*/
|
|
|
|
private final class CallDiagnosticServiceBinder extends ICallDiagnosticService.Stub {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setAdapter(ICallDiagnosticServiceAdapter adapter) throws RemoteException {
|
|
|
|
handleSetAdapter(adapter);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void initializeDiagnosticCall(ParcelableCall call) throws RemoteException {
|
|
|
|
handleCallAdded(call);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void updateCall(ParcelableCall call) throws RemoteException {
|
|
|
|
handleCallUpdated(call);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void removeDiagnosticCall(String callId) throws RemoteException {
|
|
|
|
handleCallRemoved(callId);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void updateCallAudioState(CallAudioState callAudioState) throws RemoteException {
|
2021-03-11 22:43:09 -08:00
|
|
|
getExecutor().execute(() -> onCallAudioStateChanged(callAudioState));
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void receiveDeviceToDeviceMessage(String callId, int message, int value) {
|
|
|
|
handleReceivedD2DMessage(callId, message, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void receiveBluetoothCallQualityReport(BluetoothCallQualityReport qualityReport)
|
|
|
|
throws RemoteException {
|
|
|
|
handleBluetoothCallQualityReport(qualityReport);
|
|
|
|
}
|
2021-03-09 15:06:30 -08:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void notifyCallDisconnected(@NonNull String callId,
|
|
|
|
@NonNull DisconnectCause disconnectCause) throws RemoteException {
|
|
|
|
handleCallDisconnected(callId, disconnectCause);
|
|
|
|
}
|
2021-03-12 15:44:08 -08:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void callQualityChanged(String callId, CallQuality callQuality)
|
|
|
|
throws RemoteException {
|
|
|
|
handleCallQualityChanged(callId, callQuality);
|
|
|
|
}
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-03-16 09:58:07 -07:00
|
|
|
* Listens to events raised by a {@link CallDiagnostics}.
|
2021-02-05 11:12:57 -08:00
|
|
|
*/
|
2021-03-16 09:58:07 -07:00
|
|
|
private CallDiagnostics.Listener mDiagnosticCallListener =
|
|
|
|
new CallDiagnostics.Listener() {
|
2021-02-05 11:12:57 -08:00
|
|
|
|
|
|
|
@Override
|
2021-03-16 09:58:07 -07:00
|
|
|
public void onSendDeviceToDeviceMessage(CallDiagnostics callDiagnostics,
|
|
|
|
@CallDiagnostics.MessageType int message, int value) {
|
|
|
|
handleSendDeviceToDeviceMessage(callDiagnostics, message, value);
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-03-16 09:58:07 -07:00
|
|
|
public void onDisplayDiagnosticMessage(CallDiagnostics callDiagnostics,
|
|
|
|
int messageId,
|
2021-02-05 11:12:57 -08:00
|
|
|
CharSequence message) {
|
2021-03-16 09:58:07 -07:00
|
|
|
handleDisplayDiagnosticMessage(callDiagnostics, messageId, message);
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-03-16 09:58:07 -07:00
|
|
|
public void onClearDiagnosticMessage(CallDiagnostics callDiagnostics,
|
|
|
|
int messageId) {
|
|
|
|
handleClearDiagnosticMessage(callDiagnostics, messageId);
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The {@link Intent} that must be declared as handled by the service.
|
|
|
|
*/
|
|
|
|
@SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
|
|
|
|
public static final String SERVICE_INTERFACE = "android.telecom.CallDiagnosticService";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Map which tracks the Telecom calls received from the Telecom stack.
|
|
|
|
*/
|
|
|
|
private final Map<String, Call.Details> mCallByTelecomCallId = new ArrayMap<>();
|
2021-03-16 09:58:07 -07:00
|
|
|
private final Map<String, CallDiagnostics> mDiagnosticCallByTelecomCallId = new ArrayMap<>();
|
2021-03-11 22:43:09 -08:00
|
|
|
private final Object mLock = new Object();
|
2021-02-05 11:12:57 -08:00
|
|
|
private ICallDiagnosticServiceAdapter mAdapter;
|
|
|
|
|
2021-03-11 22:43:09 -08:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2021-02-05 11:12:57 -08:00
|
|
|
@Nullable
|
|
|
|
@Override
|
|
|
|
public IBinder onBind(@NonNull Intent intent) {
|
|
|
|
Log.i(this, "onBind!");
|
|
|
|
return new CallDiagnosticServiceBinder();
|
|
|
|
}
|
|
|
|
|
2021-03-11 22:43:09 -08:00
|
|
|
/**
|
|
|
|
* 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
|
2021-03-16 09:58:07 -07:00
|
|
|
* {@link CallDiagnosticService} and {@link CallDiagnostics}.
|
2021-03-11 22:43:09 -08:00
|
|
|
*/
|
|
|
|
@SuppressLint("OnNameExpected")
|
|
|
|
@NonNull public Executor getExecutor() {
|
|
|
|
return new HandlerExecutor(Handler.createAsync(getMainLooper()));
|
|
|
|
}
|
|
|
|
|
2021-02-05 11:12:57 -08:00
|
|
|
/**
|
|
|
|
* Telecom calls this method on the {@link CallDiagnosticService} with details about a new call
|
|
|
|
* which was added to Telecom.
|
|
|
|
* <p>
|
2021-03-16 09:58:07 -07:00
|
|
|
* The {@link CallDiagnosticService} returns an implementation of {@link CallDiagnostics} to be
|
2021-02-05 11:12:57 -08:00
|
|
|
* used for the lifespan of this call.
|
2021-03-11 22:43:09 -08:00
|
|
|
* <p>
|
|
|
|
* Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
|
|
|
|
* {@link CallDiagnosticService#getExecutor()} for more information.
|
2021-02-05 11:12:57 -08:00
|
|
|
*
|
|
|
|
* @param call The details of the new call.
|
2021-03-16 09:58:07 -07:00
|
|
|
* @return An instance of {@link CallDiagnostics} which the {@link CallDiagnosticService}
|
2021-02-05 11:12:57 -08:00
|
|
|
* provides to be used for the lifespan of the call.
|
2021-03-16 09:58:07 -07:00
|
|
|
* @throws IllegalArgumentException if a {@code null} {@link CallDiagnostics} is returned.
|
2021-02-05 11:12:57 -08:00
|
|
|
*/
|
2021-03-16 09:58:07 -07:00
|
|
|
public abstract @NonNull CallDiagnostics onInitializeCallDiagnostics(@NonNull
|
2021-02-05 11:12:57 -08:00
|
|
|
android.telecom.Call.Details call);
|
|
|
|
|
|
|
|
/**
|
2021-03-16 09:58:07 -07:00
|
|
|
* 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.
|
2021-03-11 22:43:09 -08:00
|
|
|
* <p>
|
|
|
|
* Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
|
|
|
|
* {@link CallDiagnosticService#getExecutor()} for more information.
|
|
|
|
*
|
2021-02-05 11:12:57 -08:00
|
|
|
* @param call The diagnostic call which is no longer tracked by Telecom.
|
|
|
|
*/
|
2021-03-16 09:58:07 -07:00
|
|
|
public abstract void onRemoveCallDiagnostics(@NonNull CallDiagnostics call);
|
2021-02-05 11:12:57 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Telecom calls this method when the audio routing or available audio route information
|
|
|
|
* changes.
|
|
|
|
* <p>
|
|
|
|
* Audio state is common to all calls.
|
2021-03-11 22:43:09 -08:00
|
|
|
* <p>
|
|
|
|
* Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
|
|
|
|
* {@link CallDiagnosticService#getExecutor()} for more information.
|
2021-02-05 11:12:57 -08:00
|
|
|
*
|
|
|
|
* @param audioState The new audio state.
|
|
|
|
*/
|
|
|
|
public abstract void onCallAudioStateChanged(
|
|
|
|
@NonNull CallAudioState audioState);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Telecom calls this method when a {@link BluetoothCallQualityReport} is received from the
|
|
|
|
* bluetooth stack.
|
2021-03-11 22:43:09 -08:00
|
|
|
* <p>
|
|
|
|
* Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
|
|
|
|
* {@link CallDiagnosticService#getExecutor()} for more information.
|
|
|
|
*
|
2021-02-05 11:12:57 -08:00
|
|
|
* @param qualityReport the {@link BluetoothCallQualityReport}.
|
|
|
|
*/
|
|
|
|
public abstract void onBluetoothCallQualityReportReceived(
|
|
|
|
@NonNull BluetoothCallQualityReport qualityReport);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles a request from Telecom to set the adapater used to communicate back to Telecom.
|
|
|
|
* @param adapter
|
|
|
|
*/
|
|
|
|
private void handleSetAdapter(@NonNull ICallDiagnosticServiceAdapter adapter) {
|
|
|
|
mAdapter = adapter;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles a request from Telecom to add a new call.
|
|
|
|
* @param parcelableCall
|
|
|
|
*/
|
|
|
|
private void handleCallAdded(@NonNull ParcelableCall parcelableCall) {
|
|
|
|
String telecomCallId = parcelableCall.getId();
|
|
|
|
Log.i(this, "handleCallAdded: callId=%s - added", telecomCallId);
|
|
|
|
Call.Details newCallDetails = Call.Details.createFromParcelableCall(parcelableCall);
|
2021-03-11 22:43:09 -08:00
|
|
|
synchronized (mLock) {
|
|
|
|
mCallByTelecomCallId.put(telecomCallId, newCallDetails);
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
2021-03-11 22:43:09 -08:00
|
|
|
|
|
|
|
getExecutor().execute(() -> {
|
2021-03-16 09:58:07 -07:00
|
|
|
CallDiagnostics callDiagnostics = onInitializeCallDiagnostics(newCallDetails);
|
|
|
|
if (callDiagnostics == null) {
|
2021-03-11 22:43:09 -08:00
|
|
|
throw new IllegalArgumentException(
|
|
|
|
"A valid DiagnosticCall instance was not provided.");
|
|
|
|
}
|
|
|
|
synchronized (mLock) {
|
2021-03-16 09:58:07 -07:00
|
|
|
callDiagnostics.setListener(mDiagnosticCallListener);
|
|
|
|
callDiagnostics.setCallId(telecomCallId);
|
|
|
|
mDiagnosticCallByTelecomCallId.put(telecomCallId, callDiagnostics);
|
2021-03-11 22:43:09 -08:00
|
|
|
}
|
|
|
|
});
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles an update to {@link Call.Details} notified by Telecom.
|
2021-03-16 09:58:07 -07:00
|
|
|
* Caches the call details and notifies the {@link CallDiagnostics} of the change via
|
|
|
|
* {@link CallDiagnostics#onCallDetailsChanged(Call.Details)}.
|
2021-02-05 11:12:57 -08:00
|
|
|
* @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);
|
2021-03-16 09:58:07 -07:00
|
|
|
CallDiagnostics callDiagnostics;
|
2021-03-11 22:43:09 -08:00
|
|
|
synchronized (mLock) {
|
2021-03-16 09:58:07 -07:00
|
|
|
callDiagnostics = mDiagnosticCallByTelecomCallId.get(telecomCallId);
|
2021-05-21 16:20:16 -07:00
|
|
|
if (callDiagnostics == null) {
|
|
|
|
// Possible to get a call update after a call is removed.
|
|
|
|
return;
|
|
|
|
}
|
2021-03-11 22:43:09 -08:00
|
|
|
mCallByTelecomCallId.put(telecomCallId, newCallDetails);
|
|
|
|
}
|
2021-03-16 09:58:07 -07:00
|
|
|
getExecutor().execute(() -> callDiagnostics.handleCallUpdated(newCallDetails));
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles a request from Telecom to remove an existing call.
|
|
|
|
* @param telecomCallId
|
|
|
|
*/
|
|
|
|
private void handleCallRemoved(@NonNull String telecomCallId) {
|
|
|
|
Log.i(this, "handleCallRemoved: callId=%s - removed", telecomCallId);
|
|
|
|
|
2021-03-16 09:58:07 -07:00
|
|
|
CallDiagnostics callDiagnostics;
|
2021-03-11 22:43:09 -08:00
|
|
|
synchronized (mLock) {
|
2021-05-21 16:20:16 -07:00
|
|
|
if (mCallByTelecomCallId.containsKey(telecomCallId)) {
|
|
|
|
mCallByTelecomCallId.remove(telecomCallId);
|
|
|
|
}
|
|
|
|
|
2021-03-11 22:43:09 -08:00
|
|
|
if (mDiagnosticCallByTelecomCallId.containsKey(telecomCallId)) {
|
2021-03-16 09:58:07 -07:00
|
|
|
callDiagnostics = mDiagnosticCallByTelecomCallId.remove(telecomCallId);
|
2021-03-11 22:43:09 -08:00
|
|
|
} else {
|
2021-03-16 09:58:07 -07:00
|
|
|
callDiagnostics = null;
|
2021-03-11 22:43:09 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Inform the service of the removed call.
|
2021-03-16 09:58:07 -07:00
|
|
|
if (callDiagnostics != null) {
|
|
|
|
getExecutor().execute(() -> onRemoveCallDiagnostics(callDiagnostics));
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles an incoming device to device message received from Telecom. Notifies the
|
2021-03-16 09:58:07 -07:00
|
|
|
* {@link CallDiagnostics} via {@link CallDiagnostics#onReceiveDeviceToDeviceMessage(int, int)}.
|
2021-02-05 11:12:57 -08:00
|
|
|
* @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);
|
2021-03-16 09:58:07 -07:00
|
|
|
CallDiagnostics callDiagnostics;
|
2021-03-11 22:43:09 -08:00
|
|
|
synchronized (mLock) {
|
2021-03-16 09:58:07 -07:00
|
|
|
callDiagnostics = mDiagnosticCallByTelecomCallId.get(callId);
|
2021-03-11 22:43:09 -08:00
|
|
|
}
|
2021-03-16 09:58:07 -07:00
|
|
|
if (callDiagnostics != null) {
|
2021-03-11 22:43:09 -08:00
|
|
|
getExecutor().execute(
|
2021-03-16 09:58:07 -07:00
|
|
|
() -> callDiagnostics.onReceiveDeviceToDeviceMessage(message, value));
|
2021-03-11 22:43:09 -08:00
|
|
|
}
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
|
2021-03-09 15:06:30 -08:00
|
|
|
/**
|
|
|
|
* 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);
|
2021-05-21 16:20:16 -07:00
|
|
|
CallDiagnostics callDiagnostics;
|
|
|
|
synchronized (mLock) {
|
|
|
|
callDiagnostics = mDiagnosticCallByTelecomCallId.get(callId);
|
|
|
|
}
|
2021-03-09 15:06:30 -08:00
|
|
|
CharSequence message;
|
|
|
|
if (disconnectCause.getImsReasonInfo() != null) {
|
2021-03-16 09:58:07 -07:00
|
|
|
message = callDiagnostics.onCallDisconnected(disconnectCause.getImsReasonInfo());
|
2021-03-09 15:06:30 -08:00
|
|
|
} else {
|
2021-03-16 09:58:07 -07:00
|
|
|
message = callDiagnostics.onCallDisconnected(
|
2021-03-09 15:06:30 -08:00
|
|
|
disconnectCause.getTelephonyDisconnectCause(),
|
|
|
|
disconnectCause.getTelephonyPreciseDisconnectCause());
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
mAdapter.overrideDisconnectMessage(callId, message);
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
Log.w(this, "handleCallDisconnected: call=%s; cause=%s; %s",
|
|
|
|
callId, disconnectCause, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-05 11:12:57 -08:00
|
|
|
/**
|
|
|
|
* Handles an incoming bluetooth call quality report from Telecom. Notifies via
|
|
|
|
* {@link CallDiagnosticService#onBluetoothCallQualityReportReceived(
|
|
|
|
* BluetoothCallQualityReport)}.
|
|
|
|
* @param qualityReport The bluetooth call quality remote.
|
|
|
|
*/
|
|
|
|
private void handleBluetoothCallQualityReport(@NonNull BluetoothCallQualityReport
|
|
|
|
qualityReport) {
|
|
|
|
Log.i(this, "handleBluetoothCallQualityReport; report=%s", qualityReport);
|
2021-03-11 22:43:09 -08:00
|
|
|
getExecutor().execute(() -> onBluetoothCallQualityReportReceived(qualityReport));
|
2021-02-05 11:12:57 -08:00
|
|
|
}
|
|
|
|
|
2021-03-12 15:44:08 -08:00
|
|
|
/**
|
|
|
|
* 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;
|
2021-05-21 16:20:16 -07:00
|
|
|
synchronized(mLock) {
|
|
|
|
callDiagnostics = mDiagnosticCallByTelecomCallId.get(callId);
|
|
|
|
}
|
2021-03-12 15:44:08 -08:00
|
|
|
if (callDiagnostics != null) {
|
|
|
|
callDiagnostics.onCallQualityReceived(callQuality);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-05 11:12:57 -08:00
|
|
|
/**
|
2021-03-16 09:58:07 -07:00
|
|
|
* Handles a request from a {@link CallDiagnostics} to send a device to device message (received
|
|
|
|
* via {@link CallDiagnostics#sendDeviceToDeviceMessage(int, int)}.
|
|
|
|
* @param callDiagnostics
|
2021-02-05 11:12:57 -08:00
|
|
|
* @param message
|
|
|
|
* @param value
|
|
|
|
*/
|
2021-03-16 09:58:07 -07:00
|
|
|
private void handleSendDeviceToDeviceMessage(@NonNull CallDiagnostics callDiagnostics,
|
2021-02-05 11:12:57 -08:00
|
|
|
int message, int value) {
|
2021-03-16 09:58:07 -07:00
|
|
|
String callId = callDiagnostics.getCallId();
|
2021-02-05 11:12:57 -08:00
|
|
|
try {
|
|
|
|
mAdapter.sendDeviceToDeviceMessage(callId, message, value);
|
|
|
|
Log.i(this, "handleSendDeviceToDeviceMessage: call=%s; msg=%d/%d", callId, message,
|
|
|
|
value);
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
Log.w(this, "handleSendDeviceToDeviceMessage: call=%s; msg=%d/%d failed %s",
|
|
|
|
callId, message, value, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-03-16 09:58:07 -07:00
|
|
|
* Handles a request from a {@link CallDiagnostics} to display an in-call diagnostic message.
|
|
|
|
* Originates from {@link CallDiagnostics#displayDiagnosticMessage(int, CharSequence)}.
|
|
|
|
* @param callDiagnostics
|
2021-02-05 11:12:57 -08:00
|
|
|
* @param messageId
|
|
|
|
* @param message
|
|
|
|
*/
|
2021-03-16 09:58:07 -07:00
|
|
|
private void handleDisplayDiagnosticMessage(CallDiagnostics callDiagnostics, int messageId,
|
2021-02-05 11:12:57 -08:00
|
|
|
CharSequence message) {
|
2021-03-16 09:58:07 -07:00
|
|
|
String callId = callDiagnostics.getCallId();
|
2021-02-05 11:12:57 -08:00
|
|
|
try {
|
|
|
|
mAdapter.displayDiagnosticMessage(callId, messageId, message);
|
|
|
|
Log.i(this, "handleDisplayDiagnosticMessage: call=%s; msg=%d/%s", callId, messageId,
|
|
|
|
message);
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
Log.w(this, "handleDisplayDiagnosticMessage: call=%s; msg=%d/%s failed %s",
|
|
|
|
callId, messageId, message, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-03-16 09:58:07 -07:00
|
|
|
* Handles a request from a {@link CallDiagnostics} to clear a previously shown diagnostic
|
2021-02-05 11:12:57 -08:00
|
|
|
* message.
|
2021-03-16 09:58:07 -07:00
|
|
|
* Originates from {@link CallDiagnostics#clearDiagnosticMessage(int)}.
|
|
|
|
* @param callDiagnostics
|
2021-02-05 11:12:57 -08:00
|
|
|
* @param messageId
|
|
|
|
*/
|
2021-03-16 09:58:07 -07:00
|
|
|
private void handleClearDiagnosticMessage(CallDiagnostics callDiagnostics, int messageId) {
|
|
|
|
String callId = callDiagnostics.getCallId();
|
2021-02-05 11:12:57 -08:00
|
|
|
try {
|
|
|
|
mAdapter.clearDiagnosticMessage(callId, messageId);
|
|
|
|
Log.i(this, "handleClearDiagnosticMessage: call=%s; msg=%d", callId, messageId);
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
Log.w(this, "handleClearDiagnosticMessage: call=%s; msg=%d failed %s",
|
|
|
|
callId, messageId, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|