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.net.Uri; 20 import android.os.Bundle; 21 import android.os.IBinder.DeathRecipient; 22 import android.os.RemoteException; 23 24 import com.android.internal.telecom.IConnectionServiceAdapter; 25 import com.android.internal.telecom.RemoteServiceCallback; 26 27 import java.util.Collections; 28 import java.util.Iterator; 29 import java.util.List; 30 import java.util.Set; 31 import java.util.concurrent.ConcurrentHashMap; 32 33 /** 34 * Provides methods for IConnectionService implementations to interact with the system phone app. 35 * 36 * @hide 37 */ 38 final class ConnectionServiceAdapter implements DeathRecipient { 39 /** 40 * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is 41 * load factor before resizing, 1 means we only expect a single thread to 42 * access the map so make only a single shard 43 */ 44 private final Set<IConnectionServiceAdapter> mAdapters = Collections.newSetFromMap( 45 new ConcurrentHashMap<IConnectionServiceAdapter, Boolean>(8, 0.9f, 1)); 46 ConnectionServiceAdapter()47 ConnectionServiceAdapter() { 48 } 49 addAdapter(IConnectionServiceAdapter adapter)50 void addAdapter(IConnectionServiceAdapter adapter) { 51 for (IConnectionServiceAdapter it : mAdapters) { 52 if (it.asBinder() == adapter.asBinder()) { 53 Log.w(this, "Ignoring duplicate adapter addition."); 54 return; 55 } 56 } 57 if (mAdapters.add(adapter)) { 58 try { 59 adapter.asBinder().linkToDeath(this, 0); 60 } catch (RemoteException e) { 61 mAdapters.remove(adapter); 62 } 63 } 64 } 65 removeAdapter(IConnectionServiceAdapter adapter)66 void removeAdapter(IConnectionServiceAdapter adapter) { 67 if (adapter != null) { 68 for (IConnectionServiceAdapter it : mAdapters) { 69 if (it.asBinder() == adapter.asBinder() && mAdapters.remove(it)) { 70 adapter.asBinder().unlinkToDeath(this, 0); 71 break; 72 } 73 } 74 } 75 } 76 77 /** ${inheritDoc} */ 78 @Override binderDied()79 public void binderDied() { 80 Iterator<IConnectionServiceAdapter> it = mAdapters.iterator(); 81 while (it.hasNext()) { 82 IConnectionServiceAdapter adapter = it.next(); 83 if (!adapter.asBinder().isBinderAlive()) { 84 it.remove(); 85 adapter.asBinder().unlinkToDeath(this, 0); 86 } 87 } 88 } 89 handleCreateConnectionComplete( String id, ConnectionRequest request, ParcelableConnection connection)90 void handleCreateConnectionComplete( 91 String id, 92 ConnectionRequest request, 93 ParcelableConnection connection) { 94 for (IConnectionServiceAdapter adapter : mAdapters) { 95 try { 96 adapter.handleCreateConnectionComplete(id, request, connection, 97 Log.getExternalSession()); 98 } catch (RemoteException e) { 99 } 100 } 101 } 102 handleCreateConferenceComplete( String id, ConnectionRequest request, ParcelableConference conference)103 void handleCreateConferenceComplete( 104 String id, 105 ConnectionRequest request, 106 ParcelableConference conference) { 107 for (IConnectionServiceAdapter adapter : mAdapters) { 108 try { 109 adapter.handleCreateConferenceComplete(id, request, conference, 110 Log.getExternalSession()); 111 } catch (RemoteException e) { 112 } 113 } 114 } 115 116 /** 117 * Sets a call's state to active (e.g., an ongoing call where two parties can actively 118 * communicate). 119 * 120 * @param callId The unique ID of the call whose state is changing to active. 121 */ setActive(String callId)122 void setActive(String callId) { 123 for (IConnectionServiceAdapter adapter : mAdapters) { 124 try { 125 adapter.setActive(callId, Log.getExternalSession()); 126 } catch (RemoteException e) { 127 } 128 } 129 } 130 131 /** 132 * Sets a call's state to ringing (e.g., an inbound ringing call). 133 * 134 * @param callId The unique ID of the call whose state is changing to ringing. 135 */ setRinging(String callId)136 void setRinging(String callId) { 137 for (IConnectionServiceAdapter adapter : mAdapters) { 138 try { 139 adapter.setRinging(callId, Log.getExternalSession()); 140 } catch (RemoteException e) { 141 } 142 } 143 } 144 145 /** 146 * Sets a call's state to dialing (e.g., dialing an outbound call). 147 * 148 * @param callId The unique ID of the call whose state is changing to dialing. 149 */ setDialing(String callId)150 void setDialing(String callId) { 151 for (IConnectionServiceAdapter adapter : mAdapters) { 152 try { 153 adapter.setDialing(callId, Log.getExternalSession()); 154 } catch (RemoteException e) { 155 } 156 } 157 } 158 159 /** 160 * Sets a call's state to pulling (e.g. a call with {@link Connection#PROPERTY_IS_EXTERNAL_CALL} 161 * is being pulled to the local device. 162 * 163 * @param callId The unique ID of the call whose state is changing to dialing. 164 */ setPulling(String callId)165 void setPulling(String callId) { 166 for (IConnectionServiceAdapter adapter : mAdapters) { 167 try { 168 adapter.setPulling(callId, Log.getExternalSession()); 169 } catch (RemoteException e) { 170 } 171 } 172 } 173 174 /** 175 * Sets a call's state to disconnected. 176 * 177 * @param callId The unique ID of the call whose state is changing to disconnected. 178 * @param disconnectCause The reason for the disconnection, as described by 179 * {@link android.telecomm.DisconnectCause}. 180 */ setDisconnected(String callId, DisconnectCause disconnectCause)181 void setDisconnected(String callId, DisconnectCause disconnectCause) { 182 for (IConnectionServiceAdapter adapter : mAdapters) { 183 try { 184 adapter.setDisconnected(callId, disconnectCause, Log.getExternalSession()); 185 } catch (RemoteException e) { 186 } 187 } 188 } 189 190 /** 191 * Sets a call's state to be on hold. 192 * 193 * @param callId - The unique ID of the call whose state is changing to be on hold. 194 */ setOnHold(String callId)195 void setOnHold(String callId) { 196 for (IConnectionServiceAdapter adapter : mAdapters) { 197 try { 198 adapter.setOnHold(callId, Log.getExternalSession()); 199 } catch (RemoteException e) { 200 } 201 } 202 } 203 204 /** 205 * Asks Telecom to start or stop a ringback tone for a call. 206 * 207 * @param callId The unique ID of the call whose ringback is being changed. 208 * @param ringback Whether Telecom should start playing a ringback tone. 209 */ setRingbackRequested(String callId, boolean ringback)210 void setRingbackRequested(String callId, boolean ringback) { 211 for (IConnectionServiceAdapter adapter : mAdapters) { 212 try { 213 adapter.setRingbackRequested(callId, ringback, Log.getExternalSession()); 214 } catch (RemoteException e) { 215 } 216 } 217 } 218 setConnectionCapabilities(String callId, int capabilities)219 void setConnectionCapabilities(String callId, int capabilities) { 220 for (IConnectionServiceAdapter adapter : mAdapters) { 221 try { 222 adapter.setConnectionCapabilities(callId, capabilities, Log.getExternalSession()); 223 } catch (RemoteException ignored) { 224 } 225 } 226 } 227 setConnectionProperties(String callId, int properties)228 void setConnectionProperties(String callId, int properties) { 229 for (IConnectionServiceAdapter adapter : mAdapters) { 230 try { 231 adapter.setConnectionProperties(callId, properties, Log.getExternalSession()); 232 } catch (RemoteException ignored) { 233 } 234 } 235 } 236 237 /** 238 * Indicates whether or not the specified call is currently conferenced into the specified 239 * conference call. 240 * 241 * @param callId The unique ID of the call being conferenced. 242 * @param conferenceCallId The unique ID of the conference call. Null if call is not 243 * conferenced. 244 */ setIsConferenced(String callId, String conferenceCallId)245 void setIsConferenced(String callId, String conferenceCallId) { 246 for (IConnectionServiceAdapter adapter : mAdapters) { 247 try { 248 Log.d(this, "sending connection %s with conference %s", callId, conferenceCallId); 249 adapter.setIsConferenced(callId, conferenceCallId, Log.getExternalSession()); 250 } catch (RemoteException ignored) { 251 } 252 } 253 } 254 255 /** 256 * Indicates that the merge request on this call has failed. 257 * 258 * @param callId The unique ID of the call being conferenced. 259 */ onConferenceMergeFailed(String callId)260 void onConferenceMergeFailed(String callId) { 261 for (IConnectionServiceAdapter adapter : mAdapters) { 262 try { 263 Log.d(this, "merge failed for call %s", callId); 264 adapter.setConferenceMergeFailed(callId, Log.getExternalSession()); 265 } catch (RemoteException ignored) { 266 } 267 } 268 } 269 270 /** 271 * Resets the cdma connection time. 272 */ resetConnectionTime(String callId)273 void resetConnectionTime(String callId) { 274 for (IConnectionServiceAdapter adapter : mAdapters) { 275 try { 276 adapter.resetConnectionTime(callId, Log.getExternalSession()); 277 } catch (RemoteException e) { 278 } 279 } 280 } 281 282 /** 283 * Indicates that the call no longer exists. Can be used with either a call or a conference 284 * call. 285 * 286 * @param callId The unique ID of the call. 287 */ removeCall(String callId)288 void removeCall(String callId) { 289 for (IConnectionServiceAdapter adapter : mAdapters) { 290 try { 291 adapter.removeCall(callId, Log.getExternalSession()); 292 } catch (RemoteException ignored) { 293 } 294 } 295 } 296 onPostDialWait(String callId, String remaining)297 void onPostDialWait(String callId, String remaining) { 298 for (IConnectionServiceAdapter adapter : mAdapters) { 299 try { 300 adapter.onPostDialWait(callId, remaining, Log.getExternalSession()); 301 } catch (RemoteException ignored) { 302 } 303 } 304 } 305 onPostDialChar(String callId, char nextChar)306 void onPostDialChar(String callId, char nextChar) { 307 for (IConnectionServiceAdapter adapter : mAdapters) { 308 try { 309 adapter.onPostDialChar(callId, nextChar, Log.getExternalSession()); 310 } catch (RemoteException ignored) { 311 } 312 } 313 } 314 315 /** 316 * Indicates that a new conference call has been created. 317 * 318 * @param callId The unique ID of the conference call. 319 */ addConferenceCall(String callId, ParcelableConference parcelableConference)320 void addConferenceCall(String callId, ParcelableConference parcelableConference) { 321 for (IConnectionServiceAdapter adapter : mAdapters) { 322 try { 323 adapter.addConferenceCall(callId, parcelableConference, Log.getExternalSession()); 324 } catch (RemoteException ignored) { 325 } 326 } 327 } 328 329 /** 330 * Retrieves a list of remote connection services usable to place calls. 331 */ queryRemoteConnectionServices(RemoteServiceCallback callback, String callingPackage)332 void queryRemoteConnectionServices(RemoteServiceCallback callback, String callingPackage) { 333 // Only supported when there is only one adapter. 334 if (mAdapters.size() == 1) { 335 try { 336 mAdapters.iterator().next().queryRemoteConnectionServices(callback, callingPackage, 337 Log.getExternalSession()); 338 } catch (RemoteException e) { 339 Log.e(this, e, "Exception trying to query for remote CSs"); 340 } 341 } else { 342 try { 343 // This is not an error condition, so just pass back an empty list. 344 // This happens when querying from a remote connection service, not the connection 345 // manager itself. 346 callback.onResult(Collections.EMPTY_LIST, Collections.EMPTY_LIST); 347 } catch (RemoteException e) { 348 Log.e(this, e, "Exception trying to query for remote CSs"); 349 } 350 } 351 } 352 353 /** 354 * Sets the call video provider for a call. 355 * 356 * @param callId The unique ID of the call to set with the given call video provider. 357 * @param videoProvider The call video provider instance to set on the call. 358 */ setVideoProvider( String callId, Connection.VideoProvider videoProvider)359 void setVideoProvider( 360 String callId, Connection.VideoProvider videoProvider) { 361 for (IConnectionServiceAdapter adapter : mAdapters) { 362 try { 363 adapter.setVideoProvider( 364 callId, 365 videoProvider == null ? null : videoProvider.getInterface(), 366 Log.getExternalSession()); 367 } catch (RemoteException e) { 368 } 369 } 370 } 371 372 /** 373 * Requests that the framework use VOIP audio mode for this connection. 374 * 375 * @param callId The unique ID of the call to set with the given call video provider. 376 * @param isVoip True if the audio mode is VOIP. 377 */ setIsVoipAudioMode(String callId, boolean isVoip)378 void setIsVoipAudioMode(String callId, boolean isVoip) { 379 for (IConnectionServiceAdapter adapter : mAdapters) { 380 try { 381 adapter.setIsVoipAudioMode(callId, isVoip, Log.getExternalSession()); 382 } catch (RemoteException e) { 383 } 384 } 385 } 386 setStatusHints(String callId, StatusHints statusHints)387 void setStatusHints(String callId, StatusHints statusHints) { 388 for (IConnectionServiceAdapter adapter : mAdapters) { 389 try { 390 adapter.setStatusHints(callId, statusHints, Log.getExternalSession()); 391 } catch (RemoteException e) { 392 } 393 } 394 } 395 setAddress(String callId, Uri address, int presentation)396 void setAddress(String callId, Uri address, int presentation) { 397 for (IConnectionServiceAdapter adapter : mAdapters) { 398 try { 399 adapter.setAddress(callId, address, presentation, Log.getExternalSession()); 400 } catch (RemoteException e) { 401 } 402 } 403 } 404 setCallerDisplayName(String callId, String callerDisplayName, int presentation)405 void setCallerDisplayName(String callId, String callerDisplayName, int presentation) { 406 for (IConnectionServiceAdapter adapter : mAdapters) { 407 try { 408 adapter.setCallerDisplayName(callId, callerDisplayName, presentation, 409 Log.getExternalSession()); 410 } catch (RemoteException e) { 411 } 412 } 413 } 414 415 /** 416 * Sets the video state associated with a call. 417 * 418 * Valid values: {@link VideoProfile#STATE_BIDIRECTIONAL}, 419 * {@link VideoProfile#STATE_AUDIO_ONLY}, 420 * {@link VideoProfile#STATE_TX_ENABLED}, 421 * {@link VideoProfile#STATE_RX_ENABLED}. 422 * 423 * @param callId The unique ID of the call to set the video state for. 424 * @param videoState The video state. 425 */ setVideoState(String callId, int videoState)426 void setVideoState(String callId, int videoState) { 427 Log.v(this, "setVideoState: %d", videoState); 428 for (IConnectionServiceAdapter adapter : mAdapters) { 429 try { 430 adapter.setVideoState(callId, videoState, Log.getExternalSession()); 431 } catch (RemoteException ignored) { 432 } 433 } 434 } 435 setConferenceableConnections(String callId, List<String> conferenceableCallIds)436 void setConferenceableConnections(String callId, List<String> conferenceableCallIds) { 437 Log.v(this, "setConferenceableConnections: %s, %s", callId, conferenceableCallIds); 438 for (IConnectionServiceAdapter adapter : mAdapters) { 439 try { 440 adapter.setConferenceableConnections(callId, conferenceableCallIds, 441 Log.getExternalSession()); 442 } catch (RemoteException ignored) { 443 } 444 } 445 } 446 447 /** 448 * Informs telecom of an existing connection which was added by the {@link ConnectionService}. 449 * 450 * @param callId The unique ID of the call being added. 451 * @param connection The connection. 452 */ addExistingConnection(String callId, ParcelableConnection connection)453 void addExistingConnection(String callId, ParcelableConnection connection) { 454 Log.v(this, "addExistingConnection: %s", callId); 455 for (IConnectionServiceAdapter adapter : mAdapters) { 456 try { 457 adapter.addExistingConnection(callId, connection, Log.getExternalSession()); 458 } catch (RemoteException ignored) { 459 } 460 } 461 } 462 463 /** 464 * Adds some extras associated with a {@code Connection}. 465 * 466 * @param callId The unique ID of the call. 467 * @param extras The extras to add. 468 */ putExtras(String callId, Bundle extras)469 void putExtras(String callId, Bundle extras) { 470 Log.v(this, "putExtras: %s", callId); 471 for (IConnectionServiceAdapter adapter : mAdapters) { 472 try { 473 adapter.putExtras(callId, extras, Log.getExternalSession()); 474 } catch (RemoteException ignored) { 475 } 476 } 477 } 478 479 /** 480 * Adds an extra associated with a {@code Connection}. 481 * 482 * @param callId The unique ID of the call. 483 * @param key The extra key. 484 * @param value The extra value. 485 */ putExtra(String callId, String key, boolean value)486 void putExtra(String callId, String key, boolean value) { 487 Log.v(this, "putExtra: %s %s=%b", callId, key, value); 488 for (IConnectionServiceAdapter adapter : mAdapters) { 489 try { 490 Bundle bundle = new Bundle(); 491 bundle.putBoolean(key, value); 492 adapter.putExtras(callId, bundle, Log.getExternalSession()); 493 } catch (RemoteException ignored) { 494 } 495 } 496 } 497 498 /** 499 * Adds an extra associated with a {@code Connection}. 500 * 501 * @param callId The unique ID of the call. 502 * @param key The extra key. 503 * @param value The extra value. 504 */ putExtra(String callId, String key, int value)505 void putExtra(String callId, String key, int value) { 506 Log.v(this, "putExtra: %s %s=%d", callId, key, value); 507 for (IConnectionServiceAdapter adapter : mAdapters) { 508 try { 509 Bundle bundle = new Bundle(); 510 bundle.putInt(key, value); 511 adapter.putExtras(callId, bundle, Log.getExternalSession()); 512 } catch (RemoteException ignored) { 513 } 514 } 515 } 516 517 /** 518 * Adds an extra associated with a {@code Connection}. 519 * 520 * @param callId The unique ID of the call. 521 * @param key The extra key. 522 * @param value The extra value. 523 */ putExtra(String callId, String key, String value)524 void putExtra(String callId, String key, String value) { 525 Log.v(this, "putExtra: %s %s=%s", callId, key, value); 526 for (IConnectionServiceAdapter adapter : mAdapters) { 527 try { 528 Bundle bundle = new Bundle(); 529 bundle.putString(key, value); 530 adapter.putExtras(callId, bundle, Log.getExternalSession()); 531 } catch (RemoteException ignored) { 532 } 533 } 534 } 535 536 /** 537 * Removes extras associated with a {@code Connection}. 538 * @param callId The unique ID of the call. 539 * @param keys The extra keys to remove. 540 */ removeExtras(String callId, List<String> keys)541 void removeExtras(String callId, List<String> keys) { 542 Log.v(this, "removeExtras: %s %s", callId, keys); 543 for (IConnectionServiceAdapter adapter : mAdapters) { 544 try { 545 adapter.removeExtras(callId, keys, Log.getExternalSession()); 546 } catch (RemoteException ignored) { 547 } 548 } 549 } 550 551 /** 552 * Sets the audio route associated with a {@link Connection}. 553 * 554 * @param callId The unique ID of the call. 555 * @param audioRoute The new audio route (see {@code CallAudioState#ROUTE_*}). 556 */ setAudioRoute(String callId, int audioRoute, String bluetoothAddress)557 void setAudioRoute(String callId, int audioRoute, String bluetoothAddress) { 558 Log.v(this, "setAudioRoute: %s %s %s", callId, 559 CallAudioState.audioRouteToString(audioRoute), 560 bluetoothAddress); 561 for (IConnectionServiceAdapter adapter : mAdapters) { 562 try { 563 adapter.setAudioRoute(callId, audioRoute, 564 bluetoothAddress, Log.getExternalSession()); 565 } catch (RemoteException ignored) { 566 } 567 } 568 } 569 570 571 /** 572 * Informs Telecom of a connection level event. 573 * 574 * @param callId The unique ID of the call. 575 * @param event The event. 576 * @param extras Extras associated with the event. 577 */ onConnectionEvent(String callId, String event, Bundle extras)578 void onConnectionEvent(String callId, String event, Bundle extras) { 579 Log.v(this, "onConnectionEvent: %s", event); 580 for (IConnectionServiceAdapter adapter : mAdapters) { 581 try { 582 adapter.onConnectionEvent(callId, event, extras, Log.getExternalSession()); 583 } catch (RemoteException ignored) { 584 } 585 } 586 } 587 588 /** 589 * Notifies Telecom that an RTT session was successfully established. 590 * 591 * @param callId The unique ID of the call. 592 */ onRttInitiationSuccess(String callId)593 void onRttInitiationSuccess(String callId) { 594 Log.v(this, "onRttInitiationSuccess: %s", callId); 595 for (IConnectionServiceAdapter adapter : mAdapters) { 596 try { 597 adapter.onRttInitiationSuccess(callId, Log.getExternalSession()); 598 } catch (RemoteException ignored) { 599 } 600 } 601 } 602 603 /** 604 * Notifies Telecom that a requested RTT session failed to be established. 605 * 606 * @param callId The unique ID of the call. 607 */ onRttInitiationFailure(String callId, int reason)608 void onRttInitiationFailure(String callId, int reason) { 609 Log.v(this, "onRttInitiationFailure: %s", callId); 610 for (IConnectionServiceAdapter adapter : mAdapters) { 611 try { 612 adapter.onRttInitiationFailure(callId, reason, Log.getExternalSession()); 613 } catch (RemoteException ignored) { 614 } 615 } 616 } 617 618 /** 619 * Notifies Telecom that an established RTT session was terminated by the remote user on 620 * the call. 621 * 622 * @param callId The unique ID of the call. 623 */ onRttSessionRemotelyTerminated(String callId)624 void onRttSessionRemotelyTerminated(String callId) { 625 Log.v(this, "onRttSessionRemotelyTerminated: %s", callId); 626 for (IConnectionServiceAdapter adapter : mAdapters) { 627 try { 628 adapter.onRttSessionRemotelyTerminated(callId, Log.getExternalSession()); 629 } catch (RemoteException ignored) { 630 } 631 } 632 } 633 634 /** 635 * Notifies Telecom that the remote user on the call has requested an upgrade to an RTT 636 * session for this call. 637 * 638 * @param callId The unique ID of the call. 639 */ onRemoteRttRequest(String callId)640 void onRemoteRttRequest(String callId) { 641 Log.v(this, "onRemoteRttRequest: %s", callId); 642 for (IConnectionServiceAdapter adapter : mAdapters) { 643 try { 644 adapter.onRemoteRttRequest(callId, Log.getExternalSession()); 645 } catch (RemoteException ignored) { 646 } 647 } 648 } 649 650 /** 651 * Notifies Telecom that a call's PhoneAccountHandle has changed. 652 * 653 * @param callId The unique ID of the call. 654 * @param pHandle The new PhoneAccountHandle associated with the call. 655 */ onPhoneAccountChanged(String callId, PhoneAccountHandle pHandle)656 void onPhoneAccountChanged(String callId, PhoneAccountHandle pHandle) { 657 for (IConnectionServiceAdapter adapter : mAdapters) { 658 try { 659 Log.d(this, "onPhoneAccountChanged %s", callId); 660 adapter.onPhoneAccountChanged(callId, pHandle, Log.getExternalSession()); 661 } catch (RemoteException ignored) { 662 } 663 } 664 } 665 666 /** 667 * Notifies Telecom that the {@link ConnectionService} has released the call resource. 668 */ onConnectionServiceFocusReleased()669 void onConnectionServiceFocusReleased() { 670 for (IConnectionServiceAdapter adapter : mAdapters) { 671 try { 672 Log.d(this, "onConnectionServiceFocusReleased"); 673 adapter.onConnectionServiceFocusReleased(Log.getExternalSession()); 674 } catch (RemoteException ignored) { 675 } 676 } 677 } 678 679 /** 680 * Sets whether a conference is treated as a conference or a single party call. 681 * See {@link Conference#setConferenceState(boolean)} for more information. 682 * 683 * @param callId The ID of the telecom call. 684 * @param isConference {@code true} if this call should be treated as a conference, 685 * {@code false} otherwise. 686 */ setConferenceState(String callId, boolean isConference)687 void setConferenceState(String callId, boolean isConference) { 688 Log.v(this, "setConferenceState: %s %b", callId, isConference); 689 for (IConnectionServiceAdapter adapter : mAdapters) { 690 try { 691 adapter.setConferenceState(callId, isConference, Log.getExternalSession()); 692 } catch (RemoteException ignored) { 693 } 694 } 695 } 696 697 /** 698 * Sets the direction of a call. Setting a new direction of an existing call is usually only 699 * applicable during single caller emulation during conferencing, see 700 * {@link Conference#setConferenceState(boolean)} for more information. 701 * @param callId The identifier of the call. 702 * @param direction The new direction of the call. 703 */ setCallDirection(String callId, @Call.Details.CallDirection int direction)704 void setCallDirection(String callId, @Call.Details.CallDirection int direction) { 705 for (IConnectionServiceAdapter a : mAdapters) { 706 try { 707 a.setCallDirection(callId, direction, Log.getExternalSession()); 708 } catch (RemoteException e) { 709 } 710 } 711 } 712 } 713