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