TelecomServiceImpl.java revision 71734c2db8a4e412d833b267777dd011e04cc942
1a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom/* 2a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * Copyright (C) 2014 The Android Open Source Project 3a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * 4a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * you may not use this file except in compliance with the License. 6a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * You may obtain a copy of the License at 7a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * 8a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * 10a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 11a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * See the License for the specific language governing permissions and 14a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom * limitations under the License. 15a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom */ 16a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 17a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrompackage com.android.server.telecom; 18a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 19a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport static android.Manifest.permission.CALL_PHONE; 20e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport static android.Manifest.permission.MODIFY_PHONE_STATE; 2170bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampeimport static android.Manifest.permission.READ_PHONE_STATE; 22e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport static android.Manifest.permission.REGISTER_CALL_PROVIDER; 23e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport static android.Manifest.permission.REGISTER_CONNECTION_MANAGER; 24a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport static android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION; 25bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillainimport static android.Manifest.permission.WRITE_SECURE_SETTINGS; 26e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers 27a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.app.AppOpsManager; 28a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.content.ComponentName; 29e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.content.Context; 302ffb703bf431d74326c88266b4ddaf225eb3c6adIgor Murashkinimport android.content.Intent; 31e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.content.pm.ApplicationInfo; 32a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.content.pm.PackageManager; 33e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.content.res.Resources; 34e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.net.Uri; 35e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.os.Binder; 363913e488afb884ccee76d620d4357b6308e55010Andreas Gampeimport android.os.Bundle; 37e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.os.IBinder; 38a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.os.UserHandle; 39e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.os.UserManager; 40f0972a410a0665dbe32bd96df09a572d69f9f3a3Dmitry Petrochenkoimport android.telecom.DefaultDialerManager; 41a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.telecom.PhoneAccount; 42a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport android.telecom.PhoneAccountHandle; 43e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.telecom.TelecomManager; 44e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.telephony.SubscriptionManager; 4536fea8dd490ab6439f391b8cd7f366c59f026fd2Andreas Gampeimport android.telephony.TelephonyManager; 46e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport android.text.TextUtils; 47957ca1cd025104fccb0b08928f955f9bdb4ab91cMathieu Chartier 48a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom// TODO: Needed for move to system service: import com.android.internal.R; 49bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampeimport com.android.internal.telecom.ITelecomService; 50a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport com.android.internal.util.IndentingPrintWriter; 51e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport com.android.server.telecom.components.UserCallIntentProcessor; 52a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 530795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartierimport java.io.FileDescriptor; 54bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampeimport java.io.PrintWriter; 55a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport java.util.ArrayList; 56a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromimport java.util.Collections; 57e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersimport java.util.List; 58a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 59bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillain/** 60bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillain * Implementation of the ITelecom interface. 61bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillain */ 62bbcc01a5a38d28c221c05788e56473a287f57589Roland Levillainpublic class TelecomServiceImpl { 63a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION = 640d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION"; 650d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain 6670bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() { 6770bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe @Override 6870bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme, 6970bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe String callingPackage) { 7070bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe synchronized (mLock) { 7170bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe if (!canReadPhoneState(callingPackage, "getDefaultOutgoingPhoneAccount")) { 7270bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe return null; 7370bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe } 7470bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe 7570bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe long token = Binder.clearCallingIdentity(); 7670bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe try { 7770bef0d8f6aa30b0da5c6ca56e1bc5729f74654bAndreas Gampe PhoneAccountHandle defaultOutgoingPhoneAccount = 78877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle mPhoneAccountRegistrar.getOutgoingPhoneAccountForScheme(uriScheme); 79877fd963548a3175665bfef25b0d24bc0e5a0135Calin Juravle // Make sure that the calling user can see this phone account. 80d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier // TODO: Does this isVisible check actually work considering we are clearing 81d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier // the calling identity? 82d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier if (defaultOutgoingPhoneAccount != null 83d0af56cdb1eaebea403e382257bdc14d7b7fdaa4Mathieu Chartier && !isVisibleToCaller(defaultOutgoingPhoneAccount)) { 84e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers Log.w(this, "No account found for the calling user"); 85a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom return null; 86a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom } 87bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe return defaultOutgoingPhoneAccount; 88a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom } catch (Exception e) { 89bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe Log.e(this, e, "getDefaultOutgoingPhoneAccount"); 90a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom throw e; 915a4b8a236030460651a3136397d23ca6744e7eb7Andreas Gampe } finally { 92a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom Binder.restoreCallingIdentity(token); 93bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe } 94a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom } 955a4b8a236030460651a3136397d23ca6744e7eb7Andreas Gampe } 96a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 97bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe @Override 98a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() { 993f41a0193eadf037b4003c1996151f386ca07b13Andreas Gampe synchronized (mLock) { 100ceb07b3285eaab350a8cd12f7d74be3e40a255ddMathieu Chartier try { 101e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers PhoneAccountHandle userSelectedOutgoingPhoneAccount = 102a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom mPhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount(); 103e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers // Make sure that the calling user can see this phone account. 104a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom if (!isVisibleToCaller(userSelectedOutgoingPhoneAccount)) { 105409e80901468f6c746eeae5c6e93ceedf1d8c711Nicolas Geoffray Log.w(this, "No account found for the calling user"); 106700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers return null; 107700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers } 108700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers return userSelectedOutgoingPhoneAccount; 1096f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers } catch (Exception e) { 1106f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers Log.e(this, e, "getUserSelectedOutgoingPhoneAccount"); 111a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom throw e; 112a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom } 113700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers } 1148a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko } 1158a630577ed2d9e9571c3434c505e5de223b23c07Vladimir Marko 116700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers @Override 117a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) { 118a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom synchronized (mLock) { 119a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom enforceModifyPermission(); 120a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 121a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 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.w(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 : profilePhoneAccounts) { 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 synchronized (mLock) { 260 try { 261 PhoneAccountHandle accountHandle = mPhoneAccountRegistrar.getSimCallManager(); 262 if (!isVisibleToCaller(accountHandle)) { 263 Log.w(this, "%s is not visible for the calling user [gsCM]", accountHandle); 264 return null; 265 } 266 return accountHandle; 267 } catch (Exception e) { 268 Log.e(this, e, "getSimCallManager"); 269 throw e; 270 } 271 } 272 } 273 274 @Override 275 public void setSimCallManager(PhoneAccountHandle accountHandle) { 276 synchronized (mLock) { 277 enforceModifyPermission(); 278 try { 279 mPhoneAccountRegistrar.setSimCallManager(accountHandle); 280 } catch (Exception e) { 281 Log.e(this, e, "setSimCallManager"); 282 throw e; 283 } 284 } 285 } 286 287 @Override 288 public List<PhoneAccountHandle> getSimCallManagers(String callingPackage) { 289 synchronized (mLock) { 290 if (!canReadPhoneState(callingPackage, "getSimCallManagers")) { 291 return Collections.emptyList(); 292 } 293 294 long token = Binder.clearCallingIdentity(); 295 try { 296 // TODO: Does this isVisible check actually work considering we are clearing 297 // the calling identity? 298 return filterForAccountsVisibleToCaller( 299 mPhoneAccountRegistrar.getConnectionManagerPhoneAccounts()); 300 } catch (Exception e) { 301 Log.e(this, e, "getSimCallManagers"); 302 throw e; 303 } finally { 304 Binder.restoreCallingIdentity(token); 305 } 306 } 307 } 308 309 @Override 310 public void registerPhoneAccount(PhoneAccount account) { 311 synchronized (mLock) { 312 try { 313 enforcePhoneAccountModificationForPackage( 314 account.getAccountHandle().getComponentName().getPackageName()); 315 if (account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)) { 316 enforceRegisterCallProviderPermission(); 317 } 318 if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) { 319 enforceRegisterSimSubscriptionPermission(); 320 } 321 if (account.hasCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)) { 322 enforceRegisterConnectionManagerPermission(); 323 } 324 if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) { 325 enforceRegisterMultiUser(); 326 } 327 enforceUserHandleMatchesCaller(account.getAccountHandle()); 328 329 mPhoneAccountRegistrar.registerPhoneAccount(account); 330 331 // Broadcast an intent indicating the phone account which was registered. 332 long token = Binder.clearCallingIdentity(); 333 try { 334 Intent intent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED); 335 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 336 account.getAccountHandle()); 337 Log.i(this, "Sending phone-account intent as user"); 338 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 339 PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION); 340 } finally { 341 Binder.restoreCallingIdentity(token); 342 } 343 } catch (Exception e) { 344 Log.e(this, e, "registerPhoneAccount %s", account); 345 throw e; 346 } 347 } 348 } 349 350 @Override 351 public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) { 352 synchronized (mLock) { 353 try { 354 enforcePhoneAccountModificationForPackage( 355 accountHandle.getComponentName().getPackageName()); 356 enforceUserHandleMatchesCaller(accountHandle); 357 mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle); 358 } catch (Exception e) { 359 Log.e(this, e, "unregisterPhoneAccount %s", accountHandle); 360 throw e; 361 } 362 } 363 } 364 365 @Override 366 public void clearAccounts(String packageName) { 367 synchronized (mLock) { 368 try { 369 enforcePhoneAccountModificationForPackage(packageName); 370 mPhoneAccountRegistrar 371 .clearAccounts(packageName, Binder.getCallingUserHandle()); 372 } catch (Exception e) { 373 Log.e(this, e, "clearAccounts %s", packageName); 374 throw e; 375 } 376 } 377 } 378 379 /** 380 * @see android.telecom.TelecomManager#isVoiceMailNumber 381 */ 382 @Override 383 public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number, 384 String callingPackage) { 385 synchronized (mLock) { 386 if (!canReadPhoneState(callingPackage, "isVoiceMailNumber")) { 387 return false; 388 } 389 390 if (!isVisibleToCaller(accountHandle)) { 391 Log.w(this, "%s is not visible for the calling user [iVMN]", accountHandle); 392 return false; 393 } 394 395 long token = Binder.clearCallingIdentity(); 396 try { 397 return mPhoneAccountRegistrar.isVoiceMailNumber(accountHandle, number); 398 } catch (Exception e) { 399 Log.e(this, e, "getSubscriptionIdForPhoneAccount"); 400 throw e; 401 } finally { 402 Binder.restoreCallingIdentity(token); 403 } 404 } 405 } 406 407 /** 408 * @see android.telecom.TelecomManager#getVoiceMailNumber 409 */ 410 @Override 411 public String getVoiceMailNumber(PhoneAccountHandle accountHandle, String callingPackage) { 412 synchronized (mLock) { 413 if (!canReadPhoneState(callingPackage, "getVoiceMailNumber")) { 414 return null; 415 } 416 417 try { 418 if (!isVisibleToCaller(accountHandle)) { 419 Log.w(this, "%s is not visible for the calling user [gVMN]", accountHandle); 420 return null; 421 } 422 423 int subId = SubscriptionManager.getDefaultVoiceSubId(); 424 if (accountHandle != null) { 425 subId = mPhoneAccountRegistrar 426 .getSubscriptionIdForPhoneAccount(accountHandle); 427 } 428 return getTelephonyManager().getVoiceMailNumber(subId); 429 } catch (Exception e) { 430 Log.e(this, e, "getSubscriptionIdForPhoneAccount"); 431 throw e; 432 } 433 } 434 } 435 436 /** 437 * @see android.telecom.TelecomManager#getLine1Number 438 */ 439 @Override 440 public String getLine1Number(PhoneAccountHandle accountHandle, String callingPackage) { 441 if (!canReadPhoneState(callingPackage, "getLine1Number")) { 442 return null; 443 } 444 445 synchronized (mLock) { 446 if (!isVisibleToCaller(accountHandle)) { 447 Log.w(this, "%s is not visible for the calling user [gL1N]", accountHandle); 448 return null; 449 } 450 451 long token = Binder.clearCallingIdentity(); 452 try { 453 int subId = 454 mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle); 455 return getTelephonyManager().getLine1NumberForSubscriber(subId); 456 } catch (Exception e) { 457 Log.e(this, e, "getSubscriptionIdForPhoneAccount"); 458 throw e; 459 } finally { 460 Binder.restoreCallingIdentity(token); 461 } 462 } 463 } 464 465 /** 466 * @see android.telecom.TelecomManager#silenceRinger 467 */ 468 @Override 469 public void silenceRinger(String callingPackage) { 470 synchronized (mLock) { 471 enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage); 472 473 long token = Binder.clearCallingIdentity(); 474 try { 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.w(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.w(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 mAppOpsManager.checkPackage( 749 Binder.getCallingUid(), 750 phoneAccountHandle.getComponentName().getPackageName()); 751 752 // Make sure it doesn't cross the UserHandle boundary 753 enforceUserHandleMatchesCaller(phoneAccountHandle); 754 long token = Binder.clearCallingIdentity(); 755 756 try { 757 Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL); 758 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 759 phoneAccountHandle); 760 intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, true); 761 if (extras != null) { 762 intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras); 763 } 764 CallIntentProcessor.processIncomingCallIntent(mCallsManager, intent); 765 } finally { 766 Binder.restoreCallingIdentity(token); 767 } 768 } else { 769 Log.w(this, 770 "Null phoneAccountHandle. Ignoring request to add new incoming call"); 771 } 772 } 773 } 774 775 /** 776 * @see android.telecom.TelecomManager#addNewUnknownCall 777 */ 778 @Override 779 public void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) { 780 synchronized (mLock) { 781 if (phoneAccountHandle != null && phoneAccountHandle.getComponentName() != null) { 782 mAppOpsManager.checkPackage( 783 Binder.getCallingUid(), 784 phoneAccountHandle.getComponentName().getPackageName()); 785 786 // Make sure it doesn't cross the UserHandle boundary 787 enforceUserHandleMatchesCaller(phoneAccountHandle); 788 long token = Binder.clearCallingIdentity(); 789 790 try { 791 Intent intent = new Intent(TelecomManager.ACTION_NEW_UNKNOWN_CALL); 792 intent.putExtras(extras); 793 intent.putExtra(CallIntentProcessor.KEY_IS_UNKNOWN_CALL, true); 794 intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, 795 phoneAccountHandle); 796 CallIntentProcessor.processUnknownCallIntent(mCallsManager, intent); 797 } finally { 798 Binder.restoreCallingIdentity(token); 799 } 800 } else { 801 Log.i(this, 802 "Null phoneAccountHandle or not initiated by Telephony. " + 803 "Ignoring request to add new unknown call."); 804 } 805 } 806 } 807 808 /** 809 * @see android.telecom.TelecomManager#placeCall 810 */ 811 @Override 812 public void placeCall(Uri handle, Bundle extras, String callingPackage) { 813 enforceCallingPackage(callingPackage); 814 if (!canCallPhone(callingPackage, "placeCall")) { 815 throw new SecurityException("Package " + callingPackage 816 + " is not allowed to place phone calls"); 817 } 818 819 synchronized (mLock) { 820 final UserHandle userHandle = Binder.getCallingUserHandle(); 821 long token = Binder.clearCallingIdentity(); 822 try { 823 final Intent intent = new Intent(Intent.ACTION_CALL, handle); 824 intent.putExtras(extras); 825 new UserCallIntentProcessor(mContext, userHandle).processIntent(intent, 826 callingPackage); 827 } finally { 828 Binder.restoreCallingIdentity(token); 829 } 830 } 831 } 832 833 /** 834 * @see android.telecom.TelecomManager#enablePhoneAccount 835 */ 836 @Override 837 public boolean enablePhoneAccount(PhoneAccountHandle accountHandle, boolean isEnabled) { 838 enforceModifyPermission(); 839 synchronized (mLock) { 840 long token = Binder.clearCallingIdentity(); 841 try { 842 // enable/disable phone account 843 return mPhoneAccountRegistrar.enablePhoneAccount(accountHandle, isEnabled); 844 } finally { 845 Binder.restoreCallingIdentity(token); 846 } 847 } 848 } 849 850 @Override 851 public boolean setDefaultDialer(String packageName) { 852 enforcePermission(MODIFY_PHONE_STATE); 853 enforcePermission(WRITE_SECURE_SETTINGS); 854 synchronized (mLock) { 855 long token = Binder.clearCallingIdentity(); 856 try { 857 return DefaultDialerManager.setDefaultDialerApplication(mContext, packageName); 858 } finally { 859 Binder.restoreCallingIdentity(token); 860 } 861 } 862 } 863 864 /** 865 * Dumps the current state of the TelecomService. Used when generating problem reports. 866 * 867 * @param fd The file descriptor. 868 * @param writer The print writer to dump the state to. 869 * @param args Optional dump arguments. 870 */ 871 @Override 872 protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) { 873 if (mContext.checkCallingOrSelfPermission( 874 android.Manifest.permission.DUMP) 875 != PackageManager.PERMISSION_GRANTED) { 876 writer.println("Permission Denial: can't dump TelecomService " + 877 "from from pid=" + Binder.getCallingPid() + ", uid=" + 878 Binder.getCallingUid()); 879 return; 880 } 881 882 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 883 if (mCallsManager != null) { 884 pw.println("CallsManager: "); 885 pw.increaseIndent(); 886 mCallsManager.dump(pw); 887 pw.decreaseIndent(); 888 889 pw.println("PhoneAccountRegistrar: "); 890 pw.increaseIndent(); 891 mPhoneAccountRegistrar.dump(pw); 892 pw.decreaseIndent(); 893 } 894 895 Log.dumpCallEvents(pw); 896 } 897 }; 898 899 private Context mContext; 900 private AppOpsManager mAppOpsManager; 901 private UserManager mUserManager; 902 private PackageManager mPackageManager; 903 private CallsManager mCallsManager; 904 private final PhoneAccountRegistrar mPhoneAccountRegistrar; 905 private final TelecomSystem.SyncRoot mLock; 906 907 public TelecomServiceImpl( 908 Context context, 909 CallsManager callsManager, 910 PhoneAccountRegistrar phoneAccountRegistrar, 911 TelecomSystem.SyncRoot lock) { 912 mContext = context; 913 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 914 915 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 916 mPackageManager = mContext.getPackageManager(); 917 918 mCallsManager = callsManager; 919 mLock = lock; 920 mPhoneAccountRegistrar = phoneAccountRegistrar; 921 } 922 923 public ITelecomService.Stub getBinder() { 924 return mBinderImpl; 925 } 926 927 // 928 // Supporting methods for the ITelecomService interface implementation. 929 // 930 931 private boolean isVisibleToCaller(PhoneAccountHandle accountHandle) { 932 if (accountHandle == null) { 933 return false; 934 } 935 return isVisibleToCaller(mPhoneAccountRegistrar.getPhoneAccount(accountHandle)); 936 } 937 938 private boolean isVisibleToCaller(PhoneAccount account) { 939 if (account == null) { 940 return false; 941 } 942 943 // If this PhoneAccount has CAPABILITY_MULTI_USER, it should be visible to all users and 944 // all profiles. Only Telephony and SIP accounts should have this capability. 945 if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) { 946 return true; 947 } 948 949 UserHandle phoneAccountUserHandle = account.getAccountHandle().getUserHandle(); 950 if (phoneAccountUserHandle == null) { 951 return false; 952 } 953 954 if (phoneAccountUserHandle.equals(Binder.getCallingUserHandle())) { 955 return true; 956 } 957 958 List<UserHandle> profileUserHandles; 959 if (UserHandle.getCallingUserId() == UserHandle.USER_OWNER) { 960 profileUserHandles = mUserManager.getUserProfiles(); 961 } else { 962 // Otherwise, it has to be owned by the current caller's profile. 963 profileUserHandles = new ArrayList<>(1); 964 profileUserHandles.add(Binder.getCallingUserHandle()); 965 } 966 967 return profileUserHandles.contains(phoneAccountUserHandle); 968 } 969 970 /** 971 * Given a list of {@link PhoneAccountHandle}s, filter them to the ones that the calling 972 * user can see. 973 * 974 * @param phoneAccountHandles Unfiltered list of account handles. 975 * 976 * @return {@link PhoneAccountHandle}s visible to the calling user and its profiles. 977 */ 978 private List<PhoneAccountHandle> filterForAccountsVisibleToCaller( 979 List<PhoneAccountHandle> phoneAccountHandles) { 980 List<PhoneAccountHandle> profilePhoneAccountHandles = 981 new ArrayList<>(phoneAccountHandles.size()); 982 for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandles) { 983 if (isVisibleToCaller(phoneAccountHandle)) { 984 profilePhoneAccountHandles.add(phoneAccountHandle); 985 } 986 } 987 return profilePhoneAccountHandles; 988 } 989 990 private boolean isCallerSystemApp() { 991 int uid = Binder.getCallingUid(); 992 String[] packages = mPackageManager.getPackagesForUid(uid); 993 for (String packageName : packages) { 994 if (isPackageSystemApp(packageName)) { 995 return true; 996 } 997 } 998 return false; 999 } 1000 1001 private boolean isPackageSystemApp(String packageName) { 1002 try { 1003 ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(packageName, 1004 PackageManager.GET_META_DATA); 1005 if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 1006 return true; 1007 } 1008 } catch (PackageManager.NameNotFoundException e) { 1009 } 1010 return false; 1011 } 1012 1013 private void acceptRingingCallInternal() { 1014 Call call = mCallsManager.getFirstCallWithState(CallState.RINGING); 1015 if (call != null) { 1016 call.answer(call.getVideoState()); 1017 } 1018 } 1019 1020 private boolean endCallInternal() { 1021 // Always operate on the foreground call if one exists, otherwise get the first call in 1022 // priority order by call-state. 1023 Call call = mCallsManager.getForegroundCall(); 1024 if (call == null) { 1025 call = mCallsManager.getFirstCallWithState( 1026 CallState.ACTIVE, 1027 CallState.DIALING, 1028 CallState.RINGING, 1029 CallState.ON_HOLD); 1030 } 1031 1032 if (call != null) { 1033 if (call.getState() == CallState.RINGING) { 1034 call.reject(false /* rejectWithMessage */, null); 1035 } else { 1036 call.disconnect(); 1037 } 1038 return true; 1039 } 1040 1041 return false; 1042 } 1043 1044 private void enforcePhoneAccountModificationForPackage(String packageName) { 1045 // TODO: Use a new telecomm permission for this instead of reusing modify. 1046 1047 int result = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE); 1048 1049 // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement 1050 // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They 1051 // may also modify PhoneAccounts on behalf of any 'packageName'. 1052 1053 if (result != PackageManager.PERMISSION_GRANTED) { 1054 // Other callers are only allowed to modify PhoneAccounts if the relevant system 1055 // feature is enabled ... 1056 enforceConnectionServiceFeature(); 1057 // ... and the PhoneAccounts they refer to are for their own package. 1058 enforceCallingPackage(packageName); 1059 } 1060 } 1061 1062 private void enforcePermissionOrPrivilegedDialer(String permission, String packageName) { 1063 if (!isPrivilegedDialerCalling(packageName)) { 1064 try { 1065 enforcePermission(permission); 1066 } catch (SecurityException e) { 1067 Log.e(this, e, "Caller must be the default or system dialer, or have the permission" 1068 + " %s to perform this operation.", permission); 1069 throw e; 1070 } 1071 } 1072 } 1073 1074 private void enforceCallingPackage(String packageName) { 1075 mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName); 1076 } 1077 1078 private void enforceConnectionServiceFeature() { 1079 enforceFeature(PackageManager.FEATURE_CONNECTION_SERVICE); 1080 } 1081 1082 private void enforceRegisterCallProviderPermission() { 1083 enforcePermission(REGISTER_CALL_PROVIDER); 1084 } 1085 1086 private void enforceRegisterSimSubscriptionPermission() { 1087 enforcePermission(REGISTER_SIM_SUBSCRIPTION); 1088 } 1089 1090 private void enforceRegisterConnectionManagerPermission() { 1091 enforcePermission(REGISTER_CONNECTION_MANAGER); 1092 } 1093 1094 private void enforceModifyPermission() { 1095 enforcePermission(MODIFY_PHONE_STATE); 1096 } 1097 1098 private void enforcePermission(String permission) { 1099 mContext.enforceCallingOrSelfPermission(permission, null); 1100 } 1101 1102 private void enforceRegisterMultiUser() { 1103 if (!isCallerSystemApp()) { 1104 throw new SecurityException("CAPABILITY_MULTI_USER is only available to system apps."); 1105 } 1106 } 1107 1108 private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) { 1109 if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) { 1110 throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's"); 1111 } 1112 } 1113 1114 private void enforceFeature(String feature) { 1115 PackageManager pm = mContext.getPackageManager(); 1116 if (!pm.hasSystemFeature(feature)) { 1117 throw new UnsupportedOperationException( 1118 "System does not support feature " + feature); 1119 } 1120 } 1121 1122 private boolean canReadPhoneState(String callingPackage, String message) { 1123 // The system/default dialer can always read phone state - so that emergency calls will 1124 // still work. 1125 if (isPrivilegedDialerCalling(callingPackage)) { 1126 return true; 1127 } 1128 1129 // Accessing phone state is gated by a special permission. 1130 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, message); 1131 1132 // Some apps that have the permission can be restricted via app ops. 1133 return mAppOpsManager.noteOp(AppOpsManager.OP_READ_PHONE_STATE, 1134 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED; 1135 } 1136 1137 private boolean canCallPhone(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 // Accessing phone state is gated by a special permission. 1145 mContext.enforceCallingOrSelfPermission(CALL_PHONE, message); 1146 1147 // Some apps that have the permission can be restricted via app ops. 1148 return mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE, 1149 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED; 1150 } 1151 1152 private boolean isCallerSimCallManager() { 1153 PhoneAccountHandle accountHandle = TelecomSystem.getInstance().getPhoneAccountRegistrar() 1154 .getSimCallManager(); 1155 if (accountHandle != null) { 1156 try { 1157 mAppOpsManager.checkPackage( 1158 Binder.getCallingUid(), accountHandle.getComponentName().getPackageName()); 1159 return true; 1160 } catch (SecurityException e) { 1161 } 1162 } 1163 return false; 1164 } 1165 1166 private boolean isPrivilegedDialerCalling(String callingPackage) { 1167 mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage); 1168 return DefaultDialerManager.isDefaultOrSystemDialer(mContext, callingPackage); 1169 } 1170 1171 private TelephonyManager getTelephonyManager() { 1172 return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE); 1173 } 1174} 1175