TelecomServiceImpl.java revision ea5cb93d81099f17654e0fdf9b8eda3bfa89f081
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 17package com.android.server.telecom; 18 19import android.Manifest; 20import android.app.AppOpsManager; 21import android.content.ComponentName; 22import android.content.Context; 23import android.content.Intent; 24import android.content.pm.ApplicationInfo; 25import android.content.pm.PackageManager; 26import android.content.res.Resources; 27import android.net.Uri; 28import android.os.Binder; 29import android.os.Bundle; 30import android.os.IBinder; 31import android.os.UserHandle; 32import android.os.UserManager; 33import android.telecom.DefaultDialerManager; 34import android.telecom.PhoneAccount; 35import android.telecom.PhoneAccountHandle; 36import android.telecom.TelecomManager; 37import android.telephony.SubscriptionManager; 38import android.telephony.TelephonyManager; 39import android.text.TextUtils; 40 41// TODO: Needed for move to system service: import com.android.internal.R; 42import com.android.internal.telecom.ITelecomService; 43import com.android.internal.util.IndentingPrintWriter; 44import com.android.server.telecom.components.UserCallIntentProcessor; 45 46import java.io.FileDescriptor; 47import java.io.PrintWriter; 48import java.util.ArrayList; 49import java.util.Collections; 50import java.util.List; 51 52/** 53 * Implementation of the ITelecom interface. 54 */ 55public class TelecomServiceImpl { 56 private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION = 57 "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION"; 58 59 private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() { 60 @Override 61 public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme, 62 String callingPackage) { 63 synchronized (mLock) { 64 if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) { 65 return null; 66 } 67 68 long token = Binder.clearCallingIdentity(); 69 try { 70 PhoneAccountHandle defaultOutgoingPhoneAccount = 71 mPhoneAccountRegistrar.getOutgoingPhoneAccountForScheme(uriScheme); 72 // Make sure that the calling user can see this phone account. 73 // TODO: Does this isVisible check actually work considering we are clearing 74 // the calling identity? 75 if (defaultOutgoingPhoneAccount != null 76 && !isVisibleToCaller(defaultOutgoingPhoneAccount)) { 77 Log.w(this, "No account found for the calling user"); 78 return null; 79 } 80 return defaultOutgoingPhoneAccount; 81 } catch (Exception e) { 82 Log.e(this, e, "getDefaultOutgoingPhoneAccount"); 83 throw e; 84 } finally { 85 Binder.restoreCallingIdentity(token); 86 } 87 } 88 } 89 90 @Override 91 public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() { 92 synchronized (mLock) { 93 try { 94 PhoneAccountHandle userSelectedOutgoingPhoneAccount = 95 mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount(); 96 // Make sure that the calling user can see this phone account. 97 if (!isVisibleToCaller(userSelectedOutgoingPhoneAccount)) { 98 Log.w(this, "No account found for the calling user"); 99 return null; 100 } 101 return userSelectedOutgoingPhoneAccount; 102 } catch (Exception e) { 103 Log.e(this, e, "getUserSelectedOutgoingPhoneAccount"); 104 throw e; 105 } 106 } 107 } 108 109 @Override 110 public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) { 111 synchronized (mLock) { 112 enforceModifyPermission(); 113 114 long token = Binder.clearCallingIdentity(); 115 try { 116 mPhoneAccountRegistrar.setUserSelectedOutgoingPhoneAccount(accountHandle); 117 } catch (Exception e) { 118 Log.e(this, e, "setUserSelectedOutgoingPhoneAccount"); 119 throw e; 120 } finally { 121 Binder.restoreCallingIdentity(token); 122 } 123 } 124 } 125 126 @Override 127 public List<PhoneAccountHandle> getCallCapablePhoneAccounts( 128 boolean includeDisabledAccounts, String callingPackage) { 129 if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) { 130 return Collections.emptyList(); 131 } 132 133 synchronized (mLock) { 134 long token = Binder.clearCallingIdentity(); 135 try { 136 // TODO: Does this isVisible check actually work considering we are clearing 137 // the calling identity? 138 return filterForAccountsVisibleToCaller( 139 mPhoneAccountRegistrar.getCallCapablePhoneAccounts( 140 null, includeDisabledAccounts)); 141 } catch (Exception e) { 142 Log.e(this, e, "getCallCapablePhoneAccounts"); 143 throw e; 144 } finally { 145 Binder.restoreCallingIdentity(token); 146 } 147 } 148 } 149 150 @Override 151 public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme, 152 String callingPackage) { 153 synchronized (mLock) { 154 if (!canReadPhoneState(callingPackage, "getPhoneAccountsSupportingScheme")) { 155 return Collections.emptyList(); 156 } 157 158 long token = Binder.clearCallingIdentity(); 159 try { 160 // TODO: Does this isVisible check actually work considering we are clearing 161 // the calling identity? 162 return filterForAccountsVisibleToCaller( 163 mPhoneAccountRegistrar.getCallCapablePhoneAccounts(uriScheme, false)); 164 } catch (Exception e) { 165 Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme); 166 throw e; 167 } finally { 168 Binder.restoreCallingIdentity(token); 169 } 170 } 171 } 172 173 @Override 174 public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) { 175 synchronized (mLock) { 176 try { 177 return filterForAccountsVisibleToCaller( 178 mPhoneAccountRegistrar.getPhoneAccountsForPackage(packageName)); 179 } catch (Exception e) { 180 Log.e(this, e, "getPhoneAccountsForPackage %s", packageName); 181 throw e; 182 } 183 } 184 } 185 186 @Override 187 public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) { 188 synchronized (mLock) { 189 try { 190 if (!isVisibleToCaller(accountHandle)) { 191 Log.w(this, "%s is not visible for the calling user", accountHandle); 192 return null; 193 } 194 // TODO: Do we really want to return for *any* user? 195 return mPhoneAccountRegistrar.getPhoneAccount(accountHandle); 196 } catch (Exception e) { 197 Log.e(this, e, "getPhoneAccount %s", accountHandle); 198 throw e; 199 } 200 } 201 } 202 203 @Override 204 public int getAllPhoneAccountsCount() { 205 synchronized (mLock) { 206 try { 207 // This list is pre-filtered for the calling user. 208 return getAllPhoneAccounts().size(); 209 } catch (Exception e) { 210 Log.e(this, e, "getAllPhoneAccountsCount"); 211 throw e; 212 } 213 } 214 } 215 216 @Override 217 public List<PhoneAccount> getAllPhoneAccounts() { 218 synchronized (mLock) { 219 try { 220 List<PhoneAccount> allPhoneAccounts = mPhoneAccountRegistrar 221 .getAllPhoneAccounts(); 222 List<PhoneAccount> profilePhoneAccounts = new ArrayList<>( 223 allPhoneAccounts.size()); 224 for (PhoneAccount phoneAccount : profilePhoneAccounts) { 225 if (isVisibleToCaller(phoneAccount)) { 226 profilePhoneAccounts.add(phoneAccount); 227 } 228 } 229 return profilePhoneAccounts; 230 } catch (Exception e) { 231 Log.e(this, e, "getAllPhoneAccounts"); 232 throw e; 233 } 234 } 235 } 236 237 @Override 238 public List<PhoneAccountHandle> getAllPhoneAccountHandles() { 239 synchronized (mLock) { 240 try { 241 return filterForAccountsVisibleToCaller( 242 mPhoneAccountRegistrar.getAllPhoneAccountHandles()); 243 } catch (Exception e) { 244 Log.e(this, e, "getAllPhoneAccounts"); 245 throw e; 246 } 247 } 248 } 249 250 @Override 251 public PhoneAccountHandle getSimCallManager() { 252 synchronized (mLock) { 253 try { 254 PhoneAccountHandle accountHandle = mPhoneAccountRegistrar.getSimCallManager(); 255 if (!isVisibleToCaller(accountHandle)) { 256 Log.w(this, "%s is not visible for the calling user", accountHandle); 257 return null; 258 } 259 return accountHandle; 260 } catch (Exception e) { 261 Log.e(this, e, "getSimCallManager"); 262 throw e; 263 } 264 } 265 } 266 267 @Override 268 public void setSimCallManager(PhoneAccountHandle accountHandle) { 269 synchronized (mLock) { 270 enforceModifyPermission(); 271 try { 272 mPhoneAccountRegistrar.setSimCallManager(accountHandle); 273 } catch (Exception e) { 274 Log.e(this, e, "setSimCallManager"); 275 throw e; 276 } 277 } 278 } 279 280 @Override 281 public List<PhoneAccountHandle> getSimCallManagers(String callingPackage) { 282 synchronized (mLock) { 283 if (!canReadPhoneState(callingPackage, "getSimCallManagers")) { 284 return Collections.emptyList(); 285 } 286 287 long token = Binder.clearCallingIdentity(); 288 try { 289 // TODO: Does this isVisible check actually work considering we are clearing 290 // the calling identity? 291 return filterForAccountsVisibleToCaller( 292 mPhoneAccountRegistrar.getConnectionManagerPhoneAccounts()); 293 } catch (Exception e) { 294 Log.e(this, e, "getSimCallManagers"); 295 throw e; 296 } finally { 297 Binder.restoreCallingIdentity(token); 298 } 299 } 300 } 301 302 @Override 303 public void registerPhoneAccount(PhoneAccount account) { 304 synchronized (mLock) { 305 try { 306 enforcePhoneAccountModificationForPackage( 307 account.getAccountHandle().getComponentName().getPackageName()); 308 if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)) { 309 enforceRegisterCallProviderPermission(); 310 } 311 if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) { 312 enforceRegisterSimSubscriptionPermission(); 313 } 314 if (account.hasCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)) { 315 enforceRegisterConnectionManagerPermission(); 316 } 317 if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) { 318 enforceRegisterMultiUser(); 319 } 320 enforceUserHandleMatchesCaller(account.getAccountHandle()); 321 322 mPhoneAccountRegistrar.registerPhoneAccount(account); 323 324 // Broadcast an intent indicating the phone account which was registered. 325 long token = Binder.clearCallingIdentity(); 326 try { 327 Intent intent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED); 328 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 329 account.getAccountHandle()); 330 Log.i(this, "Sending phone-account intent as user"); 331 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 332 PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION); 333 } finally { 334 Binder.restoreCallingIdentity(token); 335 } 336 } catch (Exception e) { 337 Log.e(this, e, "registerPhoneAccount %s", account); 338 throw e; 339 } 340 } 341 } 342 343 @Override 344 public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) { 345 synchronized (mLock) { 346 try { 347 enforcePhoneAccountModificationForPackage( 348 accountHandle.getComponentName().getPackageName()); 349 enforceUserHandleMatchesCaller(accountHandle); 350 mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle); 351 } catch (Exception e) { 352 Log.e(this, e, "unregisterPhoneAccount %s", accountHandle); 353 throw e; 354 } 355 } 356 } 357 358 @Override 359 public void clearAccounts(String packageName) { 360 synchronized (mLock) { 361 try { 362 enforcePhoneAccountModificationForPackage(packageName); 363 mPhoneAccountRegistrar 364 .clearAccounts(packageName, Binder.getCallingUserHandle()); 365 } catch (Exception e) { 366 Log.e(this, e, "clearAccounts %s", packageName); 367 throw e; 368 } 369 } 370 } 371 372 /** 373 * @see android.telecom.TelecomManager#isVoiceMailNumber 374 */ 375 @Override 376 public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number, 377 String callingPackage) { 378 synchronized (mLock) { 379 if (!isPrivilegedDialerCalling(callingPackage) 380 && !canReadPhoneState(callingPackage, "isVoiceMailNumber")) { 381 return false; 382 } 383 384 if (!isVisibleToCaller(accountHandle)) { 385 Log.w(this, "%s is not visible for the calling user", accountHandle); 386 return false; 387 } 388 389 long token = Binder.clearCallingIdentity(); 390 try { 391 return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number); 392 } catch (Exception e) { 393 Log.e(this, e, "getSubscriptionIdForPhoneAccount"); 394 throw e; 395 } finally { 396 Binder.restoreCallingIdentity(token); 397 } 398 } 399 } 400 401 /** 402 * @see android.telecom.TelecomManager#getVoiceMailNumber 403 */ 404 @Override 405 public String getVoiceMailNumber(PhoneAccountHandle accountHandle, String callingPackage) { 406 synchronized (mLock) { 407 if (!isPrivilegedDialerCalling(callingPackage) 408 && !canReadPhoneState(callingPackage, "getVoiceMailNumber")) { 409 return null; 410 } 411 412 try { 413 if (!isVisibleToCaller(accountHandle)) { 414 Log.w(this, "%s is not visible for the calling user", accountHandle); 415 return null; 416 } 417 418 int subId = SubscriptionManager.getDefaultVoiceSubId(); 419 if (accountHandle != null) { 420 subId = mPhoneAccountRegistrar 421 .getSubscriptionIdForPhoneAccount(accountHandle); 422 } 423 return getTelephonyManager().getVoiceMailNumber(subId); 424 } catch (Exception e) { 425 Log.e(this, e, "getSubscriptionIdForPhoneAccount"); 426 throw e; 427 } 428 } 429 } 430 431 /** 432 * @see android.telecom.TelecomManager#getLine1Number 433 */ 434 @Override 435 public String getLine1Number(PhoneAccountHandle accountHandle, String callingPackage) { 436 if (!isPrivilegedDialerCalling(callingPackage) 437 && !canReadPhoneState(callingPackage, "getLine1Number")) { 438 return null; 439 } 440 441 synchronized (mLock) { 442 if (!isVisibleToCaller(accountHandle)) { 443 Log.w(this, "%s is not visible for the calling user", accountHandle); 444 return null; 445 } 446 447 long token = Binder.clearCallingIdentity(); 448 try { 449 int subId = 450 mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle); 451 return getTelephonyManager().getLine1NumberForSubscriber(subId); 452 } catch (Exception e) { 453 Log.e(this, e, "getSubscriptionIdForPhoneAccount"); 454 throw e; 455 } finally { 456 Binder.restoreCallingIdentity(token); 457 } 458 } 459 } 460 461 /** 462 * @see android.telecom.TelecomManager#silenceRinger 463 */ 464 @Override 465 public void silenceRinger(String callingPackage) { 466 synchronized (mLock) { 467 enforceModifyPermissionOrPrivilegedDialer(callingPackage); 468 469 long token = Binder.clearCallingIdentity(); 470 try { 471 mCallsManager.getRinger().silence(); 472 } finally { 473 Binder.restoreCallingIdentity(token); 474 } 475 } 476 } 477 478 /** 479 * @see android.telecom.TelecomManager#getDefaultPhoneApp 480 * @deprecated - Use {@link android.telecom.TelecomManager#getDefaultDialerPackage()} 481 * instead. 482 */ 483 @Override 484 public ComponentName getDefaultPhoneApp() { 485 // No need to synchronize 486 Resources resources = mContext.getResources(); 487 return new ComponentName( 488 resources.getString(R.string.ui_default_package), 489 resources.getString(R.string.dialer_default_class)); 490 } 491 492 /** 493 * @return the package name of the current user-selected default dialer. If no default 494 * has been selected, the package name of the system dialer is returned. If 495 * neither exists, then {@code null} is returned. 496 * @see android.telecom.TelecomManager#getDefaultDialerPackage 497 */ 498 @Override 499 public String getDefaultDialerPackage() { 500 final long token = Binder.clearCallingIdentity(); 501 try { 502 return DefaultDialerManager.getDefaultDialerApplication(mContext); 503 } finally { 504 Binder.restoreCallingIdentity(token); 505 } 506 } 507 508 /** 509 * @see android.telecom.TelecomManager#getSystemDialerPackage 510 */ 511 @Override 512 public String getSystemDialerPackage() { 513 return mContext.getResources().getString(R.string.ui_default_package); 514 } 515 516 /** 517 * @see android.telecom.TelecomManager#isInCall 518 */ 519 @Override 520 public boolean isInCall(String callingPackage) { 521 if (!canReadPhoneState(callingPackage, "isInCall")) { 522 return false; 523 } 524 525 synchronized (mLock) { 526 final int callState = mCallsManager.getCallState(); 527 return callState == TelephonyManager.CALL_STATE_OFFHOOK 528 || callState == TelephonyManager.CALL_STATE_RINGING; 529 } 530 } 531 532 /** 533 * @see android.telecom.TelecomManager#isRinging 534 */ 535 @Override 536 public boolean isRinging(String callingPackage) { 537 if (!canReadPhoneState(callingPackage, "isRinging")) { 538 return false; 539 } 540 541 synchronized (mLock) { 542 return mCallsManager.getCallState() == TelephonyManager.CALL_STATE_RINGING; 543 } 544 } 545 546 /** 547 * @see TelecomManager#getCallState 548 */ 549 @Override 550 public int getCallState() { 551 synchronized (mLock) { 552 return mCallsManager.getCallState(); 553 } 554 } 555 556 /** 557 * @see android.telecom.TelecomManager#endCall 558 */ 559 @Override 560 public boolean endCall() { 561 synchronized (mLock) { 562 enforceModifyPermission(); 563 564 long token = Binder.clearCallingIdentity(); 565 try { 566 return endCallInternal(); 567 } finally { 568 Binder.restoreCallingIdentity(token); 569 } 570 } 571 } 572 573 /** 574 * @see android.telecom.TelecomManager#acceptRingingCall 575 */ 576 @Override 577 public void acceptRingingCall() { 578 synchronized (mLock) { 579 enforceModifyPermission(); 580 581 long token = Binder.clearCallingIdentity(); 582 try { 583 acceptRingingCallInternal(); 584 } finally { 585 Binder.restoreCallingIdentity(token); 586 } 587 } 588 } 589 590 /** 591 * @see android.telecom.TelecomManager#showInCallScreen 592 */ 593 @Override 594 public void showInCallScreen(boolean showDialpad, String callingPackage) { 595 if (!isPrivilegedDialerCalling(callingPackage) 596 && !canReadPhoneState(callingPackage, "showInCallScreen")) { 597 return; 598 } 599 600 synchronized (mLock) { 601 602 long token = Binder.clearCallingIdentity(); 603 try { 604 mCallsManager.getInCallController().bringToForeground(showDialpad); 605 } finally { 606 Binder.restoreCallingIdentity(token); 607 } 608 } 609 } 610 611 /** 612 * @see android.telecom.TelecomManager#cancelMissedCallsNotification 613 */ 614 @Override 615 public void cancelMissedCallsNotification(String callingPackage) { 616 synchronized (mLock) { 617 enforceModifyPermissionOrPrivilegedDialer(callingPackage); 618 long token = Binder.clearCallingIdentity(); 619 try { 620 mCallsManager.getMissedCallNotifier().clearMissedCalls(); 621 } finally { 622 Binder.restoreCallingIdentity(token); 623 } 624 } 625 } 626 627 /** 628 * @see android.telecom.TelecomManager#handleMmi 629 */ 630 @Override 631 public boolean handlePinMmi(String dialString, String callingPackage) { 632 synchronized (mLock) { 633 enforceModifyPermissionOrPrivilegedDialer(callingPackage); 634 635 // Switch identity so that TelephonyManager checks Telecom's permissions instead. 636 long token = Binder.clearCallingIdentity(); 637 boolean retval = false; 638 try { 639 retval = getTelephonyManager().handlePinMmi(dialString); 640 } finally { 641 Binder.restoreCallingIdentity(token); 642 } 643 644 return retval; 645 } 646 } 647 648 /** 649 * @see android.telecom.TelecomManager#handleMmi 650 */ 651 @Override 652 public boolean handlePinMmiForPhoneAccount( 653 PhoneAccountHandle accountHandle, 654 String dialString, 655 String callingPackage) { 656 synchronized (mLock) { 657 enforceModifyPermissionOrPrivilegedDialer(callingPackage); 658 659 if (!isVisibleToCaller(accountHandle)) { 660 Log.w(this, "%s is not visible for the calling user", accountHandle); 661 return false; 662 } 663 664 // Switch identity so that TelephonyManager checks Telecom's permissions instead. 665 long token = Binder.clearCallingIdentity(); 666 boolean retval = false; 667 try { 668 int subId = mPhoneAccountRegistrar 669 .getSubscriptionIdForPhoneAccount(accountHandle); 670 retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString); 671 } finally { 672 Binder.restoreCallingIdentity(token); 673 } 674 675 return retval; 676 } 677 } 678 679 /** 680 * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount 681 */ 682 @Override 683 public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle, 684 String callingPackage) { 685 synchronized (mLock) { 686 enforceModifyPermissionOrPrivilegedDialer(callingPackage); 687 688 if (!isVisibleToCaller(accountHandle)) { 689 Log.w(this, "%s is not visible for the calling user", accountHandle); 690 return null; 691 } 692 693 // Switch identity so that TelephonyManager checks Telecom's permissions instead. 694 long token = Binder.clearCallingIdentity(); 695 String retval = "content://icc/adn/"; 696 try { 697 long subId = mPhoneAccountRegistrar 698 .getSubscriptionIdForPhoneAccount(accountHandle); 699 retval = retval + "subId/" + subId; 700 } finally { 701 Binder.restoreCallingIdentity(token); 702 } 703 704 return Uri.parse(retval); 705 } 706 } 707 708 /** 709 * @see android.telecom.TelecomManager#isTtySupported 710 */ 711 @Override 712 public boolean isTtySupported(String callingPackage) { 713 if (!canReadPhoneState(callingPackage, "hasVoiceMailNumber")) { 714 return false; 715 } 716 717 synchronized (mLock) { 718 return mCallsManager.isTtySupported(); 719 } 720 } 721 722 /** 723 * @see android.telecom.TelecomManager#getCurrentTtyMode 724 */ 725 @Override 726 public int getCurrentTtyMode(String callingPackage) { 727 if (!canReadPhoneState(callingPackage, "getCurrentTtyMode")) { 728 return TelecomManager.TTY_MODE_OFF; 729 } 730 731 synchronized (mLock) { 732 return mCallsManager.getCurrentTtyMode(); 733 } 734 } 735 736 /** 737 * @see android.telecom.TelecomManager#addNewIncomingCall 738 */ 739 @Override 740 public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) { 741 synchronized (mLock) { 742 Log.i(this, "Adding new incoming call with phoneAccountHandle %s", 743 phoneAccountHandle); 744 if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) { 745 mAppOpsManager.checkPackage( 746 Binder.getCallingUid(), 747 phoneAccountHandle.getComponentName().getPackageName()); 748 749 // Make sure it doesn't cross the UserHandle boundary 750 enforceUserHandleMatchesCaller(phoneAccountHandle); 751 long token = Binder.clearCallingIdentity(); 752 753 try { 754 Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL); 755 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 756 phoneAccountHandle); 757 intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, true); 758 if (extras != null) { 759 intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras); 760 } 761 CallIntentProcessor.processIncomingCallIntent(mCallsManager, intent); 762 } finally { 763 Binder.restoreCallingIdentity(token); 764 } 765 } else { 766 Log.w(this, 767 "Null phoneAccountHandle. Ignoring request to add new incoming call"); 768 } 769 } 770 } 771 772 /** 773 * @see android.telecom.TelecomManager#addNewUnknownCall 774 */ 775 @Override 776 public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) { 777 synchronized (mLock) { 778 if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) { 779 mAppOpsManager.checkPackage( 780 Binder.getCallingUid(), 781 phoneAccountHandle.getComponentName().getPackageName()); 782 783 // Make sure it doesn't cross the UserHandle boundary 784 enforceUserHandleMatchesCaller(phoneAccountHandle); 785 long token = Binder.clearCallingIdentity(); 786 787 try { 788 Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL); 789 intent.putExtras(extras); 790 intent.putExtra(CallIntentProcessor.KEY_IS_UNKNOWN_CALL, true); 791 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 792 phoneAccountHandle); 793 CallIntentProcessor.processUnknownCallIntent(mCallsManager, intent); 794 } finally { 795 Binder.restoreCallingIdentity(token); 796 } 797 } else { 798 Log.i(this, 799 "Null phoneAccountHandle or not initiated by Telephony. " + 800 "Ignoring request to add new unknown call."); 801 } 802 } 803 } 804 805 /** 806 * @see android.telecom.TelecomManager#placeCall 807 */ 808 @Override 809 public void placeCall(Uri handle, Bundle extras, String callingPackage) { 810 enforceCallingPackage(callingPackage); 811 if (!canCallPhone(callingPackage, "placeCall")) { 812 throw new SecurityException("Package " + callingPackage 813 + " is not allowed to place phone calls"); 814 } 815 synchronized (mLock) { 816 final UserHandle userHandle = Binder.getCallingUserHandle(); 817 long token = Binder.clearCallingIdentity(); 818 try { 819 final Intent intent = new Intent(Intent.ACTION_CALL, handle); 820 intent.putExtras(extras); 821 new UserCallIntentProcessor(mContext, userHandle).processIntent(intent, 822 callingPackage); 823 } finally { 824 Binder.restoreCallingIdentity(token); 825 } 826 } 827 } 828 829 /** 830 * @see android.telecom.TelecomManager#enablePhoneAccount 831 */ 832 @Override 833 public void enablePhoneAccount(PhoneAccountHandle accountHandle, boolean isEnabled) { 834 enforceModifyPermission(); 835 synchronized (mLock) { 836 long token = Binder.clearCallingIdentity(); 837 try { 838 // enable/disable phone account 839 mPhoneAccountRegistrar.enablePhoneAccount(accountHandle, isEnabled); 840 } finally { 841 Binder.restoreCallingIdentity(token); 842 } 843 } 844 } 845 846 /** 847 * Dumps the current state of the TelecomService. Used when generating problem reports. 848 * 849 * @param fd The file descriptor. 850 * @param writer The print writer to dump the state to. 851 * @param args Optional dump arguments. 852 */ 853 @Override 854 protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) { 855 if (mContext.checkCallingOrSelfPermission( 856 android.Manifest.permission.DUMP) 857 != PackageManager.PERMISSION_GRANTED) { 858 writer.println("Permission Denial: can't dump TelecomService " + 859 "from from pid=" + Binder.getCallingPid() + ", uid=" + 860 Binder.getCallingUid()); 861 return; 862 } 863 864 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 865 if (mCallsManager != null) { 866 pw.println("CallsManager: "); 867 pw.increaseIndent(); 868 mCallsManager.dump(pw); 869 pw.decreaseIndent(); 870 871 pw.println("PhoneAccountRegistrar: "); 872 pw.increaseIndent(); 873 mPhoneAccountRegistrar.dump(pw); 874 pw.decreaseIndent(); 875 } 876 877 Log.dumpCallEvents(pw); 878 } 879 }; 880 881 private Context mContext; 882 private AppOpsManager mAppOpsManager; 883 private UserManager mUserManager; 884 private PackageManager mPackageManager; 885 private CallsManager mCallsManager; 886 private final PhoneAccountRegistrar mPhoneAccountRegistrar; 887 private final TelecomSystem.SyncRoot mLock; 888 889 public TelecomServiceImpl( 890 Context context, 891 CallsManager callsManager, 892 PhoneAccountRegistrar phoneAccountRegistrar, 893 TelecomSystem.SyncRoot lock) { 894 mContext = context; 895 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 896 897 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 898 mPackageManager = mContext.getPackageManager(); 899 900 mCallsManager = callsManager; 901 mLock = lock; 902 mPhoneAccountRegistrar = phoneAccountRegistrar; 903 } 904 905 public ITelecomService.Stub getBinder() { 906 return mBinderImpl; 907 } 908 909 // 910 // Supporting methods for the ITelecomService interface implementation. 911 // 912 913 private boolean isVisibleToCaller(PhoneAccountHandle accountHandle) { 914 if (accountHandle == null) { 915 return false; 916 } 917 return isVisibleToCaller(mPhoneAccountRegistrar.getPhoneAccount(accountHandle)); 918 } 919 920 private boolean isVisibleToCaller(PhoneAccount account) { 921 if (account == null) { 922 return false; 923 } 924 925 // If this PhoneAccount has CAPABILITY_MULTI_USER, it should be visible to all users and 926 // all profiles. Only Telephony and SIP accounts should have this capability. 927 if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) { 928 return true; 929 } 930 931 UserHandle phoneAccountUserHandle = account.getAccountHandle().getUserHandle(); 932 if (phoneAccountUserHandle == null) { 933 return false; 934 } 935 936 if (phoneAccountUserHandle.equals(Binder.getCallingUserHandle())) { 937 return true; 938 } 939 940 List<UserHandle> profileUserHandles; 941 if (UserHandle.getCallingUserId() == UserHandle.USER_OWNER) { 942 profileUserHandles = mUserManager.getUserProfiles(); 943 } else { 944 // Otherwise, it has to be owned by the current caller's profile. 945 profileUserHandles = new ArrayList<>(1); 946 profileUserHandles.add(Binder.getCallingUserHandle()); 947 } 948 949 return profileUserHandles.contains(phoneAccountUserHandle); 950 } 951 952 /** 953 * Given a list of {@link PhoneAccountHandle}s, filter them to the ones that the calling 954 * user can see. 955 * 956 * @param phoneAccountHandles Unfiltered list of account handles. 957 * 958 * @return {@link PhoneAccountHandle}s visible to the calling user and its profiles. 959 */ 960 private List<PhoneAccountHandle> filterForAccountsVisibleToCaller( 961 List<PhoneAccountHandle> phoneAccountHandles) { 962 List<PhoneAccountHandle> profilePhoneAccountHandles = 963 new ArrayList<>(phoneAccountHandles.size()); 964 for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandles) { 965 if (isVisibleToCaller(phoneAccountHandle)) { 966 profilePhoneAccountHandles.add(phoneAccountHandle); 967 } 968 } 969 return profilePhoneAccountHandles; 970 } 971 972 private boolean isCallerSystemApp() { 973 int uid = Binder.getCallingUid(); 974 String[] packages = mPackageManager.getPackagesForUid(uid); 975 for (String packageName : packages) { 976 if (isPackageSystemApp(packageName)) { 977 return true; 978 } 979 } 980 return false; 981 } 982 983 private boolean isPackageSystemApp(String packageName) { 984 try { 985 ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName, 986 PackageManager.GET_META_DATA); 987 if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 988 return true; 989 } 990 } catch (PackageManager.NameNotFoundException e) { 991 } 992 return false; 993 } 994 995 private void acceptRingingCallInternal() { 996 Call call = mCallsManager.getFirstCallWithState(CallState.RINGING); 997 if (call != null) { 998 call.answer(call.getVideoState()); 999 } 1000 } 1001 1002 private boolean endCallInternal() { 1003 // Always operate on the foreground call if one exists, otherwise get the first call in 1004 // priority order by call-state. 1005 Call call = mCallsManager.getForegroundCall(); 1006 if (call == null) { 1007 call = mCallsManager.getFirstCallWithState( 1008 CallState.ACTIVE, 1009 CallState.DIALING, 1010 CallState.RINGING, 1011 CallState.ON_HOLD); 1012 } 1013 1014 if (call != null) { 1015 if (call.getState() == CallState.RINGING) { 1016 call.reject(false /* rejectWithMessage */, null); 1017 } else { 1018 call.disconnect(); 1019 } 1020 return true; 1021 } 1022 1023 return false; 1024 } 1025 1026 private void enforcePhoneAccountModificationForPackage(String packageName) { 1027 // TODO: Use a new telecomm permission for this instead of reusing modify. 1028 1029 int result = mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); 1030 1031 // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement 1032 // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They 1033 // may also modify PhoneAccounts on behalf of any 'packageName'. 1034 1035 if (result != PackageManager.PERMISSION_GRANTED) { 1036 // Other callers are only allowed to modify PhoneAccounts if the relevant system 1037 // feature is enabled ... 1038 enforceConnectionServiceFeature(); 1039 // ... and the PhoneAccounts they refer to are for their own package. 1040 enforceCallingPackage(packageName); 1041 } 1042 } 1043 1044 private void enforceModifyPermissionOrPrivilegedDialer(String packageName) { 1045 if (!isPrivilegedDialerCalling(packageName)) { 1046 try { 1047 enforceModifyPermission(); 1048 } catch (SecurityException e) { 1049 Log.e(this, e, "Caller must be the default or system dialer, or have the system" 1050 + " only permission MODIFY_PHONE_STATE to perform this operation."); 1051 throw e; 1052 } 1053 } 1054 } 1055 1056 private void enforceCallingPackage(String packageName) { 1057 mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName); 1058 } 1059 1060 private void enforceConnectionServiceFeature() { 1061 enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE); 1062 } 1063 1064 private void enforceRegisterCallProviderPermission() { 1065 enforcePermission(android.Manifest.permission.REGISTER_CALL_PROVIDER); 1066 } 1067 1068 private void enforceRegisterSimSubscriptionPermission() { 1069 enforcePermission(android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION); 1070 } 1071 1072 private void enforceRegisterConnectionManagerPermission() { 1073 enforcePermission(android.Manifest.permission.REGISTER_CONNECTION_MANAGER); 1074 } 1075 1076 private void enforceModifyPermission() { 1077 enforcePermission(Manifest.permission.MODIFY_PHONE_STATE); 1078 } 1079 1080 private void enforcePermission(String permission) { 1081 mContext.enforceCallingOrSelfPermission(permission, null); 1082 } 1083 1084 private void enforceRegisterMultiUser() { 1085 if (!isCallerSystemApp()) { 1086 throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps."); 1087 } 1088 } 1089 1090 private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) { 1091 if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) { 1092 throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's"); 1093 } 1094 } 1095 1096 private void enforceFeature(String feature) { 1097 PackageManager pm = mContext.getPackageManager(); 1098 if (!pm.hasSystemFeature(feature)) { 1099 throw new UnsupportedOperationException( 1100 "System does not support feature " + feature); 1101 } 1102 } 1103 1104 private boolean canReadPhoneState(String callingPackage, String message) { 1105 // Accessing phone state is gated by a special permission. 1106 mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE, message); 1107 1108 // Some apps that have the permission can be restricted via app ops. 1109 return mAppOpsManager.noteOp(AppOpsManager.OP_READ_PHONE_STATE, 1110 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED; 1111 } 1112 1113 private boolean canCallPhone(String callingPackage, String message) { 1114 // Accessing phone state is gated by a special permission. 1115 mContext.enforceCallingOrSelfPermission(Manifest.permission.CALL_PHONE, message); 1116 1117 // Some apps that have the permission can be restricted via app ops. 1118 return mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE, 1119 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED; 1120 } 1121 1122 private boolean isCallerSimCallManager() { 1123 PhoneAccountHandle accountHandle = TelecomSystem.getInstance().getPhoneAccountRegistrar() 1124 .getSimCallManager(); 1125 if (accountHandle != null) { 1126 try { 1127 mAppOpsManager.checkPackage( 1128 Binder.getCallingUid(), accountHandle.getComponentName().getPackageName()); 1129 return true; 1130 } catch (SecurityException e) { 1131 } 1132 } 1133 return false; 1134 } 1135 1136 private boolean isPrivilegedDialerCalling(String callingPackage) { 1137 mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage); 1138 return DefaultDialerManager.isDefaultOrSystemDialer(mContext, callingPackage); 1139 } 1140 1141 private TelephonyManager getTelephonyManager() { 1142 return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE); 1143 } 1144} 1145