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 android.telecom;
18 
19 import android.annotation.NonNull;
20 import android.bluetooth.BluetoothDevice;
21 import android.net.Uri;
22 import android.os.Bundle;
23 import android.os.RemoteException;
24 
25 import com.android.internal.telecom.IInCallAdapter;
26 
27 import java.util.List;
28 
29 /**
30  * Receives commands from {@link InCallService} implementations which should be executed by
31  * Telecom. When Telecom binds to a {@link InCallService}, an instance of this class is given to
32  * the in-call service through which it can manipulate live (active, dialing, ringing) calls. When
33  * the in-call service is notified of new calls, it can use the
34  * given call IDs to execute commands such as {@link #answerCall} for incoming calls or
35  * {@link #disconnectCall} for active calls the user would like to end. Some commands are only
36  * appropriate for calls in certain states; please consult each method for such limitations.
37  * <p>
38  * The adapter will stop functioning when there are no more calls.
39  *
40  * @hide
41  */
42 public final class InCallAdapter {
43     private final IInCallAdapter mAdapter;
44 
45     /**
46      * {@hide}
47      */
InCallAdapter(IInCallAdapter adapter)48     public InCallAdapter(IInCallAdapter adapter) {
49         mAdapter = adapter;
50     }
51 
52     /**
53      * Instructs Telecom to answer the specified call.
54      *
55      * @param callId The identifier of the call to answer.
56      * @param videoState The video state in which to answer the call.
57      */
answerCall(String callId, int videoState)58     public void answerCall(String callId, int videoState) {
59         try {
60             mAdapter.answerCall(callId, videoState);
61         } catch (RemoteException e) {
62         }
63     }
64 
65     /**
66      * Instructs Telecom to deflect the specified call.
67      *
68      * @param callId The identifier of the call to deflect.
69      * @param address The address to deflect.
70      */
deflectCall(String callId, Uri address)71     public void deflectCall(String callId, Uri address) {
72         try {
73             mAdapter.deflectCall(callId, address);
74         } catch (RemoteException e) {
75         }
76     }
77 
78     /**
79      * Instructs Telecom to reject the specified call.
80      *
81      * @param callId The identifier of the call to reject.
82      * @param rejectWithMessage Whether to reject with a text message.
83      * @param textMessage An optional text message with which to respond.
84      */
rejectCall(String callId, boolean rejectWithMessage, String textMessage)85     public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
86         try {
87             mAdapter.rejectCall(callId, rejectWithMessage, textMessage);
88         } catch (RemoteException e) {
89         }
90     }
91 
92     /**
93      * Instructs Telecom to reject the specified call.
94      *
95      * @param callId The identifier of the call to reject.
96      * @param rejectReason The reason the call was rejected.
97      */
rejectCall(String callId, @Call.RejectReason int rejectReason)98     public void rejectCall(String callId, @Call.RejectReason int rejectReason) {
99         try {
100             mAdapter.rejectCallWithReason(callId, rejectReason);
101         } catch (RemoteException e) {
102         }
103     }
104 
105     /**
106      * Instructs Telecom to transfer the specified call.
107      *
108      * @param callId The identifier of the call to transfer.
109      * @param targetNumber The address to transfer to.
110      * @param isConfirmationRequired if {@code true} it will initiate a confirmed transfer,
111      * if {@code false}, it will initiate unconfirmed transfer.
112      */
transferCall(@onNull String callId, @NonNull Uri targetNumber, boolean isConfirmationRequired)113     public void transferCall(@NonNull String callId, @NonNull Uri targetNumber,
114             boolean isConfirmationRequired) {
115         try {
116             mAdapter.transferCall(callId, targetNumber, isConfirmationRequired);
117         } catch (RemoteException e) {
118         }
119     }
120 
121     /**
122      * Instructs Telecom to transfer the specified call to another ongoing call.
123      *
124      * @param callId The identifier of the call to transfer.
125      * @param otherCallId The identifier of the other call to which this will be transferred.
126      */
transferCall(@onNull String callId, @NonNull String otherCallId)127     public void transferCall(@NonNull String callId, @NonNull String otherCallId) {
128         try {
129             mAdapter.consultativeTransfer(callId, otherCallId);
130         } catch (RemoteException e) {
131         }
132     }
133 
134     /**
135      * Instructs Telecom to disconnect the specified call.
136      *
137      * @param callId The identifier of the call to disconnect.
138      */
disconnectCall(String callId)139     public void disconnectCall(String callId) {
140         try {
141             mAdapter.disconnectCall(callId);
142         } catch (RemoteException e) {
143         }
144     }
145 
146     /**
147      * Instructs Telecom to put the specified call on hold.
148      *
149      * @param callId The identifier of the call to put on hold.
150      */
holdCall(String callId)151     public void holdCall(String callId) {
152         try {
153             mAdapter.holdCall(callId);
154         } catch (RemoteException e) {
155         }
156     }
157 
158     /**
159      * Instructs Telecom to release the specified call from hold.
160      *
161      * @param callId The identifier of the call to release from hold.
162      */
unholdCall(String callId)163     public void unholdCall(String callId) {
164         try {
165             mAdapter.unholdCall(callId);
166         } catch (RemoteException e) {
167         }
168     }
169 
170     /**
171      * Mute the microphone.
172      *
173      * @param shouldMute True if the microphone should be muted.
174      */
mute(boolean shouldMute)175     public void mute(boolean shouldMute) {
176         try {
177             mAdapter.mute(shouldMute);
178         } catch (RemoteException e) {
179         }
180     }
181 
182     /**
183      * Sets the audio route (speaker, bluetooth, etc...). See {@link CallAudioState}.
184      *
185      * @param route The audio route to use.
186      */
setAudioRoute(int route)187     public void setAudioRoute(int route) {
188         try {
189             mAdapter.setAudioRoute(route, null);
190         } catch (RemoteException e) {
191         }
192     }
193 
194     /**
195      * @see Call#enterBackgroundAudioProcessing()
196      */
enterBackgroundAudioProcessing(String callId)197     public void enterBackgroundAudioProcessing(String callId) {
198         try {
199             mAdapter.enterBackgroundAudioProcessing(callId);
200         } catch (RemoteException e) {
201         }
202     }
203 
204     /**
205      * @see Call#exitBackgroundAudioProcessing(boolean)
206      */
exitBackgroundAudioProcessing(String callId, boolean shouldRing)207     public void exitBackgroundAudioProcessing(String callId, boolean shouldRing) {
208         try {
209             mAdapter.exitBackgroundAudioProcessing(callId, shouldRing);
210         } catch (RemoteException e) {
211         }
212     }
213 
214     /**
215      * Request audio routing to a specific bluetooth device. Calling this method may result in
216      * the device routing audio to a different bluetooth device than the one specified. A list of
217      * available devices can be obtained via {@link CallAudioState#getSupportedBluetoothDevices()}
218      *
219      * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
220      * {@link BluetoothDevice#getAddress()}, or {@code null} if no device is preferred.
221      */
requestBluetoothAudio(String bluetoothAddress)222     public void requestBluetoothAudio(String bluetoothAddress) {
223         try {
224             mAdapter.setAudioRoute(CallAudioState.ROUTE_BLUETOOTH, bluetoothAddress);
225         } catch (RemoteException e) {
226         }
227     }
228 
229     /**
230      * Instructs Telecom to play a dual-tone multi-frequency signaling (DTMF) tone in a call.
231      *
232      * Any other currently playing DTMF tone in the specified call is immediately stopped.
233      *
234      * @param callId The unique ID of the call in which the tone will be played.
235      * @param digit A character representing the DTMF digit for which to play the tone. This
236      *         value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
237      */
playDtmfTone(String callId, char digit)238     public void playDtmfTone(String callId, char digit) {
239         try {
240             mAdapter.playDtmfTone(callId, digit);
241         } catch (RemoteException e) {
242         }
243     }
244 
245     /**
246      * Instructs Telecom to stop any dual-tone multi-frequency signaling (DTMF) tone currently
247      * playing.
248      *
249      * DTMF tones are played by calling {@link #playDtmfTone(String,char)}. If no DTMF tone is
250      * currently playing, this method will do nothing.
251      *
252      * @param callId The unique ID of the call in which any currently playing tone will be stopped.
253      */
stopDtmfTone(String callId)254     public void stopDtmfTone(String callId) {
255         try {
256             mAdapter.stopDtmfTone(callId);
257         } catch (RemoteException e) {
258         }
259     }
260 
261     /**
262      * Instructs Telecom to continue playing a post-dial DTMF string.
263      *
264      * A post-dial DTMF string is a string of digits entered after a phone number, when dialed,
265      * that are immediately sent as DTMF tones to the recipient as soon as the connection is made.
266      * While these tones are playing, Telecom will notify the {@link InCallService} that the call
267      * is in the post dial state.
268      *
269      * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_PAUSE} symbol, Telecom
270      * will temporarily pause playing the tones for a pre-defined period of time.
271      *
272      * If the DTMF string contains a {@link TelecomManager#DTMF_CHARACTER_WAIT} symbol, Telecom
273      * will pause playing the tones and notify the {@link InCallService} that the call is in the
274      * post dial wait state. When the user decides to continue the postdial sequence, the
275      * {@link InCallService} should invoke the {@link #postDialContinue(String,boolean)} method.
276      *
277      * @param callId The unique ID of the call for which postdial string playing should continue.
278      * @param proceed Whether or not to continue with the post-dial sequence.
279      */
postDialContinue(String callId, boolean proceed)280     public void postDialContinue(String callId, boolean proceed) {
281         try {
282             mAdapter.postDialContinue(callId, proceed);
283         } catch (RemoteException e) {
284         }
285     }
286 
287     /**
288      * Instructs Telecom to add a PhoneAccountHandle to the specified call.
289      *
290      * @param callId The identifier of the call.
291      * @param accountHandle The PhoneAccountHandle through which to place the call.
292      * @param setDefault {@code True} if this account should be set as the default for calls.
293      */
phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, boolean setDefault)294     public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle,
295             boolean setDefault) {
296         try {
297             mAdapter.phoneAccountSelected(callId, accountHandle, setDefault);
298         } catch (RemoteException e) {
299         }
300     }
301 
302     /**
303      * Instructs Telecom to conference the specified call.
304      *
305      * @param callId The unique ID of the call.
306      * @hide
307      */
conference(String callId, String otherCallId)308     public void conference(String callId, String otherCallId) {
309         try {
310             mAdapter.conference(callId, otherCallId);
311         } catch (RemoteException ignored) {
312         }
313     }
314 
315     /**
316      * Instructs Telecom to pull participants to existing call
317      *
318      * @param callId The unique ID of the call.
319      * @param participants participants to be pulled to existing call.
320      */
addConferenceParticipants(String callId, List<Uri> participants)321     public void addConferenceParticipants(String callId, List<Uri> participants) {
322         try {
323             mAdapter.addConferenceParticipants(callId, participants);
324         } catch (RemoteException ignored) {
325         }
326     }
327 
328 
329     /**
330      * Instructs Telecom to split the specified call from any conference call with which it may be
331      * connected.
332      *
333      * @param callId The unique ID of the call.
334      * @hide
335      */
splitFromConference(String callId)336     public void splitFromConference(String callId) {
337         try {
338             mAdapter.splitFromConference(callId);
339         } catch (RemoteException ignored) {
340         }
341     }
342 
343     /**
344      * Instructs Telecom to merge child calls of the specified conference call.
345      */
mergeConference(String callId)346     public void mergeConference(String callId) {
347         try {
348             mAdapter.mergeConference(callId);
349         } catch (RemoteException ignored) {
350         }
351     }
352 
353     /**
354      * Instructs Telecom to swap the child calls of the specified conference call.
355      */
swapConference(String callId)356     public void swapConference(String callId) {
357         try {
358             mAdapter.swapConference(callId);
359         } catch (RemoteException ignored) {
360         }
361     }
362 
363     /**
364      * Instructs Telecom to pull an external call to the local device.
365      *
366      * @param callId The callId to pull.
367      */
pullExternalCall(String callId)368     public void pullExternalCall(String callId) {
369         try {
370             mAdapter.pullExternalCall(callId);
371         } catch (RemoteException ignored) {
372         }
373     }
374 
375     /**
376      * Intructs Telecom to send a call event.
377      *
378      * @param callId The callId to send the event for.
379      * @param event The event.
380      * @param targetSdkVer Target sdk version of the app calling this api
381      * @param extras Extras associated with the event.
382      */
sendCallEvent(String callId, String event, int targetSdkVer, Bundle extras)383     public void sendCallEvent(String callId, String event, int targetSdkVer, Bundle extras) {
384         try {
385             mAdapter.sendCallEvent(callId, event, targetSdkVer, extras);
386         } catch (RemoteException ignored) {
387         }
388     }
389 
390     /**
391      * Intructs Telecom to add extras to a call.
392      *
393      * @param callId The callId to add the extras to.
394      * @param extras The extras.
395      */
putExtras(String callId, Bundle extras)396     public void putExtras(String callId, Bundle extras) {
397         try {
398             mAdapter.putExtras(callId, extras);
399         } catch (RemoteException ignored) {
400         }
401     }
402 
403     /**
404      * Intructs Telecom to add an extra to a call.
405      *
406      * @param callId The callId to add the extras to.
407      * @param key The extra key.
408      * @param value The extra value.
409      */
putExtra(String callId, String key, boolean value)410     public void putExtra(String callId, String key, boolean value) {
411         try {
412             Bundle bundle = new Bundle();
413             bundle.putBoolean(key, value);
414             mAdapter.putExtras(callId, bundle);
415         } catch (RemoteException ignored) {
416         }
417     }
418 
419     /**
420      * Intructs Telecom to add an extra to a call.
421      *
422      * @param callId The callId to add the extras to.
423      * @param key The extra key.
424      * @param value The extra value.
425      */
putExtra(String callId, String key, int value)426     public void putExtra(String callId, String key, int value) {
427         try {
428             Bundle bundle = new Bundle();
429             bundle.putInt(key, value);
430             mAdapter.putExtras(callId, bundle);
431         } catch (RemoteException ignored) {
432         }
433     }
434 
435     /**
436      * Intructs Telecom to add an extra to a call.
437      *
438      * @param callId The callId to add the extras to.
439      * @param key The extra key.
440      * @param value The extra value.
441      */
putExtra(String callId, String key, String value)442     public void putExtra(String callId, String key, String value) {
443         try {
444             Bundle bundle = new Bundle();
445             bundle.putString(key, value);
446             mAdapter.putExtras(callId, bundle);
447         } catch (RemoteException ignored) {
448         }
449     }
450 
451     /**
452      * Intructs Telecom to remove extras from a call.
453      * @param callId The callId to remove the extras from.
454      * @param keys The extra keys to remove.
455      */
removeExtras(String callId, List<String> keys)456     public void removeExtras(String callId, List<String> keys) {
457         try {
458             mAdapter.removeExtras(callId, keys);
459         } catch (RemoteException ignored) {
460         }
461     }
462 
463     /**
464      * Instructs Telecom to turn the proximity sensor on.
465      */
turnProximitySensorOn()466     public void turnProximitySensorOn() {
467         try {
468             mAdapter.turnOnProximitySensor();
469         } catch (RemoteException ignored) {
470         }
471     }
472 
473     /**
474      * Instructs Telecom to turn the proximity sensor off.
475      *
476      * @param screenOnImmediately If true, the screen will be turned on immediately if it was
477      * previously off. Otherwise, the screen will only be turned on after the proximity sensor
478      * is no longer triggered.
479      */
turnProximitySensorOff(boolean screenOnImmediately)480     public void turnProximitySensorOff(boolean screenOnImmediately) {
481         try {
482             mAdapter.turnOffProximitySensor(screenOnImmediately);
483         } catch (RemoteException ignored) {
484         }
485     }
486 
487     /**
488      * Sends an RTT upgrade request to the remote end of the connection.
489      */
sendRttRequest(String callId)490     public void sendRttRequest(String callId) {
491         try {
492             mAdapter.sendRttRequest(callId);
493         } catch (RemoteException ignored) {
494         }
495     }
496 
497     /**
498      * Responds to an RTT upgrade request initiated from the remote end.
499      *
500      * @param id the ID of the request as specified by Telecom
501      * @param accept Whether the request should be accepted.
502      */
respondToRttRequest(String callId, int id, boolean accept)503     public void respondToRttRequest(String callId, int id, boolean accept) {
504         try {
505             mAdapter.respondToRttRequest(callId, id, accept);
506         } catch (RemoteException ignored) {
507         }
508     }
509 
510     /**
511      * Instructs Telecom to shut down the RTT communication channel.
512      */
stopRtt(String callId)513     public void stopRtt(String callId) {
514         try {
515             mAdapter.stopRtt(callId);
516         } catch (RemoteException ignored) {
517         }
518     }
519 
520     /**
521      * Sets the RTT audio mode.
522      * @param mode the desired RTT audio mode
523      */
setRttMode(String callId, int mode)524     public void setRttMode(String callId, int mode) {
525         try {
526             mAdapter.setRttMode(callId, mode);
527         } catch (RemoteException ignored) {
528         }
529     }
530 
531 
532     /**
533      * Initiates a handover of this {@link Call} to the {@link ConnectionService} identified
534      * by destAcct.
535      * @param callId The callId of the Call which calls this function.
536      * @param destAcct ConnectionService to which the call should be handed over.
537      * @param videoState The video state desired after the handover.
538      * @param extras Extra information to be passed to ConnectionService
539      */
handoverTo(String callId, PhoneAccountHandle destAcct, int videoState, Bundle extras)540     public void handoverTo(String callId, PhoneAccountHandle destAcct, int videoState,
541                            Bundle extras) {
542         try {
543             mAdapter.handoverTo(callId, destAcct, videoState, extras);
544         } catch (RemoteException ignored) {
545         }
546     }
547 }
548