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