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