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