• 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.telecom.Log;
23 import android.telecom.PhoneAccountHandle;
24 
25 import com.android.internal.telecom.IInCallAdapter;
26 
27 import java.util.List;
28 
29 /**
30  * Receives call commands and updates from in-call app and passes them through to CallsManager.
31  * {@link InCallController} creates an instance of this class and passes it to the in-call app after
32  * binding to it. This adapter can receive commands and updates until the in-call app is unbound.
33  */
34 class InCallAdapter extends IInCallAdapter.Stub {
35     private final CallsManager mCallsManager;
36     private final CallIdMapper mCallIdMapper;
37     private final TelecomSystem.SyncRoot mLock;
38     private final String mOwnerComponentName;
39 
40     /** Persists the specified parameters. */
InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper, TelecomSystem.SyncRoot lock, String ownerComponentName)41     public InCallAdapter(CallsManager callsManager, CallIdMapper callIdMapper,
42             TelecomSystem.SyncRoot lock, String ownerComponentName) {
43         mCallsManager = callsManager;
44         mCallIdMapper = callIdMapper;
45         mLock = lock;
46         mOwnerComponentName = ownerComponentName;
47     }
48 
49     @Override
answerCall(String callId, int videoState)50     public void answerCall(String callId, int videoState) {
51         try {
52             Log.startSession(LogUtils.Sessions.ICA_ANSWER_CALL, mOwnerComponentName);
53             long token = Binder.clearCallingIdentity();
54             try {
55                 synchronized (mLock) {
56                     Log.d(this, "answerCall(%s,%d)", callId, videoState);
57                     Call call = mCallIdMapper.getCall(callId);
58                     if (call != null) {
59                         mCallsManager.answerCall(call, videoState);
60                     } else {
61                         Log.w(this, "answerCall, unknown call id: %s", callId);
62                     }
63                 }
64             } finally {
65                 Binder.restoreCallingIdentity(token);
66             }
67         } finally {
68             Log.endSession();
69         }
70     }
71 
72     @Override
deflectCall(String callId, Uri address)73     public void deflectCall(String callId, Uri address) {
74         try {
75             Log.startSession(LogUtils.Sessions.ICA_DEFLECT_CALL, mOwnerComponentName);
76             long token = Binder.clearCallingIdentity();
77             try {
78                 synchronized (mLock) {
79                     Log.i(this, "deflectCall - %s, %s ", callId, Log.pii(address));
80                     Call call = mCallIdMapper.getCall(callId);
81                     if (call != null) {
82                         mCallsManager.deflectCall(call, address);
83                     } else {
84                         Log.w(this, "deflectCall, unknown call id: %s", callId);
85                     }
86                 }
87             } finally {
88                 Binder.restoreCallingIdentity(token);
89             }
90         } finally {
91             Log.endSession();
92         }
93     }
94 
95     @Override
rejectCall(String callId, boolean rejectWithMessage, String textMessage)96     public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
97         try {
98             Log.startSession(LogUtils.Sessions.ICA_REJECT_CALL, mOwnerComponentName);
99             // Check to make sure the in-call app's user isn't restricted from sending SMS. If so,
100             // silently drop the outgoing message. Also drop message if the screen is locked.
101             if (!mCallsManager.isReplyWithSmsAllowed(Binder.getCallingUid())) {
102                 rejectWithMessage = false;
103                 textMessage = null;
104             }
105             long token = Binder.clearCallingIdentity();
106             try {
107                 synchronized (mLock) {
108                     Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage);
109                     Call call = mCallIdMapper.getCall(callId);
110                     if (call != null) {
111                         mCallsManager.rejectCall(call, rejectWithMessage, textMessage);
112                     } else {
113                         Log.w(this, "setRingback, unknown call id: %s", callId);
114                     }
115                 }
116             } finally {
117                 Binder.restoreCallingIdentity(token);
118             }
119         } finally {
120             Log.endSession();
121         }
122     }
123 
124     @Override
playDtmfTone(String callId, char digit)125     public void playDtmfTone(String callId, char digit) {
126         try {
127             Log.startSession("ICA.pDT", mOwnerComponentName);
128             long token = Binder.clearCallingIdentity();
129             try {
130                 synchronized (mLock) {
131                     Log.d(this, "playDtmfTone(%s,%c)", callId, digit);
132                     Call call = mCallIdMapper.getCall(callId);
133                     if (call != null) {
134                         mCallsManager.playDtmfTone(call, digit);
135                     } else {
136                         Log.w(this, "playDtmfTone, unknown call id: %s", callId);
137                     }
138                 }
139             } finally {
140                 Binder.restoreCallingIdentity(token);
141             }
142         } finally {
143             Log.endSession();
144         }
145     }
146 
147     @Override
stopDtmfTone(String callId)148     public void stopDtmfTone(String callId) {
149         try {
150             Log.startSession("ICA.sDT", mOwnerComponentName);
151             long token = Binder.clearCallingIdentity();
152             try {
153                 synchronized (mLock) {
154                     Log.d(this, "stopDtmfTone(%s)", callId);
155                     Call call = mCallIdMapper.getCall(callId);
156                     if (call != null) {
157                         mCallsManager.stopDtmfTone(call);
158                     } else {
159                         Log.w(this, "stopDtmfTone, unknown call id: %s", callId);
160                     }
161                 }
162             } finally {
163                 Binder.restoreCallingIdentity(token);
164             }
165         } finally {
166             Log.endSession();
167         }
168     }
169 
170     @Override
postDialContinue(String callId, boolean proceed)171     public void postDialContinue(String callId, boolean proceed) {
172         try {
173             Log.startSession("ICA.pDC", mOwnerComponentName);
174             long token = Binder.clearCallingIdentity();
175             try {
176                 synchronized (mLock) {
177                     Log.d(this, "postDialContinue(%s)", callId);
178                     Call call = mCallIdMapper.getCall(callId);
179                     if (call != null) {
180                         mCallsManager.postDialContinue(call, proceed);
181                     } else {
182                         Log.w(this, "postDialContinue, unknown call id: %s", callId);
183                     }
184                 }
185             } finally {
186                 Binder.restoreCallingIdentity(token);
187             }
188         } finally {
189             Log.endSession();
190         }
191     }
192 
193     @Override
disconnectCall(String callId)194     public void disconnectCall(String callId) {
195         try {
196             Log.startSession(LogUtils.Sessions.ICA_DISCONNECT_CALL, mOwnerComponentName);
197             long token = Binder.clearCallingIdentity();
198             try {
199                 synchronized (mLock) {
200                     Log.v(this, "disconnectCall: %s", callId);
201                     Call call = mCallIdMapper.getCall(callId);
202                     if (call != null) {
203                         mCallsManager.disconnectCall(call);
204                     } else {
205                         Log.w(this, "disconnectCall, unknown call id: %s", callId);
206                     }
207                 }
208             } finally {
209                 Binder.restoreCallingIdentity(token);
210             }
211         } finally {
212             Log.endSession();
213         }
214     }
215 
216     @Override
holdCall(String callId)217     public void holdCall(String callId) {
218         try {
219             Log.startSession(LogUtils.Sessions.ICA_HOLD_CALL, mOwnerComponentName);
220             long token = Binder.clearCallingIdentity();
221             try {
222                 synchronized (mLock) {
223                     Call call = mCallIdMapper.getCall(callId);
224                     if (call != null) {
225                         mCallsManager.holdCall(call);
226                     } else {
227                         Log.w(this, "holdCall, unknown call id: %s", callId);
228                     }
229                 }
230             } finally {
231                 Binder.restoreCallingIdentity(token);
232             }
233         } finally {
234             Log.endSession();
235         }
236     }
237 
238     @Override
unholdCall(String callId)239     public void unholdCall(String callId) {
240         try {
241             Log.startSession(LogUtils.Sessions.ICA_UNHOLD_CALL, mOwnerComponentName);
242             long token = Binder.clearCallingIdentity();
243             try {
244                 synchronized (mLock) {
245                     Call call = mCallIdMapper.getCall(callId);
246                     if (call != null) {
247                         mCallsManager.unholdCall(call);
248                     } else {
249                         Log.w(this, "unholdCall, unknown call id: %s", callId);
250                     }
251                 }
252             } finally {
253                 Binder.restoreCallingIdentity(token);
254             }
255         } finally {
256             Log.endSession();
257         }
258     }
259 
260     @Override
phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, boolean setDefault)261     public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle,
262             boolean setDefault) {
263         try {
264             Log.startSession("ICA.pAS", mOwnerComponentName);
265             long token = Binder.clearCallingIdentity();
266             try {
267                 synchronized (mLock) {
268                     Call call = mCallIdMapper.getCall(callId);
269                     if (call != null) {
270                         mCallsManager.phoneAccountSelected(call, accountHandle, setDefault);
271                     } else {
272                         Log.w(this, "phoneAccountSelected, unknown call id: %s", callId);
273                     }
274                 }
275             } finally {
276                 Binder.restoreCallingIdentity(token);
277             }
278         } finally {
279             Log.endSession();
280         }
281     }
282 
283     @Override
mute(boolean shouldMute)284     public void mute(boolean shouldMute) {
285         try {
286             Log.startSession(LogUtils.Sessions.ICA_MUTE, mOwnerComponentName);
287             long token = Binder.clearCallingIdentity();
288             try {
289                 synchronized (mLock) {
290                     mCallsManager.mute(shouldMute);
291                 }
292             } finally {
293                 Binder.restoreCallingIdentity(token);
294             }
295         } finally {
296             Log.endSession();
297         }
298     }
299 
300     @Override
setAudioRoute(int route, String bluetoothAddress)301     public void setAudioRoute(int route, String bluetoothAddress) {
302         try {
303             Log.startSession(LogUtils.Sessions.ICA_SET_AUDIO_ROUTE, mOwnerComponentName);
304             long token = Binder.clearCallingIdentity();
305             try {
306                 synchronized (mLock) {
307                     mCallsManager.setAudioRoute(route, bluetoothAddress);
308                 }
309             } finally {
310                 Binder.restoreCallingIdentity(token);
311             }
312         } finally {
313             Log.endSession();
314         }
315     }
316 
317     @Override
conference(String callId, String otherCallId)318     public void conference(String callId, String otherCallId) {
319         try {
320             Log.startSession(LogUtils.Sessions.ICA_CONFERENCE, mOwnerComponentName);
321             long token = Binder.clearCallingIdentity();
322             try {
323                 synchronized (mLock) {
324                     Call call = mCallIdMapper.getCall(callId);
325                     Call otherCall = mCallIdMapper.getCall(otherCallId);
326                     if (call != null && otherCall != null) {
327                         mCallsManager.conference(call, otherCall);
328                     } else {
329                         Log.w(this, "conference, unknown call id: %s or %s", callId, otherCallId);
330                     }
331                 }
332             } finally {
333                 Binder.restoreCallingIdentity(token);
334             }
335         } finally {
336             Log.endSession();
337         }
338     }
339 
340     @Override
splitFromConference(String callId)341     public void splitFromConference(String callId) {
342         try {
343             Log.startSession("ICA.sFC", mOwnerComponentName);
344             long token = Binder.clearCallingIdentity();
345             try {
346                 synchronized (mLock) {
347                     Call call = mCallIdMapper.getCall(callId);
348                     if (call != null) {
349                         call.splitFromConference();
350                     } else {
351                         Log.w(this, "splitFromConference, unknown call id: %s", callId);
352                     }
353                 }
354             } finally {
355                 Binder.restoreCallingIdentity(token);
356             }
357         } finally {
358             Log.endSession();
359         }
360     }
361 
362     @Override
mergeConference(String callId)363     public void mergeConference(String callId) {
364         try {
365             Log.startSession("ICA.mC", mOwnerComponentName);
366             long token = Binder.clearCallingIdentity();
367             try {
368                 synchronized (mLock) {
369                     Call call = mCallIdMapper.getCall(callId);
370                     if (call != null) {
371                         call.mergeConference();
372                     } else {
373                         Log.w(this, "mergeConference, unknown call id: %s", callId);
374                     }
375                 }
376             } finally {
377                 Binder.restoreCallingIdentity(token);
378             }
379         } finally {
380             Log.endSession();
381         }
382     }
383 
384     @Override
swapConference(String callId)385     public void swapConference(String callId) {
386         try {
387             Log.startSession("ICA.sC", mOwnerComponentName);
388             long token = Binder.clearCallingIdentity();
389             try {
390                 synchronized (mLock) {
391                     Call call = mCallIdMapper.getCall(callId);
392                     if (call != null) {
393                         call.swapConference();
394                     } else {
395                         Log.w(this, "swapConference, unknown call id: %s", callId);
396                     }
397                 }
398             } finally {
399                 Binder.restoreCallingIdentity(token);
400             }
401         } finally {
402             Log.endSession();
403         }
404     }
405 
406     @Override
pullExternalCall(String callId)407     public void pullExternalCall(String callId) {
408         try {
409             Log.startSession("ICA.pEC", mOwnerComponentName);
410             long token = Binder.clearCallingIdentity();
411             try {
412                 synchronized (mLock) {
413                     Call call = mCallIdMapper.getCall(callId);
414                     if (call != null) {
415                         call.pullExternalCall();
416                     } else {
417                         Log.w(this, "pullExternalCall, unknown call id: %s", callId);
418                     }
419                 }
420             } finally {
421                 Binder.restoreCallingIdentity(token);
422             }
423         } finally {
424             Log.endSession();
425         }
426     }
427 
428     @Override
sendCallEvent(String callId, String event, int targetSdkVer, Bundle extras)429     public void sendCallEvent(String callId, String event, int targetSdkVer, Bundle extras) {
430         try {
431             Log.startSession("ICA.sCE", mOwnerComponentName);
432             long token = Binder.clearCallingIdentity();
433             try {
434                 synchronized (mLock) {
435                     Call call = mCallIdMapper.getCall(callId);
436                     if (call != null) {
437                         call.sendCallEvent(event, targetSdkVer, extras);
438                     } else {
439                         Log.w(this, "sendCallEvent, unknown call id: %s", callId);
440                     }
441                 }
442             } finally {
443                 Binder.restoreCallingIdentity(token);
444             }
445         } finally {
446             Log.endSession();
447         }
448     }
449 
450     @Override
putExtras(String callId, Bundle extras)451     public void putExtras(String callId, Bundle extras) {
452         try {
453             Log.startSession("ICA.pE", mOwnerComponentName);
454             long token = Binder.clearCallingIdentity();
455             try {
456                 synchronized (mLock) {
457                     Call call = mCallIdMapper.getCall(callId);
458                     if (call != null) {
459                         call.putExtras(Call.SOURCE_INCALL_SERVICE, extras);
460                     } else {
461                         Log.w(this, "putExtras, unknown call id: %s", callId);
462                     }
463                 }
464             } finally {
465                 Binder.restoreCallingIdentity(token);
466             }
467         } finally {
468             Log.endSession();
469         }
470     }
471 
472     @Override
removeExtras(String callId, List<String> keys)473     public void removeExtras(String callId, List<String> keys) {
474         try {
475             Log.startSession("ICA.rE", mOwnerComponentName);
476             long token = Binder.clearCallingIdentity();
477             try {
478                 synchronized (mLock) {
479                     Call call = mCallIdMapper.getCall(callId);
480                     if (call != null) {
481                         call.removeExtras(Call.SOURCE_INCALL_SERVICE, keys);
482                     } else {
483                         Log.w(this, "removeExtra, unknown call id: %s", callId);
484                     }
485                 }
486             } finally {
487                 Binder.restoreCallingIdentity(token);
488             }
489         } finally {
490             Log.endSession();
491         }
492     }
493 
494     @Override
turnOnProximitySensor()495     public void turnOnProximitySensor() {
496         try {
497             Log.startSession("ICA.tOnPS", mOwnerComponentName);
498             long token = Binder.clearCallingIdentity();
499             try {
500                 synchronized (mLock) {
501                     mCallsManager.turnOnProximitySensor();
502                 }
503             } finally {
504                 Binder.restoreCallingIdentity(token);
505             }
506         } finally {
507             Log.endSession();
508         }
509     }
510 
511     @Override
turnOffProximitySensor(boolean screenOnImmediately)512     public void turnOffProximitySensor(boolean screenOnImmediately) {
513         try {
514             Log.startSession("ICA.tOffPS", mOwnerComponentName);
515             long token = Binder.clearCallingIdentity();
516             try {
517                 synchronized (mLock) {
518                     mCallsManager.turnOffProximitySensor(screenOnImmediately);
519                 }
520             } finally {
521                 Binder.restoreCallingIdentity(token);
522             }
523         } finally {
524              Log.endSession();
525         }
526     }
527 
528     @Override
sendRttRequest(String callId)529     public void sendRttRequest(String callId) {
530         try {
531             Log.startSession("ICA.sRR");
532             long token = Binder.clearCallingIdentity();
533             try {
534                 synchronized (mLock) {
535                     Call call = mCallIdMapper.getCall(callId);
536                     if (call != null) {
537                         call.sendRttRequest();
538                     } else {
539                         Log.w(this, "stopRtt(): call %s not found", callId);
540                     }
541                 }
542             } finally {
543                 Binder.restoreCallingIdentity(token);
544             }
545         } finally {
546             Log.endSession();
547         }
548     }
549 
550     @Override
respondToRttRequest(String callId, int id, boolean accept)551     public void respondToRttRequest(String callId, int id, boolean accept) {
552         try {
553             Log.startSession("ICA.rTRR");
554             long token = Binder.clearCallingIdentity();
555             try {
556                 synchronized (mLock) {
557                     Call call = mCallIdMapper.getCall(callId);
558                     if (call != null) {
559                         call.handleRttRequestResponse(id, accept);
560                     } else {
561                         Log.w(this, "respondToRttRequest(): call %s not found", callId);
562                     }
563                 }
564             } finally {
565                 Binder.restoreCallingIdentity(token);
566             }
567         } finally {
568             Log.endSession();
569         }
570     }
571 
572     @Override
stopRtt(String callId)573     public void stopRtt(String callId) {
574         try {
575             Log.startSession("ICA.sRTT");
576             long token = Binder.clearCallingIdentity();
577             try {
578                 synchronized (mLock) {
579                     Call call = mCallIdMapper.getCall(callId);
580                     if (call != null) {
581                         call.stopRtt();
582                     } else {
583                         Log.w(this, "stopRtt(): call %s not found", callId);
584                     }
585                 }
586             } finally {
587                 Binder.restoreCallingIdentity(token);
588             }
589         } finally {
590             Log.endSession();
591         }
592     }
593 
594     @Override
setRttMode(String callId, int mode)595     public void setRttMode(String callId, int mode) {
596         try {
597             Log.startSession("ICA.sRM");
598             long token = Binder.clearCallingIdentity();
599             try {
600                 synchronized (mLock) {
601                     // TODO
602                 }
603             } finally {
604                 Binder.restoreCallingIdentity(token);
605             }
606         } finally {
607             Log.endSession();
608         }
609     }
610 
611     @Override
handoverTo(String callId, PhoneAccountHandle destAcct, int videoState, Bundle extras)612     public void handoverTo(String callId, PhoneAccountHandle destAcct, int videoState,
613                            Bundle extras) {
614         try {
615             Log.startSession("ICA.hT", mOwnerComponentName);
616             long token = Binder.clearCallingIdentity();
617             try {
618                 synchronized (mLock) {
619                     Call call = mCallIdMapper.getCall(callId);
620                     if (call != null) {
621                         call.handoverTo(destAcct, videoState, extras);
622                     } else {
623                         Log.w(this, "handoverTo, unknown call id: %s", callId);
624                     }
625                 }
626             } finally {
627                 Binder.restoreCallingIdentity(token);
628             }
629         } finally {
630             Log.endSession();
631         }
632     }
633 }
634