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