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