TelecomServiceImpl.java revision 8de76915ea2772faeb41705aaaeb65f5b3478ac4
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 android.Manifest; 20import android.app.AppOpsManager; 21import android.content.ComponentName; 22import android.content.Context; 23import android.content.Intent; 24import android.content.pm.ApplicationInfo; 25import android.content.pm.PackageManager; 26import android.content.res.Resources; 27import android.net.Uri; 28import android.os.Binder; 29import android.os.Bundle; 30import android.os.Handler; 31import android.os.IBinder; 32import android.os.Looper; 33import android.os.Message; 34import android.os.UserHandle; 35import android.os.UserManager; 36import android.telecom.CallState; 37import android.telecom.PhoneAccount; 38import android.telecom.PhoneAccountHandle; 39import android.telecom.TelecomManager; 40import android.telephony.SubscriptionManager; 41import android.telephony.TelephonyManager; 42import android.text.TextUtils; 43 44// TODO: Needed for move to system service: import com.android.internal.R; 45import com.android.internal.telecom.ITelecomService; 46import com.android.internal.util.IndentingPrintWriter; 47 48import java.io.FileDescriptor; 49import java.io.PrintWriter; 50import java.util.ArrayList; 51import java.util.List; 52 53/** 54 * Implementation of the ITelecom interface. 55 */ 56public class TelecomServiceImpl { 57 private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION = 58 "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION"; 59 60 /** The context. */ 61 private Context mContext; 62 63 /** 64 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the 65 * request after sending. The main thread will notify the request when it is complete. 66 */ 67 private static final class MainThreadRequest { 68 /** The result of the request that is run on the main thread */ 69 public Object result; 70 /** Object that can be used to store non-integer arguments */ 71 public Object arg; 72 } 73 74 /** 75 * A handler that processes messages on the main thread. Since many of the method calls are not 76 * thread safe this is needed to shuttle the requests from the inbound binder threads to the 77 * main thread. 78 */ 79 private final class MainThreadHandler extends Handler { 80 @Override 81 public void handleMessage(Message msg) { 82 if (msg.obj instanceof MainThreadRequest) { 83 MainThreadRequest request = (MainThreadRequest) msg.obj; 84 Object result = null; 85 switch (msg.what) { 86 case MSG_SILENCE_RINGER: 87 mCallsManager.getRinger().silence(); 88 break; 89 case MSG_SHOW_CALL_SCREEN: 90 mCallsManager.getInCallController().bringToForeground(msg.arg1 == 1); 91 break; 92 case MSG_END_CALL: 93 result = endCallInternal(); 94 break; 95 case MSG_ACCEPT_RINGING_CALL: 96 acceptRingingCallInternal(); 97 break; 98 case MSG_CANCEL_MISSED_CALLS_NOTIFICATION: 99 mCallsManager.getMissedCallNotifier().clearMissedCalls(); 100 break; 101 case MSG_IS_TTY_SUPPORTED: 102 result = mCallsManager.isTtySupported(); 103 break; 104 case MSG_GET_CURRENT_TTY_MODE: 105 result = mCallsManager.getCurrentTtyMode(); 106 break; 107 case MSG_NEW_INCOMING_CALL: 108 if (request.arg == null || !(request.arg instanceof Intent)) { 109 Log.w(this, "Invalid new incoming call request"); 110 break; 111 } 112 CallIntentProcessor.processIncomingCallIntent( 113 mCallsManager, 114 (Intent) request.arg); 115 break; 116 } 117 118 if (result != null) { 119 request.result = result; 120 synchronized(request) { 121 request.notifyAll(); 122 } 123 } 124 } 125 } 126 } 127 128 private static final String TAG = com.android.server.telecom.TelecomServiceImpl.class.getSimpleName(); 129 130 private static final String SERVICE_NAME = "telecom"; 131 132 private static final int MSG_SILENCE_RINGER = 1; 133 private static final int MSG_SHOW_CALL_SCREEN = 2; 134 private static final int MSG_END_CALL = 3; 135 private static final int MSG_ACCEPT_RINGING_CALL = 4; 136 private static final int MSG_CANCEL_MISSED_CALLS_NOTIFICATION = 5; 137 private static final int MSG_IS_TTY_SUPPORTED = 6; 138 private static final int MSG_GET_CURRENT_TTY_MODE = 7; 139 private static final int MSG_NEW_INCOMING_CALL = 8; 140 141 private final MainThreadHandler mMainThreadHandler = new MainThreadHandler(); 142 143 private final AppOpsManager mAppOpsManager; 144 private final UserManager mUserManager; 145 private final PackageManager mPackageManager; 146 private final TelecomBinderImpl mBinderImpl; 147 private final CallsManager mCallsManager; 148 private final PhoneAccountRegistrar mPhoneAccountRegistrar; 149 150 public TelecomServiceImpl( 151 Context context, 152 CallsManager callsManager, 153 PhoneAccountRegistrar phoneAccountRegistrar) { 154 mContext = context; 155 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 156 mBinderImpl = new TelecomBinderImpl(); 157 158 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 159 mPackageManager = mContext.getPackageManager(); 160 161 mCallsManager = callsManager; 162 mPhoneAccountRegistrar = phoneAccountRegistrar; 163 } 164 165 public IBinder getBinder() { 166 return mBinderImpl; 167 } 168 169 /** 170 * Implementation of the ITelecomService interface. 171 * TODO: Reorganize this inner class to top of file. 172 */ 173 class TelecomBinderImpl extends ITelecomService.Stub { 174 @Override 175 public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) { 176 enforceReadPermission(); 177 long token = Binder.clearCallingIdentity(); 178 try { 179 PhoneAccountHandle defaultOutgoingPhoneAccount = 180 mCallsManager.getPhoneAccountRegistrar().getDefaultOutgoingPhoneAccount(uriScheme); 181 // Make sure that the calling user can see this phone account. 182 if (defaultOutgoingPhoneAccount != null 183 && !isVisibleToCaller(defaultOutgoingPhoneAccount)) { 184 Log.w(this, "No account found for the calling user"); 185 return null; 186 } 187 return defaultOutgoingPhoneAccount; 188 } catch (Exception e) { 189 Log.e(this, e, "getDefaultOutgoingPhoneAccount"); 190 throw e; 191 } finally { 192 Binder.restoreCallingIdentity(token); 193 } 194 } 195 196 @Override 197 public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() { 198 try { 199 PhoneAccountHandle userSelectedOutgoingPhoneAccount = 200 mCallsManager.getPhoneAccountRegistrar().getUserSelectedOutgoingPhoneAccount(); 201 // Make sure that the calling user can see this phone account. 202 if (!isVisibleToCaller(userSelectedOutgoingPhoneAccount)) { 203 Log.w(this, "No account found for the calling user"); 204 return null; 205 } 206 return userSelectedOutgoingPhoneAccount; 207 } catch (Exception e) { 208 Log.e(this, e, "getUserSelectedOutgoingPhoneAccount"); 209 throw e; 210 } 211 } 212 213 @Override 214 public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) { 215 enforceModifyPermission(); 216 217 try { 218 mCallsManager.getPhoneAccountRegistrar().setUserSelectedOutgoingPhoneAccount(accountHandle); 219 } catch (Exception e) { 220 Log.e(this, e, "setUserSelectedOutgoingPhoneAccount"); 221 throw e; 222 } 223 } 224 225 @Override 226 public List<PhoneAccountHandle> getCallCapablePhoneAccounts() { 227 enforceReadPermission(); 228 long token = Binder.clearCallingIdentity(); 229 try { 230 return filterForAccountsVisibleToCaller( 231 mCallsManager.getPhoneAccountRegistrar().getCallCapablePhoneAccounts()); 232 } catch (Exception e) { 233 Log.e(this, e, "getCallCapablePhoneAccounts"); 234 throw e; 235 } finally { 236 Binder.restoreCallingIdentity(token); 237 } 238 } 239 240 @Override 241 public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) { 242 enforceReadPermission(); 243 long token = Binder.clearCallingIdentity(); 244 try { 245 return filterForAccountsVisibleToCaller( 246 mCallsManager.getPhoneAccountRegistrar().getCallCapablePhoneAccounts(uriScheme)); 247 } catch (Exception e) { 248 Log.e(this, e, "getPhoneAccountsSupportingScheme %s", uriScheme); 249 throw e; 250 } finally { 251 Binder.restoreCallingIdentity(token); 252 } 253 } 254 255 @Override 256 public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) { 257 try { 258 return filterForAccountsVisibleToCaller( 259 mCallsManager.getPhoneAccountRegistrar().getPhoneAccountsForPackage(packageName)); 260 } catch (Exception e) { 261 Log.e(this, e, "getPhoneAccountsForPackage %s", packageName); 262 throw e; 263 } 264 } 265 266 @Override 267 public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle) { 268 try { 269 if (!isVisibleToCaller(accountHandle)) { 270 Log.w(this, "%s is not visible for the calling user", accountHandle); 271 return null; 272 } 273 return mCallsManager.getPhoneAccountRegistrar().getPhoneAccountInternal(accountHandle); 274 } catch (Exception e) { 275 Log.e(this, e, "getPhoneAccount %s", accountHandle); 276 throw e; 277 } 278 } 279 280 @Override 281 public int getAllPhoneAccountsCount() { 282 try { 283 // This list is pre-filtered for the calling user. 284 return getAllPhoneAccounts().size(); 285 } catch (Exception e) { 286 Log.e(this, e, "getAllPhoneAccountsCount"); 287 throw e; 288 } 289 } 290 291 @Override 292 public List<PhoneAccount> getAllPhoneAccounts() { 293 try { 294 List<PhoneAccount> allPhoneAccounts = mCallsManager.getPhoneAccountRegistrar().getAllPhoneAccounts(); 295 List<PhoneAccount> profilePhoneAccounts = new ArrayList<>(allPhoneAccounts.size()); 296 for (PhoneAccount phoneAccount : profilePhoneAccounts) { 297 if (isVisibleToCaller(phoneAccount)) { 298 profilePhoneAccounts.add(phoneAccount); 299 } 300 } 301 return profilePhoneAccounts; 302 } catch (Exception e) { 303 Log.e(this, e, "getAllPhoneAccounts"); 304 throw e; 305 } 306 } 307 308 @Override 309 public List<PhoneAccountHandle> getAllPhoneAccountHandles() { 310 try { 311 return filterForAccountsVisibleToCaller( 312 mCallsManager.getPhoneAccountRegistrar().getAllPhoneAccountHandles()); 313 } catch (Exception e) { 314 Log.e(this, e, "getAllPhoneAccounts"); 315 throw e; 316 } 317 } 318 319 @Override 320 public PhoneAccountHandle getSimCallManager() { 321 try { 322 PhoneAccountHandle accountHandle = mCallsManager.getPhoneAccountRegistrar().getSimCallManager(); 323 if (!isVisibleToCaller(accountHandle)) { 324 Log.w(this, "%s is not visible for the calling user", accountHandle); 325 return null; 326 } 327 return accountHandle; 328 } catch (Exception e) { 329 Log.e(this, e, "getSimCallManager"); 330 throw e; 331 } 332 } 333 334 @Override 335 public void setSimCallManager(PhoneAccountHandle accountHandle) { 336 enforceModifyPermission(); 337 338 try { 339 mCallsManager.getPhoneAccountRegistrar().setSimCallManager(accountHandle); 340 } catch (Exception e) { 341 Log.e(this, e, "setSimCallManager"); 342 throw e; 343 } 344 } 345 346 @Override 347 public List<PhoneAccountHandle> getSimCallManagers() { 348 enforceReadPermission(); 349 long token = Binder.clearCallingIdentity(); 350 try { 351 return filterForAccountsVisibleToCaller( 352 mCallsManager.getPhoneAccountRegistrar().getConnectionManagerPhoneAccounts()); 353 } catch (Exception e) { 354 Log.e(this, e, "getSimCallManagers"); 355 throw e; 356 } finally { 357 Binder.restoreCallingIdentity(token); 358 } 359 } 360 361 @Override 362 public void registerPhoneAccount(PhoneAccount account) { 363 try { 364 enforcePhoneAccountModificationForPackage( 365 account.getAccountHandle().getComponentName().getPackageName()); 366 if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)) { 367 enforceRegisterCallProviderPermission(); 368 } 369 if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) { 370 enforceRegisterSimSubscriptionPermission(); 371 } 372 if (account.hasCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)) { 373 enforceRegisterConnectionManagerPermission(); 374 } 375 if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) { 376 enforceRegisterMultiUser(); 377 } 378 enforceUserHandleMatchesCaller(account.getAccountHandle()); 379 380 mPhoneAccountRegistrar.registerPhoneAccount(account); 381 382 // Broadcast an intent indicating the phone account which was registered. 383 long token = Binder.clearCallingIdentity(); 384 Intent intent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED); 385 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 386 account.getAccountHandle()); 387 Log.i(this, "Sending phone-account intent as user"); 388 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 389 PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION); 390 Binder.restoreCallingIdentity(token); 391 } catch (Exception e) { 392 Log.e(this, e, "registerPhoneAccount %s", account); 393 throw e; 394 } 395 } 396 397 @Override 398 public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) { 399 try { 400 enforcePhoneAccountModificationForPackage( 401 accountHandle.getComponentName().getPackageName()); 402 enforceUserHandleMatchesCaller(accountHandle); 403 mCallsManager.getPhoneAccountRegistrar().unregisterPhoneAccount(accountHandle); 404 } catch (Exception e) { 405 Log.e(this, e, "unregisterPhoneAccount %s", accountHandle); 406 throw e; 407 } 408 } 409 410 @Override 411 public void clearAccounts(String packageName) { 412 try { 413 enforcePhoneAccountModificationForPackage(packageName); 414 mCallsManager.getPhoneAccountRegistrar().clearAccounts(packageName, Binder.getCallingUserHandle()); 415 } catch (Exception e) { 416 Log.e(this, e, "clearAccounts %s", packageName); 417 throw e; 418 } 419 } 420 421 /** 422 * @see android.telecom.TelecomManager#isVoiceMailNumber 423 */ 424 @Override 425 public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) { 426 enforceReadPermissionOrDefaultDialer(); 427 try { 428 if (!isVisibleToCaller(accountHandle)) { 429 Log.w(this, "%s is not visible for the calling user", accountHandle); 430 return false; 431 } 432 return mCallsManager.getPhoneAccountRegistrar().isVoiceMailNumber(accountHandle, number); 433 } catch (Exception e) { 434 Log.e(this, e, "getSubscriptionIdForPhoneAccount"); 435 throw e; 436 } 437 } 438 439 /** 440 * @see android.telecom.TelecomManager#hasVoiceMailNumber 441 */ 442 @Override 443 public boolean hasVoiceMailNumber(PhoneAccountHandle accountHandle) { 444 enforceReadPermissionOrDefaultDialer(); 445 try { 446 if (!isVisibleToCaller(accountHandle)) { 447 Log.w(this, "%s is not visible for the calling user", accountHandle); 448 return false; 449 } 450 451 int subId = SubscriptionManager.getDefaultVoiceSubId(); 452 if (accountHandle != null) { 453 subId = mCallsManager.getPhoneAccountRegistrar().getSubscriptionIdForPhoneAccount(accountHandle); 454 } 455 return !TextUtils.isEmpty(getTelephonyManager().getVoiceMailNumber(subId)); 456 } catch (Exception e) { 457 Log.e(this, e, "getSubscriptionIdForPhoneAccount"); 458 throw e; 459 } 460 } 461 462 /** 463 * @see android.telecom.TelecomManager#getLine1Number 464 */ 465 @Override 466 public String getLine1Number(PhoneAccountHandle accountHandle) { 467 enforceReadPermissionOrDefaultDialer(); 468 try { 469 if (!isVisibleToCaller(accountHandle)) { 470 Log.w(this, "%s is not visible for the calling user", accountHandle); 471 return null; 472 } 473 int subId = TelecomSystem.getInstance().getPhoneAccountRegistrar().getSubscriptionIdForPhoneAccount(accountHandle); 474 return getTelephonyManager().getLine1NumberForSubscriber(subId); 475 } catch (Exception e) { 476 Log.e(this, e, "getSubscriptionIdForPhoneAccount"); 477 throw e; 478 } 479 } 480 481 /** 482 * @see android.telecom.TelecomManager#silenceRinger 483 */ 484 @Override 485 public void silenceRinger() { 486 Log.d(this, "silenceRinger"); 487 enforceModifyPermission(); 488 sendRequestAsync(MSG_SILENCE_RINGER, 0); 489 } 490 491 /** 492 * @see android.telecom.TelecomManager#getDefaultPhoneApp 493 */ 494 @Override 495 public ComponentName getDefaultPhoneApp() { 496 Resources resources = mContext.getResources(); 497 return new ComponentName( 498 resources.getString(R.string.ui_default_package), 499 resources.getString(R.string.dialer_default_class)); 500 } 501 502 /** 503 * @see android.telecom.TelecomManager#isInCall 504 */ 505 @Override 506 public boolean isInCall() { 507 enforceReadPermission(); 508 // Do not use sendRequest() with this method since it could cause a deadlock with 509 // audio service, which we call into from the main thread: AudioManager.setMode(). 510 final int callState = mCallsManager.getCallState(); 511 return callState == TelephonyManager.CALL_STATE_OFFHOOK 512 || callState == TelephonyManager.CALL_STATE_RINGING; 513 } 514 515 /** 516 * @see android.telecom.TelecomManager#isRinging 517 */ 518 @Override 519 public boolean isRinging() { 520 enforceReadPermission(); 521 return mCallsManager.getCallState() == TelephonyManager.CALL_STATE_RINGING; 522 } 523 524 /** 525 * @see TelecomManager#getCallState 526 */ 527 @Override 528 public int getCallState() { 529 return mCallsManager.getCallState(); 530 } 531 532 /** 533 * @see android.telecom.TelecomManager#endCall 534 */ 535 @Override 536 public boolean endCall() { 537 enforceModifyPermission(); 538 return (boolean) sendRequest(MSG_END_CALL); 539 } 540 541 /** 542 * @see android.telecom.TelecomManager#acceptRingingCall 543 */ 544 @Override 545 public void acceptRingingCall() { 546 enforceModifyPermission(); 547 sendRequestAsync(MSG_ACCEPT_RINGING_CALL, 0); 548 } 549 550 /** 551 * @see android.telecom.TelecomManager#showInCallScreen 552 */ 553 @Override 554 public void showInCallScreen(boolean showDialpad) { 555 enforceReadPermissionOrDefaultDialer(); 556 sendRequestAsync(MSG_SHOW_CALL_SCREEN, showDialpad ? 1 : 0); 557 } 558 559 /** 560 * @see android.telecom.TelecomManager#cancelMissedCallsNotification 561 */ 562 @Override 563 public void cancelMissedCallsNotification() { 564 enforceModifyPermissionOrDefaultDialer(); 565 sendRequestAsync(MSG_CANCEL_MISSED_CALLS_NOTIFICATION, 0); 566 } 567 568 /** 569 * @see android.telecom.TelecomManager#handleMmi 570 */ 571 @Override 572 public boolean handlePinMmi(String dialString) { 573 enforceModifyPermissionOrDefaultDialer(); 574 575 // Switch identity so that TelephonyManager checks Telecom's permissions instead. 576 long token = Binder.clearCallingIdentity(); 577 boolean retval = false; 578 try { 579 retval = getTelephonyManager().handlePinMmi(dialString); 580 } finally { 581 Binder.restoreCallingIdentity(token); 582 } 583 584 return retval; 585 } 586 587 /** 588 * @see android.telecom.TelecomManager#handleMmi 589 */ 590 @Override 591 public boolean handlePinMmiForPhoneAccount(PhoneAccountHandle accountHandle, 592 String dialString) { 593 enforceModifyPermissionOrDefaultDialer(); 594 595 if (!isVisibleToCaller(accountHandle)) { 596 Log.w(this, "%s is not visible for the calling user", accountHandle); 597 return false; 598 } 599 600 // Switch identity so that TelephonyManager checks Telecom's permissions instead. 601 long token = Binder.clearCallingIdentity(); 602 boolean retval = false; 603 try { 604 int subId = mCallsManager.getPhoneAccountRegistrar() 605 .getSubscriptionIdForPhoneAccount(accountHandle); 606 retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString); 607 } finally { 608 Binder.restoreCallingIdentity(token); 609 } 610 611 return retval; 612 } 613 614 /** 615 * @see android.telecom.TelecomManager#getAdnUriForPhoneAccount 616 */ 617 @Override 618 public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) { 619 enforceModifyPermissionOrDefaultDialer(); 620 621 if (!isVisibleToCaller(accountHandle)) { 622 Log.w(this, "%s is not visible for the calling user", accountHandle); 623 return null; 624 } 625 626 // Switch identity so that TelephonyManager checks Telecom's permissions instead. 627 long token = Binder.clearCallingIdentity(); 628 String retval = "content://icc/adn/"; 629 try { 630 long subId = mCallsManager.getPhoneAccountRegistrar() 631 .getSubscriptionIdForPhoneAccount(accountHandle); 632 retval = retval + "subId/" + subId; 633 } finally { 634 Binder.restoreCallingIdentity(token); 635 } 636 637 return Uri.parse(retval); 638 } 639 640 /** 641 * @see android.telecom.TelecomManager#isTtySupported 642 */ 643 @Override 644 public boolean isTtySupported() { 645 enforceReadPermission(); 646 return (boolean) sendRequest(MSG_IS_TTY_SUPPORTED); 647 } 648 649 /** 650 * @see android.telecom.TelecomManager#getCurrentTtyMode 651 */ 652 @Override 653 public int getCurrentTtyMode() { 654 enforceReadPermission(); 655 return (int) sendRequest(MSG_GET_CURRENT_TTY_MODE); 656 } 657 658 /** 659 * @see android.telecom.TelecomManager#addNewIncomingCall 660 */ 661 @Override 662 public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) { 663 Log.i(this, "Adding new incoming call with phoneAccountHandle %s", phoneAccountHandle); 664 if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) { 665 // TODO(sail): Add unit tests for adding incoming calls from a SIM call manager. 666 if (isCallerSimCallManager() && TelephonyUtil.isPstnComponentName( 667 phoneAccountHandle.getComponentName())) { 668 Log.v(this, "Allowing call manager to add incoming call with PSTN handle"); 669 } else { 670 mAppOpsManager.checkPackage(Binder.getCallingUid(), 671 phoneAccountHandle.getComponentName().getPackageName()); 672 // Make sure it doesn't cross the UserHandle boundary 673 enforceUserHandleMatchesCaller(phoneAccountHandle); 674 } 675 676 Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL); 677 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle); 678 intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, true); 679 if (extras != null) { 680 intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras); 681 } 682 sendRequestAsync(MSG_NEW_INCOMING_CALL, 0, intent); 683 } else { 684 Log.w(this, "Null phoneAccountHandle. Ignoring request to add new incoming call"); 685 } 686 } 687 688 /** 689 * @see android.telecom.TelecomManager#addNewUnknownCall 690 */ 691 @Override 692 public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) { 693 if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null && 694 TelephonyUtil.isPstnComponentName(phoneAccountHandle.getComponentName())) { 695 mAppOpsManager.checkPackage( 696 Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName()); 697 698 // Make sure it doesn't cross the UserHandle boundary 699 enforceUserHandleMatchesCaller(phoneAccountHandle); 700 701 Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL); 702 intent.setClass(mContext, CallIntentProcessor.class); 703 intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); 704 intent.putExtras(extras); 705 intent.putExtra(CallIntentProcessor.KEY_IS_UNKNOWN_CALL, true); 706 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle); 707 mContext.sendBroadcastAsUser(intent, phoneAccountHandle.getUserHandle()); 708 } else { 709 Log.i(this, "Null phoneAccountHandle or not initiated by Telephony. Ignoring request" 710 + " to add new unknown call."); 711 } 712 } 713 714 /** 715 * Dumps the current state of the TelecomService. Used when generating problem reports. 716 * 717 * @param fd The file descriptor. 718 * @param writer The print writer to dump the state to. 719 * @param args Optional dump arguments. 720 */ 721 @Override 722 protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) { 723 if (mContext.checkCallingOrSelfPermission( 724 android.Manifest.permission.DUMP) 725 != PackageManager.PERMISSION_GRANTED) { 726 writer.println("Permission Denial: can't dump TelecomService " + 727 "from from pid=" + Binder.getCallingPid() + ", uid=" + 728 Binder.getCallingUid()); 729 return; 730 } 731 732 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 733 if (mCallsManager != null) { 734 pw.println("CallsManager: "); 735 pw.increaseIndent(); 736 mCallsManager.dump(pw); 737 pw.decreaseIndent(); 738 739 pw.println("PhoneAccountRegistrar: "); 740 pw.increaseIndent(); 741 mCallsManager.getPhoneAccountRegistrar().dump(pw); 742 pw.decreaseIndent(); 743 } 744 } 745 } 746 747 // 748 // Supporting methods for the ITelecomService interface implementation. 749 // 750 751 private boolean isVisibleToCaller(PhoneAccountHandle accountHandle) { 752 if (accountHandle == null) { 753 return false; 754 } 755 756 return isVisibleToCaller(mCallsManager.getPhoneAccountRegistrar() 757 .getPhoneAccountInternal(accountHandle)); 758 } 759 760 private boolean isVisibleToCaller(PhoneAccount account) { 761 if (account == null) { 762 return false; 763 } 764 765 // If this PhoneAccount has CAPABILITY_MULTI_USER, it should be visible to all users and 766 // all profiles. Only Telephony and SIP accounts should have this capability. 767 if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) { 768 return true; 769 } 770 771 UserHandle phoneAccountUserHandle = account.getAccountHandle().getUserHandle(); 772 if (phoneAccountUserHandle == null) { 773 return false; 774 } 775 776 if (phoneAccountUserHandle.equals(Binder.getCallingUserHandle())) { 777 return true; 778 } 779 780 List<UserHandle> profileUserHandles; 781 if (UserHandle.getCallingUserId() == UserHandle.USER_OWNER) { 782 profileUserHandles = mUserManager.getUserProfiles(); 783 } else { 784 // Otherwise, it has to be owned by the current caller's profile. 785 profileUserHandles = new ArrayList<>(1); 786 profileUserHandles.add(Binder.getCallingUserHandle()); 787 } 788 789 return profileUserHandles.contains(phoneAccountUserHandle); 790 } 791 792 /** 793 * Given a list of {@link PhoneAccountHandle}s, filter them to the ones that the calling 794 * user can see. 795 * 796 * @param phoneAccountHandles Unfiltered list of account handles. 797 * 798 * @return {@link PhoneAccountHandle}s visible to the calling user and its profiles. 799 */ 800 private List<PhoneAccountHandle> filterForAccountsVisibleToCaller( 801 List<PhoneAccountHandle> phoneAccountHandles) { 802 List<PhoneAccountHandle> profilePhoneAccountHandles = 803 new ArrayList<>(phoneAccountHandles.size()); 804 for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandles) { 805 if (isVisibleToCaller(phoneAccountHandle)) { 806 profilePhoneAccountHandles.add(phoneAccountHandle); 807 } 808 } 809 return profilePhoneAccountHandles; 810 } 811 812 private boolean isCallerSystemApp() { 813 int uid = Binder.getCallingUid(); 814 String[] packages = mPackageManager.getPackagesForUid(uid); 815 for (String packageName : packages) { 816 if (isPackageSystemApp(packageName)) { 817 return true; 818 } 819 } 820 return false; 821 } 822 823 private boolean isPackageSystemApp(String packageName) { 824 try { 825 ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName, 826 PackageManager.GET_META_DATA); 827 if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 828 return true; 829 } 830 } catch (PackageManager.NameNotFoundException e) { 831 } 832 return false; 833 } 834 835 private void acceptRingingCallInternal() { 836 Call call = mCallsManager.getFirstCallWithState(CallState.RINGING); 837 if (call != null) { 838 call.answer(call.getVideoState()); 839 } 840 } 841 842 private boolean endCallInternal() { 843 // Always operate on the foreground call if one exists, otherwise get the first call in 844 // priority order by call-state. 845 Call call = mCallsManager.getForegroundCall(); 846 if (call == null) { 847 call = mCallsManager.getFirstCallWithState( 848 CallState.ACTIVE, 849 CallState.DIALING, 850 CallState.RINGING, 851 CallState.ON_HOLD); 852 } 853 854 if (call != null) { 855 if (call.getState() == CallState.RINGING) { 856 call.reject(false /* rejectWithMessage */, null); 857 } else { 858 call.disconnect(); 859 } 860 return true; 861 } 862 863 return false; 864 } 865 866 private void enforcePhoneAccountModificationForPackage(String packageName) { 867 // TODO: Use a new telecomm permission for this instead of reusing modify. 868 869 int result = mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); 870 871 // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement 872 // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They 873 // may also modify PhoneAccounts on behalf of any 'packageName'. 874 875 if (result != PackageManager.PERMISSION_GRANTED) { 876 // Other callers are only allowed to modify PhoneAccounts if the relevant system 877 // feature is enabled ... 878 enforceConnectionServiceFeature(); 879 // ... and the PhoneAccounts they refer to are for their own package. 880 enforceCallingPackage(packageName); 881 } 882 } 883 884 private void enforceReadPermissionOrDefaultDialer() { 885 if (!isDefaultDialerCalling()) { 886 enforceReadPermission(); 887 } 888 } 889 890 private void enforceModifyPermissionOrDefaultDialer() { 891 if (!isDefaultDialerCalling()) { 892 enforceModifyPermission(); 893 } 894 } 895 896 private void enforceCallingPackage(String packageName) { 897 mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName); 898 } 899 900 private void enforceConnectionServiceFeature() { 901 enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE); 902 } 903 904 private void enforceRegisterCallProviderPermission() { 905 enforcePermission(android.Manifest.permission.REGISTER_CALL_PROVIDER); 906 } 907 908 private void enforceRegisterSimSubscriptionPermission() { 909 enforcePermission(android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION); 910 } 911 912 private void enforceRegisterConnectionManagerPermission() { 913 enforcePermission(android.Manifest.permission.REGISTER_CONNECTION_MANAGER); 914 } 915 916 private void enforceReadPermission() { 917 enforcePermission(Manifest.permission.READ_PHONE_STATE); 918 } 919 920 private void enforceModifyPermission() { 921 enforcePermission(Manifest.permission.MODIFY_PHONE_STATE); 922 } 923 924 private void enforcePermission(String permission) { 925 mContext.enforceCallingOrSelfPermission(permission, null); 926 } 927 928 private void enforceRegisterMultiUser() { 929 if (!isCallerSystemApp()) { 930 throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps."); 931 } 932 } 933 934 private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) { 935 if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) { 936 throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's"); 937 } 938 } 939 940 private void enforceFeature(String feature) { 941 PackageManager pm = mContext.getPackageManager(); 942 if (!pm.hasSystemFeature(feature)) { 943 throw new UnsupportedOperationException( 944 "System does not support feature " + feature); 945 } 946 } 947 948 private boolean isCallerSimCallManager() { 949 PhoneAccountHandle accountHandle = TelecomSystem.getInstance().getPhoneAccountRegistrar() 950 .getSimCallManager(); 951 if (accountHandle != null) { 952 try { 953 mAppOpsManager.checkPackage( 954 Binder.getCallingUid(), accountHandle.getComponentName().getPackageName()); 955 return true; 956 } catch (SecurityException e) { 957 } 958 } 959 return false; 960 } 961 962 private boolean isDefaultDialerCalling() { 963 ComponentName defaultDialerComponent = getDefaultPhoneAppInternal(); 964 if (defaultDialerComponent != null) { 965 try { 966 mAppOpsManager.checkPackage( 967 Binder.getCallingUid(), defaultDialerComponent.getPackageName()); 968 return true; 969 } catch (SecurityException e) { 970 Log.e(this, e, "Could not get default dialer."); 971 } 972 } 973 return false; 974 } 975 976 private ComponentName getDefaultPhoneAppInternal() { 977 Resources resources = mContext.getResources(); 978 return new ComponentName( 979 resources.getString(R.string.ui_default_package), 980 resources.getString(R.string.dialer_default_class)); 981 } 982 983 private TelephonyManager getTelephonyManager() { 984 return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE); 985 } 986 987 private MainThreadRequest sendRequestAsync(int command, int arg1) { 988 return sendRequestAsync(command, arg1, null); 989 } 990 991 private MainThreadRequest sendRequestAsync(int command, int arg1, Object arg) { 992 MainThreadRequest request = new MainThreadRequest(); 993 request.arg = arg; 994 mMainThreadHandler.obtainMessage(command, arg1, 0, request).sendToTarget(); 995 return request; 996 } 997 998 /** 999 * Posts the specified command to be executed on the main thread, waits for the request to 1000 * complete, and returns the result. 1001 */ 1002 private Object sendRequest(int command) { 1003 if (Looper.myLooper() == mMainThreadHandler.getLooper()) { 1004 MainThreadRequest request = new MainThreadRequest(); 1005 mMainThreadHandler.handleMessage(mMainThreadHandler.obtainMessage(command, request)); 1006 return request.result; 1007 } else { 1008 MainThreadRequest request = sendRequestAsync(command, 0); 1009 1010 // Wait for the request to complete 1011 synchronized (request) { 1012 while (request.result == null) { 1013 try { 1014 request.wait(); 1015 } catch (InterruptedException e) { 1016 // Do nothing, go back and wait until the request is complete 1017 } 1018 } 1019 } 1020 return request.result; 1021 } 1022 } 1023} 1024