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