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