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