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