blob: f5357b19c4de92402e29a6f763db8d83e1d6dde3 [file] [log] [blame]
Tyler Gunnd5821842021-02-05 11:12:57 -08001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.telecom;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.annotation.SdkConstant;
Tyler Gunn80196212021-03-11 22:43:09 -080022import android.annotation.SuppressLint;
Tyler Gunnd5821842021-02-05 11:12:57 -080023import android.annotation.SystemApi;
24import android.app.Service;
25import android.content.Intent;
Tyler Gunn80196212021-03-11 22:43:09 -080026import android.os.Handler;
27import android.os.HandlerExecutor;
Tyler Gunnd5821842021-02-05 11:12:57 -080028import android.os.IBinder;
29import android.os.RemoteException;
30import android.util.ArrayMap;
31
32import com.android.internal.telecom.ICallDiagnosticService;
33import com.android.internal.telecom.ICallDiagnosticServiceAdapter;
34
35import java.util.Map;
Tyler Gunn80196212021-03-11 22:43:09 -080036import java.util.concurrent.Executor;
Tyler Gunnd5821842021-02-05 11:12:57 -080037
38/**
39 * The platform supports a single OEM provided {@link CallDiagnosticService}, as defined by the
40 * {@code call_diagnostic_service_package_name} key in the
41 * {@code packages/services/Telecomm/res/values/config.xml} file. An OEM can use this API to help
42 * provide more actionable information about calling issues the user encounters during and after
43 * a call.
44 *
45 * <h1>Manifest Declaration</h1>
46 * The following is an example of how to declare the service entry in the
47 * {@link CallDiagnosticService} manifest file:
48 * <pre>
49 * {@code
50 * <service android:name="your.package.YourCallDiagnosticServiceImplementation"
51 * android:permission="android.permission.BIND_CALL_DIAGNOSTIC_SERVICE">
52 * <intent-filter>
53 * <action android:name="android.telecom.CallDiagnosticService"/>
54 * </intent-filter>
55 * </service>
56 * }
57 * </pre>
Tyler Gunn80196212021-03-11 22:43:09 -080058 * <p>
59 * <h2>Threading Model</h2>
Tyler Gunn066de602021-03-16 09:58:07 -070060 * By default, all incoming IPC from Telecom in this service and in the {@link CallDiagnostics}
Tyler Gunn80196212021-03-11 22:43:09 -080061 * instances will take place on the main thread. You can override {@link #getExecutor()} in your
62 * implementation to provide your own {@link Executor}.
Tyler Gunnd5821842021-02-05 11:12:57 -080063 * @hide
64 */
65@SystemApi
66public abstract class CallDiagnosticService extends Service {
67
68 /**
69 * Binder stub implementation which handles incoming requests from Telecom.
70 */
71 private final class CallDiagnosticServiceBinder extends ICallDiagnosticService.Stub {
72
73 @Override
74 public void setAdapter(ICallDiagnosticServiceAdapter adapter) throws RemoteException {
75 handleSetAdapter(adapter);
76 }
77
78 @Override
79 public void initializeDiagnosticCall(ParcelableCall call) throws RemoteException {
80 handleCallAdded(call);
81 }
82
83 @Override
84 public void updateCall(ParcelableCall call) throws RemoteException {
85 handleCallUpdated(call);
86 }
87
88 @Override
89 public void removeDiagnosticCall(String callId) throws RemoteException {
90 handleCallRemoved(callId);
91 }
92
93 @Override
94 public void updateCallAudioState(CallAudioState callAudioState) throws RemoteException {
Tyler Gunn80196212021-03-11 22:43:09 -080095 getExecutor().execute(() -> onCallAudioStateChanged(callAudioState));
Tyler Gunnd5821842021-02-05 11:12:57 -080096 }
97
98 @Override
99 public void receiveDeviceToDeviceMessage(String callId, int message, int value) {
100 handleReceivedD2DMessage(callId, message, value);
101 }
102
103 @Override
104 public void receiveBluetoothCallQualityReport(BluetoothCallQualityReport qualityReport)
105 throws RemoteException {
106 handleBluetoothCallQualityReport(qualityReport);
107 }
Tyler Gunnbc9ecbc2021-03-09 15:06:30 -0800108
109 @Override
110 public void notifyCallDisconnected(@NonNull String callId,
111 @NonNull DisconnectCause disconnectCause) throws RemoteException {
112 handleCallDisconnected(callId, disconnectCause);
113 }
Tyler Gunnd5821842021-02-05 11:12:57 -0800114 }
115
116 /**
Tyler Gunn066de602021-03-16 09:58:07 -0700117 * Listens to events raised by a {@link CallDiagnostics}.
Tyler Gunnd5821842021-02-05 11:12:57 -0800118 */
Tyler Gunn066de602021-03-16 09:58:07 -0700119 private CallDiagnostics.Listener mDiagnosticCallListener =
120 new CallDiagnostics.Listener() {
Tyler Gunnd5821842021-02-05 11:12:57 -0800121
122 @Override
Tyler Gunn066de602021-03-16 09:58:07 -0700123 public void onSendDeviceToDeviceMessage(CallDiagnostics callDiagnostics,
124 @CallDiagnostics.MessageType int message, int value) {
125 handleSendDeviceToDeviceMessage(callDiagnostics, message, value);
Tyler Gunnd5821842021-02-05 11:12:57 -0800126 }
127
128 @Override
Tyler Gunn066de602021-03-16 09:58:07 -0700129 public void onDisplayDiagnosticMessage(CallDiagnostics callDiagnostics,
130 int messageId,
Tyler Gunnd5821842021-02-05 11:12:57 -0800131 CharSequence message) {
Tyler Gunn066de602021-03-16 09:58:07 -0700132 handleDisplayDiagnosticMessage(callDiagnostics, messageId, message);
Tyler Gunnd5821842021-02-05 11:12:57 -0800133 }
134
135 @Override
Tyler Gunn066de602021-03-16 09:58:07 -0700136 public void onClearDiagnosticMessage(CallDiagnostics callDiagnostics,
137 int messageId) {
138 handleClearDiagnosticMessage(callDiagnostics, messageId);
Tyler Gunnd5821842021-02-05 11:12:57 -0800139 }
140 };
141
142 /**
143 * The {@link Intent} that must be declared as handled by the service.
144 */
145 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
146 public static final String SERVICE_INTERFACE = "android.telecom.CallDiagnosticService";
147
148 /**
149 * Map which tracks the Telecom calls received from the Telecom stack.
150 */
151 private final Map<String, Call.Details> mCallByTelecomCallId = new ArrayMap<>();
Tyler Gunn066de602021-03-16 09:58:07 -0700152 private final Map<String, CallDiagnostics> mDiagnosticCallByTelecomCallId = new ArrayMap<>();
Tyler Gunn80196212021-03-11 22:43:09 -0800153 private final Object mLock = new Object();
Tyler Gunnd5821842021-02-05 11:12:57 -0800154 private ICallDiagnosticServiceAdapter mAdapter;
155
Tyler Gunn80196212021-03-11 22:43:09 -0800156 /**
157 * Handles binding to the {@link CallDiagnosticService}.
158 *
159 * @param intent The Intent that was used to bind to this service,
160 * as given to {@link android.content.Context#bindService
161 * Context.bindService}. Note that any extras that were included with
162 * the Intent at that point will <em>not</em> be seen here.
163 * @return
164 */
Tyler Gunnd5821842021-02-05 11:12:57 -0800165 @Nullable
166 @Override
167 public IBinder onBind(@NonNull Intent intent) {
168 Log.i(this, "onBind!");
169 return new CallDiagnosticServiceBinder();
170 }
171
172 /**
Tyler Gunn80196212021-03-11 22:43:09 -0800173 * Returns the {@link Executor} to use for incoming IPS from Telecom into your service
174 * implementation.
175 * <p>
176 * Override this method in your {@link CallDiagnosticService} implementation to provide the
177 * executor you want to use for incoming IPC.
178 *
179 * @return the {@link Executor} to use for incoming IPC from Telecom to
Tyler Gunn066de602021-03-16 09:58:07 -0700180 * {@link CallDiagnosticService} and {@link CallDiagnostics}.
Tyler Gunn80196212021-03-11 22:43:09 -0800181 */
182 @SuppressLint("OnNameExpected")
183 @NonNull public Executor getExecutor() {
184 return new HandlerExecutor(Handler.createAsync(getMainLooper()));
185 }
186
187 /**
Tyler Gunnd5821842021-02-05 11:12:57 -0800188 * Telecom calls this method on the {@link CallDiagnosticService} with details about a new call
189 * which was added to Telecom.
190 * <p>
Tyler Gunn066de602021-03-16 09:58:07 -0700191 * The {@link CallDiagnosticService} returns an implementation of {@link CallDiagnostics} to be
Tyler Gunnd5821842021-02-05 11:12:57 -0800192 * used for the lifespan of this call.
Tyler Gunn80196212021-03-11 22:43:09 -0800193 * <p>
194 * Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
195 * {@link CallDiagnosticService#getExecutor()} for more information.
Tyler Gunnd5821842021-02-05 11:12:57 -0800196 *
197 * @param call The details of the new call.
Tyler Gunn066de602021-03-16 09:58:07 -0700198 * @return An instance of {@link CallDiagnostics} which the {@link CallDiagnosticService}
Tyler Gunnd5821842021-02-05 11:12:57 -0800199 * provides to be used for the lifespan of the call.
Tyler Gunn066de602021-03-16 09:58:07 -0700200 * @throws IllegalArgumentException if a {@code null} {@link CallDiagnostics} is returned.
Tyler Gunnd5821842021-02-05 11:12:57 -0800201 */
Tyler Gunn066de602021-03-16 09:58:07 -0700202 public abstract @NonNull CallDiagnostics onInitializeCallDiagnostics(@NonNull
Tyler Gunnd5821842021-02-05 11:12:57 -0800203 android.telecom.Call.Details call);
204
205 /**
Tyler Gunn066de602021-03-16 09:58:07 -0700206 * Telecom calls this method when a previous created {@link CallDiagnostics} is no longer
207 * needed. This happens when Telecom is no longer tracking the call in question.
Tyler Gunn80196212021-03-11 22:43:09 -0800208 * <p>
209 * Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
210 * {@link CallDiagnosticService#getExecutor()} for more information.
211 *
Tyler Gunnd5821842021-02-05 11:12:57 -0800212 * @param call The diagnostic call which is no longer tracked by Telecom.
213 */
Tyler Gunn066de602021-03-16 09:58:07 -0700214 public abstract void onRemoveCallDiagnostics(@NonNull CallDiagnostics call);
Tyler Gunnd5821842021-02-05 11:12:57 -0800215
216 /**
217 * Telecom calls this method when the audio routing or available audio route information
218 * changes.
219 * <p>
220 * Audio state is common to all calls.
Tyler Gunn80196212021-03-11 22:43:09 -0800221 * <p>
222 * Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
223 * {@link CallDiagnosticService#getExecutor()} for more information.
Tyler Gunnd5821842021-02-05 11:12:57 -0800224 *
225 * @param audioState The new audio state.
226 */
227 public abstract void onCallAudioStateChanged(
228 @NonNull CallAudioState audioState);
229
230 /**
231 * Telecom calls this method when a {@link BluetoothCallQualityReport} is received from the
232 * bluetooth stack.
Tyler Gunn80196212021-03-11 22:43:09 -0800233 * <p>
234 * Calls to this method will use the {@link CallDiagnosticService}'s {@link Executor}; see
235 * {@link CallDiagnosticService#getExecutor()} for more information.
236 *
Tyler Gunnd5821842021-02-05 11:12:57 -0800237 * @param qualityReport the {@link BluetoothCallQualityReport}.
238 */
239 public abstract void onBluetoothCallQualityReportReceived(
240 @NonNull BluetoothCallQualityReport qualityReport);
241
242 /**
243 * Handles a request from Telecom to set the adapater used to communicate back to Telecom.
244 * @param adapter
245 */
246 private void handleSetAdapter(@NonNull ICallDiagnosticServiceAdapter adapter) {
247 mAdapter = adapter;
248 }
249
250 /**
251 * Handles a request from Telecom to add a new call.
252 * @param parcelableCall
253 */
254 private void handleCallAdded(@NonNull ParcelableCall parcelableCall) {
255 String telecomCallId = parcelableCall.getId();
256 Log.i(this, "handleCallAdded: callId=%s - added", telecomCallId);
257 Call.Details newCallDetails = Call.Details.createFromParcelableCall(parcelableCall);
Tyler Gunn80196212021-03-11 22:43:09 -0800258 synchronized (mLock) {
259 mCallByTelecomCallId.put(telecomCallId, newCallDetails);
Tyler Gunnd5821842021-02-05 11:12:57 -0800260 }
Tyler Gunn80196212021-03-11 22:43:09 -0800261
262 getExecutor().execute(() -> {
Tyler Gunn066de602021-03-16 09:58:07 -0700263 CallDiagnostics callDiagnostics = onInitializeCallDiagnostics(newCallDetails);
264 if (callDiagnostics == null) {
Tyler Gunn80196212021-03-11 22:43:09 -0800265 throw new IllegalArgumentException(
266 "A valid DiagnosticCall instance was not provided.");
267 }
268 synchronized (mLock) {
Tyler Gunn066de602021-03-16 09:58:07 -0700269 callDiagnostics.setListener(mDiagnosticCallListener);
270 callDiagnostics.setCallId(telecomCallId);
271 mDiagnosticCallByTelecomCallId.put(telecomCallId, callDiagnostics);
Tyler Gunn80196212021-03-11 22:43:09 -0800272 }
273 });
Tyler Gunnd5821842021-02-05 11:12:57 -0800274 }
275
276 /**
277 * Handles an update to {@link Call.Details} notified by Telecom.
Tyler Gunn066de602021-03-16 09:58:07 -0700278 * Caches the call details and notifies the {@link CallDiagnostics} of the change via
279 * {@link CallDiagnostics#onCallDetailsChanged(Call.Details)}.
Tyler Gunnd5821842021-02-05 11:12:57 -0800280 * @param parcelableCall the new parceled call details from Telecom.
281 */
282 private void handleCallUpdated(@NonNull ParcelableCall parcelableCall) {
283 String telecomCallId = parcelableCall.getId();
284 Log.i(this, "handleCallUpdated: callId=%s - updated", telecomCallId);
285 Call.Details newCallDetails = Call.Details.createFromParcelableCall(parcelableCall);
Tyler Gunn066de602021-03-16 09:58:07 -0700286 CallDiagnostics callDiagnostics;
Tyler Gunn80196212021-03-11 22:43:09 -0800287 synchronized (mLock) {
Tyler Gunn066de602021-03-16 09:58:07 -0700288 callDiagnostics = mDiagnosticCallByTelecomCallId.get(telecomCallId);
Tyler Gunn80196212021-03-11 22:43:09 -0800289 mCallByTelecomCallId.put(telecomCallId, newCallDetails);
290 }
Tyler Gunn066de602021-03-16 09:58:07 -0700291 getExecutor().execute(() -> callDiagnostics.handleCallUpdated(newCallDetails));
Tyler Gunnd5821842021-02-05 11:12:57 -0800292 }
293
294 /**
295 * Handles a request from Telecom to remove an existing call.
296 * @param telecomCallId
297 */
298 private void handleCallRemoved(@NonNull String telecomCallId) {
299 Log.i(this, "handleCallRemoved: callId=%s - removed", telecomCallId);
300
301 if (mCallByTelecomCallId.containsKey(telecomCallId)) {
302 mCallByTelecomCallId.remove(telecomCallId);
303 }
Tyler Gunn80196212021-03-11 22:43:09 -0800304
Tyler Gunn066de602021-03-16 09:58:07 -0700305 CallDiagnostics callDiagnostics;
Tyler Gunn80196212021-03-11 22:43:09 -0800306 synchronized (mLock) {
307 if (mDiagnosticCallByTelecomCallId.containsKey(telecomCallId)) {
Tyler Gunn066de602021-03-16 09:58:07 -0700308 callDiagnostics = mDiagnosticCallByTelecomCallId.remove(telecomCallId);
Tyler Gunn80196212021-03-11 22:43:09 -0800309 } else {
Tyler Gunn066de602021-03-16 09:58:07 -0700310 callDiagnostics = null;
Tyler Gunn80196212021-03-11 22:43:09 -0800311 }
312 }
313
314 // Inform the service of the removed call.
Tyler Gunn066de602021-03-16 09:58:07 -0700315 if (callDiagnostics != null) {
316 getExecutor().execute(() -> onRemoveCallDiagnostics(callDiagnostics));
Tyler Gunnd5821842021-02-05 11:12:57 -0800317 }
318 }
319
320 /**
321 * Handles an incoming device to device message received from Telecom. Notifies the
Tyler Gunn066de602021-03-16 09:58:07 -0700322 * {@link CallDiagnostics} via {@link CallDiagnostics#onReceiveDeviceToDeviceMessage(int, int)}.
Tyler Gunnd5821842021-02-05 11:12:57 -0800323 * @param callId
324 * @param message
325 * @param value
326 */
327 private void handleReceivedD2DMessage(@NonNull String callId, int message, int value) {
328 Log.i(this, "handleReceivedD2DMessage: callId=%s, msg=%d/%d", callId, message, value);
Tyler Gunn066de602021-03-16 09:58:07 -0700329 CallDiagnostics callDiagnostics;
Tyler Gunn80196212021-03-11 22:43:09 -0800330 synchronized (mLock) {
Tyler Gunn066de602021-03-16 09:58:07 -0700331 callDiagnostics = mDiagnosticCallByTelecomCallId.get(callId);
Tyler Gunn80196212021-03-11 22:43:09 -0800332 }
Tyler Gunn066de602021-03-16 09:58:07 -0700333 if (callDiagnostics != null) {
Tyler Gunn80196212021-03-11 22:43:09 -0800334 getExecutor().execute(
Tyler Gunn066de602021-03-16 09:58:07 -0700335 () -> callDiagnostics.onReceiveDeviceToDeviceMessage(message, value));
Tyler Gunn80196212021-03-11 22:43:09 -0800336 }
Tyler Gunnd5821842021-02-05 11:12:57 -0800337 }
338
339 /**
Tyler Gunnbc9ecbc2021-03-09 15:06:30 -0800340 * Handles a request from the Telecom framework to get a disconnect message from the
341 * {@link CallDiagnosticService}.
342 * @param callId The ID of the call.
343 * @param disconnectCause The telecom disconnect cause.
344 */
345 private void handleCallDisconnected(@NonNull String callId,
346 @NonNull DisconnectCause disconnectCause) {
347 Log.i(this, "handleCallDisconnected: call=%s; cause=%s", callId, disconnectCause);
Tyler Gunn066de602021-03-16 09:58:07 -0700348 CallDiagnostics callDiagnostics = mDiagnosticCallByTelecomCallId.get(callId);
Tyler Gunnbc9ecbc2021-03-09 15:06:30 -0800349 CharSequence message;
350 if (disconnectCause.getImsReasonInfo() != null) {
Tyler Gunn066de602021-03-16 09:58:07 -0700351 message = callDiagnostics.onCallDisconnected(disconnectCause.getImsReasonInfo());
Tyler Gunnbc9ecbc2021-03-09 15:06:30 -0800352 } else {
Tyler Gunn066de602021-03-16 09:58:07 -0700353 message = callDiagnostics.onCallDisconnected(
Tyler Gunnbc9ecbc2021-03-09 15:06:30 -0800354 disconnectCause.getTelephonyDisconnectCause(),
355 disconnectCause.getTelephonyPreciseDisconnectCause());
356 }
357 try {
358 mAdapter.overrideDisconnectMessage(callId, message);
359 } catch (RemoteException e) {
360 Log.w(this, "handleCallDisconnected: call=%s; cause=%s; %s",
361 callId, disconnectCause, e);
362 }
363 }
364
365 /**
Tyler Gunnd5821842021-02-05 11:12:57 -0800366 * Handles an incoming bluetooth call quality report from Telecom. Notifies via
367 * {@link CallDiagnosticService#onBluetoothCallQualityReportReceived(
368 * BluetoothCallQualityReport)}.
369 * @param qualityReport The bluetooth call quality remote.
370 */
371 private void handleBluetoothCallQualityReport(@NonNull BluetoothCallQualityReport
372 qualityReport) {
373 Log.i(this, "handleBluetoothCallQualityReport; report=%s", qualityReport);
Tyler Gunn80196212021-03-11 22:43:09 -0800374 getExecutor().execute(() -> onBluetoothCallQualityReportReceived(qualityReport));
Tyler Gunnd5821842021-02-05 11:12:57 -0800375 }
376
377 /**
Tyler Gunn066de602021-03-16 09:58:07 -0700378 * Handles a request from a {@link CallDiagnostics} to send a device to device message (received
379 * via {@link CallDiagnostics#sendDeviceToDeviceMessage(int, int)}.
380 * @param callDiagnostics
Tyler Gunnd5821842021-02-05 11:12:57 -0800381 * @param message
382 * @param value
383 */
Tyler Gunn066de602021-03-16 09:58:07 -0700384 private void handleSendDeviceToDeviceMessage(@NonNull CallDiagnostics callDiagnostics,
Tyler Gunnd5821842021-02-05 11:12:57 -0800385 int message, int value) {
Tyler Gunn066de602021-03-16 09:58:07 -0700386 String callId = callDiagnostics.getCallId();
Tyler Gunnd5821842021-02-05 11:12:57 -0800387 try {
388 mAdapter.sendDeviceToDeviceMessage(callId, message, value);
389 Log.i(this, "handleSendDeviceToDeviceMessage: call=%s; msg=%d/%d", callId, message,
390 value);
391 } catch (RemoteException e) {
392 Log.w(this, "handleSendDeviceToDeviceMessage: call=%s; msg=%d/%d failed %s",
393 callId, message, value, e);
394 }
395 }
396
397 /**
Tyler Gunn066de602021-03-16 09:58:07 -0700398 * Handles a request from a {@link CallDiagnostics} to display an in-call diagnostic message.
399 * Originates from {@link CallDiagnostics#displayDiagnosticMessage(int, CharSequence)}.
400 * @param callDiagnostics
Tyler Gunnd5821842021-02-05 11:12:57 -0800401 * @param messageId
402 * @param message
403 */
Tyler Gunn066de602021-03-16 09:58:07 -0700404 private void handleDisplayDiagnosticMessage(CallDiagnostics callDiagnostics, int messageId,
Tyler Gunnd5821842021-02-05 11:12:57 -0800405 CharSequence message) {
Tyler Gunn066de602021-03-16 09:58:07 -0700406 String callId = callDiagnostics.getCallId();
Tyler Gunnd5821842021-02-05 11:12:57 -0800407 try {
408 mAdapter.displayDiagnosticMessage(callId, messageId, message);
409 Log.i(this, "handleDisplayDiagnosticMessage: call=%s; msg=%d/%s", callId, messageId,
410 message);
411 } catch (RemoteException e) {
412 Log.w(this, "handleDisplayDiagnosticMessage: call=%s; msg=%d/%s failed %s",
413 callId, messageId, message, e);
414 }
415 }
416
417 /**
Tyler Gunn066de602021-03-16 09:58:07 -0700418 * Handles a request from a {@link CallDiagnostics} to clear a previously shown diagnostic
Tyler Gunnd5821842021-02-05 11:12:57 -0800419 * message.
Tyler Gunn066de602021-03-16 09:58:07 -0700420 * Originates from {@link CallDiagnostics#clearDiagnosticMessage(int)}.
421 * @param callDiagnostics
Tyler Gunnd5821842021-02-05 11:12:57 -0800422 * @param messageId
423 */
Tyler Gunn066de602021-03-16 09:58:07 -0700424 private void handleClearDiagnosticMessage(CallDiagnostics callDiagnostics, int messageId) {
425 String callId = callDiagnostics.getCallId();
Tyler Gunnd5821842021-02-05 11:12:57 -0800426 try {
427 mAdapter.clearDiagnosticMessage(callId, messageId);
428 Log.i(this, "handleClearDiagnosticMessage: call=%s; msg=%d", callId, messageId);
429 } catch (RemoteException e) {
430 Log.w(this, "handleClearDiagnosticMessage: call=%s; msg=%d failed %s",
431 callId, messageId, e);
432 }
433 }
434}