• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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 
17 package com.android.server.telecom;
18 
19 import android.net.Uri;
20 import android.os.Binder;
21 import android.os.Bundle;
22 import android.os.ResultReceiver;
23 import android.telecom.CallEndpoint;
24 import android.telecom.Log;
25 import android.telecom.PhoneAccountHandle;
26 
27 import com.android.internal.telecom.IInCallAdapter;
28 
29 import java.util.List;
30 
31 /**
32  * Receives call commands and updates from in-call app and passes them through to CallsManager.
33  * {@link InCallController} creates an instance of this class and passes it to the in-call app after
34  * binding to it. This adapter can receive commands and updates until the in-call app is unbound.
35  */
36 class InCallAdapter extends IInCallAdapter.Stub {
37     private final CallsManager mCallsManager;
38     private final CallIdMapper mCallIdMapper;
39     private final TelecomSystem.SyncRoot mLock;
40     private final String mOwnerPackageName;
41     private final String mOwnerPackageAbbreviation;
42 
43     /** Persists the specified parameters. */
InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper, TelecomSystem.SyncRoot lock, String ownerPackageName)44     public InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper,
45             TelecomSystem.SyncRoot lock, String ownerPackageName) {
46         mCallsManager = callsManager;
47         mCallIdMapper = callIdMapper;
48         mLock = lock;
49         mOwnerPackageName = ownerPackageName;
50         mOwnerPackageAbbreviation = Log.getPackageAbbreviation(ownerPackageName);
51     }
52 
53     @Override
answerCall(String callId, int videoState)54     public void answerCall(String callId, int videoState) {
55         try {
56             Log.startSession(LogUtils.Sessions.ICA_ANSWER_CALL, mOwnerPackageAbbreviation);
57             long token = Binder.clearCallingIdentity();
58             try {
59                 synchronized (mLock) {
60                     Log.d(this, "answerCall(%s,%d)", callId, videoState);
61                     Call call = mCallIdMapper.getCall(callId);
62                     if (call != null) {
63                         mCallsManager.answerCall(call, videoState);
64                     } else {
65                         Log.w(this, "answerCall, unknown call id: %s", callId);
66                     }
67                 }
68             } finally {
69                 Binder.restoreCallingIdentity(token);
70             }
71         } finally {
72             Log.endSession();
73         }
74     }
75 
76     @Override
deflectCall(String callId, Uri address)77     public void deflectCall(String callId, Uri address) {
78         try {
79             Log.startSession(LogUtils.Sessions.ICA_DEFLECT_CALL, mOwnerPackageAbbreviation);
80             long token = Binder.clearCallingIdentity();
81             try {
82                 synchronized (mLock) {
83                     Log.i(this, "deflectCall - %s, %s ", callId, Log.pii(address));
84                     Call call = mCallIdMapper.getCall(callId);
85                     if (call != null) {
86                         mCallsManager.deflectCall(call, address);
87                     } else {
88                         Log.w(this, "deflectCall, unknown call id: %s", callId);
89                     }
90                 }
91             } finally {
92                 Binder.restoreCallingIdentity(token);
93             }
94         } finally {
95             Log.endSession();
96         }
97     }
98 
99     @Override
rejectCall(String callId, boolean rejectWithMessage, String textMessage)100     public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
101         try {
102             Log.startSession(LogUtils.Sessions.ICA_REJECT_CALL, mOwnerPackageAbbreviation);
103 
104             int callingUid = Binder.getCallingUid();
105             long token = Binder.clearCallingIdentity();
106             try {
107                 synchronized (mLock) {
108                     // Check to make sure the in-call app's user isn't restricted from sending SMS.
109                     // If so, silently drop the outgoing message. Also drop message if the screen is
110                     // locked.
111                     if (!mCallsManager.isReplyWithSmsAllowed(callingUid)) {
112                         rejectWithMessage = false;
113                         textMessage = null;
114                     }
115 
116                     Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage);
117                     Call call = mCallIdMapper.getCall(callId);
118                     if (call != null) {
119                         mCallsManager.rejectCall(call, rejectWithMessage, textMessage);
120                     } else {
121                         Log.w(this, "setRingback, unknown call id: %s", callId);
122                     }
123                 }
124             } finally {
125                 Binder.restoreCallingIdentity(token);
126             }
127         } finally {
128             Log.endSession();
129         }
130     }
131 
132     @Override
rejectCallWithReason(String callId, @android.telecom.Call.RejectReason int rejectReason)133     public void rejectCallWithReason(String callId,
134             @android.telecom.Call.RejectReason int rejectReason) {
135         try {
136             Log.startSession(LogUtils.Sessions.ICA_REJECT_CALL, mOwnerPackageAbbreviation);
137 
138             int callingUid = Binder.getCallingUid();
139             long token = Binder.clearCallingIdentity();
140             try {
141                 synchronized (mLock) {
142                     Log.d(this, "rejectCallWithReason(%s,%d)", callId, rejectReason);
143                     Call call = mCallIdMapper.getCall(callId);
144                     if (call != null) {
145                         mCallsManager.rejectCall(call, rejectReason);
146                     } else {
147                         Log.w(this, "rejectCallWithReason, unknown call id: %s", callId);
148                     }
149                 }
150             } finally {
151                 Binder.restoreCallingIdentity(token);
152             }
153         } finally {
154             Log.endSession();
155         }
156     }
157 
transferCall(String callId, Uri targetNumber, boolean isConfirmationRequired)158     public void transferCall(String callId, Uri targetNumber, boolean isConfirmationRequired) {
159         try {
160             Log.startSession(LogUtils.Sessions.ICA_TRANSFER_CALL, mOwnerPackageAbbreviation);
161             long token = Binder.clearCallingIdentity();
162             try {
163                 synchronized (mLock) {
164                     Log.i(this, "transferCall - %s, %s, %b", callId, Log.pii(targetNumber),
165                             isConfirmationRequired);
166                     Call call = mCallIdMapper.getCall(callId);
167                     if (call != null) {
168                         mCallsManager.transferCall(call, targetNumber, isConfirmationRequired);
169                     } else {
170                         Log.w(this, "transferCall, unknown call id: %s", callId);
171                     }
172                 }
173             } finally {
174                 Binder.restoreCallingIdentity(token);
175             }
176         } finally {
177             Log.endSession();
178         }
179     }
180 
181     @Override
consultativeTransfer(String callId, String otherCallId)182     public void consultativeTransfer(String callId, String otherCallId) {
183         try {
184             Log.startSession(LogUtils.Sessions.ICA_CONSULTATIVE_TRANSFER,
185                     mOwnerPackageAbbreviation);
186             long token = Binder.clearCallingIdentity();
187             try {
188                 synchronized (mLock) {
189                     Log.i(this, "consultativeTransfer - %s, %s", callId, otherCallId);
190                     Call call = mCallIdMapper.getCall(callId);
191                     Call otherCall = mCallIdMapper.getCall(otherCallId);
192                     if (call != null && otherCall != null) {
193                         mCallsManager.transferCall(call, otherCall);
194                     } else {
195                         Log.w(this, "consultativeTransfer, unknown call id: %s or %s",
196                                 callId, otherCallId);
197                     }
198                 }
199             } finally {
200                 Binder.restoreCallingIdentity(token);
201             }
202         } finally {
203             Log.endSession();
204         }
205     }
206 
207     @Override
playDtmfTone(String callId, char digit)208     public void playDtmfTone(String callId, char digit) {
209         try {
210             Log.startSession("ICA.pDT", mOwnerPackageAbbreviation);
211             long token = Binder.clearCallingIdentity();
212             try {
213                 synchronized (mLock) {
214                     Log.d(this, "playDtmfTone(%s,%c)", callId, digit);
215                     Call call = mCallIdMapper.getCall(callId);
216                     if (call != null) {
217                         mCallsManager.playDtmfTone(call, digit);
218                     } else {
219                         Log.w(this, "playDtmfTone, unknown call id: %s", callId);
220                     }
221                 }
222             } finally {
223                 Binder.restoreCallingIdentity(token);
224             }
225         } finally {
226             Log.endSession();
227         }
228     }
229 
230     @Override
stopDtmfTone(String callId)231     public void stopDtmfTone(String callId) {
232         try {
233             Log.startSession("ICA.sDT", mOwnerPackageAbbreviation);
234             long token = Binder.clearCallingIdentity();
235             try {
236                 synchronized (mLock) {
237                     Log.d(this, "stopDtmfTone(%s)", callId);
238                     Call call = mCallIdMapper.getCall(callId);
239                     if (call != null) {
240                         mCallsManager.stopDtmfTone(call);
241                     } else {
242                         Log.w(this, "stopDtmfTone, unknown call id: %s", callId);
243                     }
244                 }
245             } finally {
246                 Binder.restoreCallingIdentity(token);
247             }
248         } finally {
249             Log.endSession();
250         }
251     }
252 
253     @Override
postDialContinue(String callId, boolean proceed)254     public void postDialContinue(String callId, boolean proceed) {
255         try {
256             Log.startSession("ICA.pDC", mOwnerPackageAbbreviation);
257             long token = Binder.clearCallingIdentity();
258             try {
259                 synchronized (mLock) {
260                     Log.d(this, "postDialContinue(%s)", callId);
261                     Call call = mCallIdMapper.getCall(callId);
262                     if (call != null) {
263                         mCallsManager.postDialContinue(call, proceed);
264                     } else {
265                         Log.w(this, "postDialContinue, unknown call id: %s", callId);
266                     }
267                 }
268             } finally {
269                 Binder.restoreCallingIdentity(token);
270             }
271         } finally {
272             Log.endSession();
273         }
274     }
275 
276     @Override
disconnectCall(String callId)277     public void disconnectCall(String callId) {
278         try {
279             Log.startSession(LogUtils.Sessions.ICA_DISCONNECT_CALL, mOwnerPackageAbbreviation);
280             long token = Binder.clearCallingIdentity();
281             try {
282                 synchronized (mLock) {
283                     Log.v(this, "disconnectCall: %s", callId);
284                     Call call = mCallIdMapper.getCall(callId);
285                     if (call != null) {
286                         mCallsManager.disconnectCall(call);
287                     } else {
288                         Log.w(this, "disconnectCall, unknown call id: %s", callId);
289                     }
290                 }
291             } finally {
292                 Binder.restoreCallingIdentity(token);
293             }
294         } finally {
295             Log.endSession();
296         }
297     }
298 
299     @Override
holdCall(String callId)300     public void holdCall(String callId) {
301         try {
302             Log.startSession(LogUtils.Sessions.ICA_HOLD_CALL, mOwnerPackageAbbreviation);
303             long token = Binder.clearCallingIdentity();
304             try {
305                 synchronized (mLock) {
306                     Call call = mCallIdMapper.getCall(callId);
307                     if (call != null) {
308                         mCallsManager.holdCall(call);
309                     } else {
310                         Log.w(this, "holdCall, unknown call id: %s", callId);
311                     }
312                 }
313             } finally {
314                 Binder.restoreCallingIdentity(token);
315             }
316         } finally {
317             Log.endSession();
318         }
319     }
320 
321     @Override
unholdCall(String callId)322     public void unholdCall(String callId) {
323         try {
324             Log.startSession(LogUtils.Sessions.ICA_UNHOLD_CALL, mOwnerPackageAbbreviation);
325             long token = Binder.clearCallingIdentity();
326             try {
327                 synchronized (mLock) {
328                     Call call = mCallIdMapper.getCall(callId);
329                     if (call != null) {
330                         mCallsManager.unholdCall(call);
331                     } else {
332                         Log.w(this, "unholdCall, unknown call id: %s", callId);
333                     }
334                 }
335             } finally {
336                 Binder.restoreCallingIdentity(token);
337             }
338         } finally {
339             Log.endSession();
340         }
341     }
342 
343     @Override
phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, boolean setDefault)344     public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle,
345             boolean setDefault) {
346         try {
347             Log.startSession("ICA.pAS", mOwnerPackageAbbreviation);
348             long token = Binder.clearCallingIdentity();
349             try {
350                 synchronized (mLock) {
351                     Call call = mCallIdMapper.getCall(callId);
352                     if (call != null) {
353                         mCallsManager.phoneAccountSelected(call, accountHandle, setDefault);
354                     } else {
355                         Log.w(this, "phoneAccountSelected, unknown call id: %s", callId);
356                     }
357                 }
358             } finally {
359                 Binder.restoreCallingIdentity(token);
360             }
361         } finally {
362             Log.endSession();
363         }
364     }
365 
366     @Override
mute(boolean shouldMute)367     public void mute(boolean shouldMute) {
368         try {
369             Log.startSession(LogUtils.Sessions.ICA_MUTE, mOwnerPackageAbbreviation);
370             long token = Binder.clearCallingIdentity();
371             try {
372                 synchronized (mLock) {
373                     mCallsManager.mute(shouldMute);
374                 }
375             } finally {
376                 Binder.restoreCallingIdentity(token);
377             }
378         } finally {
379             Log.endSession();
380         }
381     }
382 
383     @Override
setAudioRoute(int route, String bluetoothAddress)384     public void setAudioRoute(int route, String bluetoothAddress) {
385         try {
386             Log.startSession(LogUtils.Sessions.ICA_SET_AUDIO_ROUTE, mOwnerPackageAbbreviation);
387             long token = Binder.clearCallingIdentity();
388             try {
389                 synchronized (mLock) {
390                     mCallsManager.setAudioRoute(route, bluetoothAddress);
391                 }
392             } finally {
393                 Binder.restoreCallingIdentity(token);
394             }
395         } finally {
396             Log.endSession();
397         }
398     }
399 
400     @Override
requestCallEndpointChange(CallEndpoint endpoint, ResultReceiver callback)401     public void requestCallEndpointChange(CallEndpoint endpoint, ResultReceiver callback) {
402         try {
403             Log.startSession(LogUtils.Sessions.ICA_SET_AUDIO_ROUTE, mOwnerPackageAbbreviation);
404             long token = Binder.clearCallingIdentity();
405             try {
406                 synchronized (mLock) {
407                     mCallsManager.requestCallEndpointChange(endpoint, callback);
408                 }
409             } finally {
410                 Binder.restoreCallingIdentity(token);
411             }
412         } finally {
413             Log.endSession();
414         }
415     }
416 
417     @Override
enterBackgroundAudioProcessing(String callId)418     public void enterBackgroundAudioProcessing(String callId) {
419         try {
420             Log.startSession(LogUtils.Sessions.ICA_ENTER_AUDIO_PROCESSING,
421                     mOwnerPackageAbbreviation);
422             // TODO: enforce the extra permission.
423             Binder.withCleanCallingIdentity(() -> {
424                 synchronized (mLock) {
425                     Call call = mCallIdMapper.getCall(callId);
426                     if (call != null) {
427                         mCallsManager.enterBackgroundAudioProcessing(call, mOwnerPackageName);
428                     } else {
429                         Log.w(this, "enterBackgroundAudioProcessing, unknown call id: %s", callId);
430                     }
431                 }
432             });
433         } finally {
434             Log.endSession();
435         }
436     }
437 
438     @Override
exitBackgroundAudioProcessing(String callId, boolean shouldRing)439     public void exitBackgroundAudioProcessing(String callId, boolean shouldRing) {
440         try {
441             Log.startSession(LogUtils.Sessions.ICA_EXIT_AUDIO_PROCESSING,
442                     mOwnerPackageAbbreviation);
443             Binder.withCleanCallingIdentity(() -> {
444                 synchronized (mLock) {
445                     Call call = mCallIdMapper.getCall(callId);
446                     if (call != null) {
447                         mCallsManager.exitBackgroundAudioProcessing(call, shouldRing);
448                     } else {
449                         Log.w(InCallAdapter.this,
450                                 "exitBackgroundAudioProcessing, unknown call id: %s", callId);
451                     }
452                 }
453             });
454         } finally {
455             Log.endSession();
456         }
457     }
458 
459     @Override
conference(String callId, String otherCallId)460     public void conference(String callId, String otherCallId) {
461         try {
462             Log.startSession(LogUtils.Sessions.ICA_CONFERENCE, mOwnerPackageAbbreviation);
463             long token = Binder.clearCallingIdentity();
464             try {
465                 synchronized (mLock) {
466                     Call call = mCallIdMapper.getCall(callId);
467                     Call otherCall = mCallIdMapper.getCall(otherCallId);
468                     if (call != null && otherCall != null) {
469                         mCallsManager.conference(call, otherCall);
470                     } else {
471                         Log.w(this, "conference, unknown call id: %s or %s", callId, otherCallId);
472                     }
473                 }
474             } finally {
475                 Binder.restoreCallingIdentity(token);
476             }
477         } finally {
478             Log.endSession();
479         }
480     }
481 
482     @Override
splitFromConference(String callId)483     public void splitFromConference(String callId) {
484         try {
485             Log.startSession("ICA.sFC", mOwnerPackageAbbreviation);
486             long token = Binder.clearCallingIdentity();
487             try {
488                 synchronized (mLock) {
489                     Call call = mCallIdMapper.getCall(callId);
490                     if (call != null) {
491                         call.splitFromConference();
492                     } else {
493                         Log.w(this, "splitFromConference, unknown call id: %s", callId);
494                     }
495                 }
496             } finally {
497                 Binder.restoreCallingIdentity(token);
498             }
499         } finally {
500             Log.endSession();
501         }
502     }
503 
504     @Override
mergeConference(String callId)505     public void mergeConference(String callId) {
506         try {
507             Log.startSession("ICA.mC", mOwnerPackageAbbreviation);
508             long token = Binder.clearCallingIdentity();
509             try {
510                 synchronized (mLock) {
511                     Call call = mCallIdMapper.getCall(callId);
512                     if (call != null) {
513                         call.mergeConference();
514                     } else {
515                         Log.w(this, "mergeConference, unknown call id: %s", callId);
516                     }
517                 }
518             } finally {
519                 Binder.restoreCallingIdentity(token);
520             }
521         } finally {
522             Log.endSession();
523         }
524     }
525 
526     @Override
swapConference(String callId)527     public void swapConference(String callId) {
528         try {
529             Log.startSession("ICA.sC", mOwnerPackageAbbreviation);
530             long token = Binder.clearCallingIdentity();
531             try {
532                 synchronized (mLock) {
533                     Call call = mCallIdMapper.getCall(callId);
534                     if (call != null) {
535                         call.swapConference();
536                     } else {
537                         Log.w(this, "swapConference, unknown call id: %s", callId);
538                     }
539                 }
540             } finally {
541                 Binder.restoreCallingIdentity(token);
542             }
543         } finally {
544             Log.endSession();
545         }
546     }
547 
548     @Override
addConferenceParticipants(String callId, List<Uri> participants)549     public void addConferenceParticipants(String callId, List<Uri> participants) {
550         try {
551             Log.startSession("ICA.aCP", mOwnerPackageAbbreviation);
552             long token = Binder.clearCallingIdentity();
553             try {
554                 synchronized (mLock) {
555                     Call call = mCallIdMapper.getCall(callId);
556                     if (call != null) {
557                         call.addConferenceParticipants(participants);
558                     } else {
559                         Log.w(this, "addConferenceParticipants, unknown call id: %s", callId);
560                     }
561                 }
562             } finally {
563                 Binder.restoreCallingIdentity(token);
564             }
565         } finally {
566             Log.endSession();
567         }
568     }
569 
570 
571     @Override
pullExternalCall(String callId)572     public void pullExternalCall(String callId) {
573         try {
574             Log.startSession("ICA.pEC", mOwnerPackageAbbreviation);
575             long token = Binder.clearCallingIdentity();
576             try {
577                 synchronized (mLock) {
578                     Call call = mCallIdMapper.getCall(callId);
579                     if (call != null) {
580                         call.pullExternalCall();
581                     } else {
582                         Log.w(this, "pullExternalCall, unknown call id: %s", callId);
583                     }
584                 }
585             } finally {
586                 Binder.restoreCallingIdentity(token);
587             }
588         } finally {
589             Log.endSession();
590         }
591     }
592 
593     @Override
sendCallEvent(String callId, String event, int targetSdkVer, Bundle extras)594     public void sendCallEvent(String callId, String event, int targetSdkVer, Bundle extras) {
595         try {
596             Log.startSession("ICA.sCE", mOwnerPackageAbbreviation);
597             long token = Binder.clearCallingIdentity();
598             try {
599                 synchronized (mLock) {
600                     Call call = mCallIdMapper.getCall(callId);
601                     if (call != null) {
602                         call.sendCallEvent(event, targetSdkVer, extras);
603                     } else {
604                         Log.w(this, "sendCallEvent, unknown call id: %s", callId);
605                     }
606                 }
607             } finally {
608                 Binder.restoreCallingIdentity(token);
609             }
610         } finally {
611             Log.endSession();
612         }
613     }
614 
615     @Override
putExtras(String callId, Bundle extras)616     public void putExtras(String callId, Bundle extras) {
617         try {
618             Log.startSession("ICA.pE", mOwnerPackageAbbreviation);
619             long token = Binder.clearCallingIdentity();
620             try {
621                 synchronized (mLock) {
622                     Call call = mCallIdMapper.getCall(callId);
623                     if (call != null) {
624                         // Make sure to identify the ICS that originated the extras change so that
625                         // InCallController can propagate these out to other ICSes.
626                         call.putInCallServiceExtras(extras, mOwnerPackageName);
627                     } else {
628                         Log.w(this, "putExtras, unknown call id: %s", callId);
629                     }
630                 }
631             } finally {
632                 Binder.restoreCallingIdentity(token);
633             }
634         } finally {
635             Log.endSession();
636         }
637     }
638 
639     @Override
removeExtras(String callId, List<String> keys)640     public void removeExtras(String callId, List<String> keys) {
641         try {
642             Log.startSession("ICA.rE", mOwnerPackageAbbreviation);
643             long token = Binder.clearCallingIdentity();
644             try {
645                 synchronized (mLock) {
646                     Call call = mCallIdMapper.getCall(callId);
647                     if (call != null) {
648                         call.removeExtras(Call.SOURCE_INCALL_SERVICE, keys);
649                     } else {
650                         Log.w(this, "removeExtra, unknown call id: %s", callId);
651                     }
652                 }
653             } finally {
654                 Binder.restoreCallingIdentity(token);
655             }
656         } finally {
657             Log.endSession();
658         }
659     }
660 
661     @Override
turnOnProximitySensor()662     public void turnOnProximitySensor() {
663         try {
664             Log.startSession("ICA.tOnPS", mOwnerPackageAbbreviation);
665             long token = Binder.clearCallingIdentity();
666             try {
667                 synchronized (mLock) {
668                     mCallsManager.turnOnProximitySensor();
669                 }
670             } finally {
671                 Binder.restoreCallingIdentity(token);
672             }
673         } finally {
674             Log.endSession();
675         }
676     }
677 
678     @Override
turnOffProximitySensor(boolean screenOnImmediately)679     public void turnOffProximitySensor(boolean screenOnImmediately) {
680         try {
681             Log.startSession("ICA.tOffPS", mOwnerPackageAbbreviation);
682             long token = Binder.clearCallingIdentity();
683             try {
684                 synchronized (mLock) {
685                     mCallsManager.turnOffProximitySensor(screenOnImmediately);
686                 }
687             } finally {
688                 Binder.restoreCallingIdentity(token);
689             }
690         } finally {
691              Log.endSession();
692         }
693     }
694 
695     @Override
sendRttRequest(String callId)696     public void sendRttRequest(String callId) {
697         try {
698             Log.startSession("ICA.sRR", mOwnerPackageAbbreviation);
699             long token = Binder.clearCallingIdentity();
700             try {
701                 synchronized (mLock) {
702                     Call call = mCallIdMapper.getCall(callId);
703                     if (call != null) {
704                         call.sendRttRequest();
705                     } else {
706                         Log.w(this, "stopRtt(): call %s not found", callId);
707                     }
708                 }
709             } finally {
710                 Binder.restoreCallingIdentity(token);
711             }
712         } finally {
713             Log.endSession();
714         }
715     }
716 
717     @Override
respondToRttRequest(String callId, int id, boolean accept)718     public void respondToRttRequest(String callId, int id, boolean accept) {
719         try {
720             Log.startSession("ICA.rTRR", mOwnerPackageAbbreviation);
721             long token = Binder.clearCallingIdentity();
722             try {
723                 synchronized (mLock) {
724                     Call call = mCallIdMapper.getCall(callId);
725                     if (call != null) {
726                         call.handleRttRequestResponse(id, accept);
727                     } else {
728                         Log.w(this, "respondToRttRequest(): call %s not found", callId);
729                     }
730                 }
731             } finally {
732                 Binder.restoreCallingIdentity(token);
733             }
734         } finally {
735             Log.endSession();
736         }
737     }
738 
739     @Override
stopRtt(String callId)740     public void stopRtt(String callId) {
741         try {
742             Log.startSession("ICA.sRTT", mOwnerPackageAbbreviation);
743             long token = Binder.clearCallingIdentity();
744             try {
745                 synchronized (mLock) {
746                     Call call = mCallIdMapper.getCall(callId);
747                     if (call != null) {
748                         call.stopRtt();
749                     } else {
750                         Log.w(this, "stopRtt(): call %s not found", callId);
751                     }
752                 }
753             } finally {
754                 Binder.restoreCallingIdentity(token);
755             }
756         } finally {
757             Log.endSession();
758         }
759     }
760 
761     @Override
setRttMode(String callId, int mode)762     public void setRttMode(String callId, int mode) {
763         try {
764             Log.startSession("ICA.sRM", mOwnerPackageAbbreviation);
765             long token = Binder.clearCallingIdentity();
766             try {
767                 synchronized (mLock) {
768                     Call call = mCallIdMapper.getCall(callId);
769                     if (call != null) {
770                         call.setRttMode(mode);
771                     } else {
772                         Log.w(this, "setRttMode(): call %s not found", callId);
773                     }
774                 }
775             } finally {
776                 Binder.restoreCallingIdentity(token);
777             }
778         } finally {
779             Log.endSession();
780         }
781     }
782 
783     @Override
handoverTo(String callId, PhoneAccountHandle destAcct, int videoState, Bundle extras)784     public void handoverTo(String callId, PhoneAccountHandle destAcct, int videoState,
785                            Bundle extras) {
786         try {
787             Log.startSession("ICA.hT", mOwnerPackageAbbreviation);
788             long token = Binder.clearCallingIdentity();
789             try {
790                 synchronized (mLock) {
791                     Call call = mCallIdMapper.getCall(callId);
792                     if (call != null) {
793                         call.handoverTo(destAcct, videoState, extras);
794                     } else {
795                         Log.w(this, "handoverTo, unknown call id: %s", callId);
796                     }
797                 }
798             } finally {
799                 Binder.restoreCallingIdentity(token);
800             }
801         } finally {
802             Log.endSession();
803         }
804     }
805 }
806