1 /* 2 * Copyright (C) 2007 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; 18 19 import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX; 20 import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED; 21 import static android.telephony.TelephonyRegistryManager.SIM_ACTIVATION_TYPE_DATA; 22 import static android.telephony.TelephonyRegistryManager.SIM_ACTIVATION_TYPE_VOICE; 23 24 import static java.util.Arrays.copyOf; 25 26 import android.Manifest; 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.app.ActivityManager; 30 import android.app.AppOpsManager; 31 import android.app.BroadcastOptions; 32 import android.app.compat.CompatChanges; 33 import android.compat.annotation.ChangeId; 34 import android.compat.annotation.EnabledSince; 35 import android.content.BroadcastReceiver; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.IntentFilter; 39 import android.content.pm.PackageManager; 40 import android.os.Binder; 41 import android.os.Build; 42 import android.os.Bundle; 43 import android.os.Handler; 44 import android.os.IBinder; 45 import android.os.Message; 46 import android.os.Process; 47 import android.os.RemoteException; 48 import android.os.UserHandle; 49 import android.provider.DeviceConfig; 50 import android.telecom.TelecomManager; 51 import android.telephony.AccessNetworkConstants; 52 import android.telephony.Annotation; 53 import android.telephony.Annotation.RadioPowerState; 54 import android.telephony.Annotation.SrvccState; 55 import android.telephony.BarringInfo; 56 import android.telephony.CallQuality; 57 import android.telephony.CallState; 58 import android.telephony.CellIdentity; 59 import android.telephony.CellInfo; 60 import android.telephony.CellSignalStrength; 61 import android.telephony.CellSignalStrengthCdma; 62 import android.telephony.CellSignalStrengthGsm; 63 import android.telephony.CellSignalStrengthLte; 64 import android.telephony.CellSignalStrengthNr; 65 import android.telephony.CellSignalStrengthTdscdma; 66 import android.telephony.CellSignalStrengthWcdma; 67 import android.telephony.DisconnectCause; 68 import android.telephony.LinkCapacityEstimate; 69 import android.telephony.LocationAccessPolicy; 70 import android.telephony.PhoneCapability; 71 import android.telephony.PhoneStateListener; 72 import android.telephony.PhysicalChannelConfig; 73 import android.telephony.PreciseCallState; 74 import android.telephony.PreciseDataConnectionState; 75 import android.telephony.PreciseDisconnectCause; 76 import android.telephony.Rlog; 77 import android.telephony.ServiceState; 78 import android.telephony.SignalStrength; 79 import android.telephony.SubscriptionInfo; 80 import android.telephony.SubscriptionManager; 81 import android.telephony.TelephonyCallback; 82 import android.telephony.TelephonyDisplayInfo; 83 import android.telephony.TelephonyManager; 84 import android.telephony.data.ApnSetting; 85 import android.telephony.emergency.EmergencyNumber; 86 import android.telephony.ims.ImsCallSession; 87 import android.telephony.ims.ImsReasonInfo; 88 import android.telephony.ims.MediaQualityStatus; 89 import android.text.TextUtils; 90 import android.util.ArrayMap; 91 import android.util.ArraySet; 92 import android.util.LocalLog; 93 import android.util.Pair; 94 import android.util.SparseArray; 95 96 import com.android.internal.annotations.VisibleForTesting; 97 import com.android.internal.app.IBatteryStats; 98 import com.android.internal.telephony.ICarrierConfigChangeListener; 99 import com.android.internal.telephony.ICarrierPrivilegesCallback; 100 import com.android.internal.telephony.IOnSubscriptionsChangedListener; 101 import com.android.internal.telephony.IPhoneStateListener; 102 import com.android.internal.telephony.ITelephonyRegistry; 103 import com.android.internal.telephony.TelephonyPermissions; 104 import com.android.internal.telephony.util.TelephonyUtils; 105 import com.android.internal.util.ArrayUtils; 106 import com.android.internal.util.DumpUtils; 107 import com.android.internal.util.FrameworkStatsLog; 108 import com.android.internal.util.IndentingPrintWriter; 109 import com.android.server.am.BatteryStatsService; 110 111 import dalvik.annotation.optimization.NeverCompile; 112 113 import java.io.FileDescriptor; 114 import java.io.PrintWriter; 115 import java.util.ArrayList; 116 import java.util.Arrays; 117 import java.util.Collections; 118 import java.util.HashMap; 119 import java.util.HashSet; 120 import java.util.List; 121 import java.util.Map; 122 import java.util.NoSuchElementException; 123 import java.util.Objects; 124 import java.util.Set; 125 import java.util.stream.Collectors; 126 127 /** 128 * Since phone process can be restarted, this class provides a centralized place 129 * that applications can register and be called back from. 130 * 131 * Change-Id: I450c968bda93767554b5188ee63e10c9f43c5aa4 fixes bugs 16148026 132 * and 15973975 by saving the phoneId of the registrant and then using the 133 * phoneId when deciding to to make a callback. This is necessary because 134 * a subId changes from to a placeholder value when a SIM is removed and thus won't 135 * compare properly. Because getPhoneIdFromSubId(int subId) handles 136 * the placeholder value conversion we properly do the callbacks. 137 * 138 * Eventually we may want to remove the notion of placeholder value but for now this 139 * looks like the best approach. 140 */ 141 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 142 public class TelephonyRegistry extends ITelephonyRegistry.Stub { 143 private static final String TAG = "TelephonyRegistry"; 144 private static final boolean DBG = false; // STOPSHIP if true 145 private static final boolean DBG_LOC = false; // STOPSHIP if true 146 private static final boolean VDBG = false; // STOPSHIP if true 147 148 private static class Record { 149 Context context; 150 151 String callingPackage; 152 String callingFeatureId; 153 154 IBinder binder; 155 156 TelephonyRegistryDeathRecipient deathRecipient; 157 158 IPhoneStateListener callback; 159 IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback; 160 IOnSubscriptionsChangedListener onOpportunisticSubscriptionsChangedListenerCallback; 161 ICarrierPrivilegesCallback carrierPrivilegesCallback; 162 ICarrierConfigChangeListener carrierConfigChangeListener; 163 164 int callerUid; 165 int callerPid; 166 boolean renounceFineLocationAccess; 167 boolean renounceCoarseLocationAccess; 168 169 Set<Integer> eventList; 170 171 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 172 173 int phoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; 174 matchTelephonyCallbackEvent(int event)175 boolean matchTelephonyCallbackEvent(int event) { 176 return (callback != null) && (this.eventList.contains(event)); 177 } 178 matchOnSubscriptionsChangedListener()179 boolean matchOnSubscriptionsChangedListener() { 180 return (onSubscriptionsChangedListenerCallback != null); 181 } 182 matchOnOpportunisticSubscriptionsChangedListener()183 boolean matchOnOpportunisticSubscriptionsChangedListener() { 184 return (onOpportunisticSubscriptionsChangedListenerCallback != null); 185 } 186 matchCarrierPrivilegesCallback()187 boolean matchCarrierPrivilegesCallback() { 188 return carrierPrivilegesCallback != null; 189 } 190 matchCarrierConfigChangeListener()191 boolean matchCarrierConfigChangeListener() { 192 return carrierConfigChangeListener != null; 193 } 194 canReadCallLog()195 boolean canReadCallLog() { 196 try { 197 return TelephonyPermissions.checkReadCallLog( 198 context, subId, callerPid, callerUid, callingPackage, callingFeatureId); 199 } catch (SecurityException e) { 200 return false; 201 } 202 } 203 204 @Override toString()205 public String toString() { 206 return "{callingPackage=" + pii(callingPackage) + " callerUid=" + callerUid + " binder=" 207 + binder + " callback=" + callback 208 + " onSubscriptionsChangedListenererCallback=" 209 + onSubscriptionsChangedListenerCallback 210 + " onOpportunisticSubscriptionsChangedListenererCallback=" 211 + onOpportunisticSubscriptionsChangedListenerCallback 212 + " carrierPrivilegesCallback=" + carrierPrivilegesCallback 213 + " carrierConfigChangeListener=" + carrierConfigChangeListener 214 + " subId=" + subId + " phoneId=" + phoneId + " events=" + eventList + "}"; 215 } 216 } 217 218 /** 219 * Wrapper class to facilitate testing -- encapsulates bits of configuration that are 220 * normally fetched from static methods with many dependencies. 221 */ 222 public static class ConfigurationProvider { 223 /** 224 * @return The per-pid registration limit for PhoneStateListeners, as set from DeviceConfig 225 * @noinspection ConstantConditions 226 */ getRegistrationLimit()227 public int getRegistrationLimit() { 228 return Binder.withCleanCallingIdentity(() -> 229 DeviceConfig.getInt(DeviceConfig.NAMESPACE_TELEPHONY, 230 TelephonyCallback.FLAG_PER_PID_REGISTRATION_LIMIT, 231 TelephonyCallback.DEFAULT_PER_PID_REGISTRATION_LIMIT)); 232 } 233 234 /** 235 * @param uid uid to check 236 * @return Whether enforcement of the per-pid registation limit for PhoneStateListeners is 237 * enabled in PlatformCompat for the given uid. 238 * @noinspection ConstantConditions 239 */ isRegistrationLimitEnabledInPlatformCompat(int uid)240 public boolean isRegistrationLimitEnabledInPlatformCompat(int uid) { 241 return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled( 242 TelephonyCallback.PHONE_STATE_LISTENER_LIMIT_CHANGE_ID, uid)); 243 } 244 245 /** 246 * See {@link TelecomManager#ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION} for more 247 * information. 248 * @noinspection ConstantConditions 249 */ isCallStateReadPhoneStateEnforcedInPlatformCompat(String packageName, UserHandle userHandle)250 public boolean isCallStateReadPhoneStateEnforcedInPlatformCompat(String packageName, 251 UserHandle userHandle) { 252 return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled( 253 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION, packageName, 254 userHandle)); 255 } 256 257 /** 258 * To check the SDK version for 259 * {@link android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener} should add 260 * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12. 261 * @noinspection ConstantConditions 262 */ isActiveDataSubIdReadPhoneStateEnforcedInPlatformCompat(String packageName, UserHandle userHandle)263 public boolean isActiveDataSubIdReadPhoneStateEnforcedInPlatformCompat(String packageName, 264 UserHandle userHandle) { 265 return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled( 266 REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_ACTIVE_DATA_SUB_ID, packageName, 267 userHandle)); 268 } 269 270 /** 271 * To check the SDK version for 272 * {@link android.telephony.TelephonyCallback.CellInfoListener} should add 273 * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12. 274 * @noinspection ConstantConditions 275 */ isCellInfoReadPhoneStateEnforcedInPlatformCompat(String packageName, UserHandle userHandle)276 public boolean isCellInfoReadPhoneStateEnforcedInPlatformCompat(String packageName, 277 UserHandle userHandle) { 278 return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled( 279 REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_CELL_INFO, packageName, userHandle)); 280 } 281 282 /** 283 * To check the SDK version for 284 * {@link android.telephony.TelephonyCallback.DisplayInfoListener} should remove 285 * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12. 286 * @noinspection ConstantConditions 287 */ isDisplayInfoReadPhoneStateEnforcedInPlatformCompat(String packageName, UserHandle userHandle)288 public boolean isDisplayInfoReadPhoneStateEnforcedInPlatformCompat(String packageName, 289 UserHandle userHandle) { 290 return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled( 291 REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_DISPLAY_INFO, packageName, userHandle)); 292 } 293 294 /** 295 * Support backward compatibility for {@link android.telephony.TelephonyDisplayInfo}. 296 * 297 * @noinspection ConstantConditions 298 */ isDisplayInfoNrAdvancedSupported(String packageName, UserHandle userHandle)299 public boolean isDisplayInfoNrAdvancedSupported(String packageName, 300 UserHandle userHandle) { 301 return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled( 302 DISPLAY_INFO_NR_ADVANCED_SUPPORTED, packageName, userHandle)); 303 } 304 } 305 306 private final Context mContext; 307 308 private ConfigurationProvider mConfigurationProvider; 309 310 // access should be inside synchronized (mRecords) for these two fields 311 private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>(); 312 private final ArrayList<Record> mRecords = new ArrayList<Record>(); 313 314 private final IBatteryStats mBatteryStats; 315 316 private final AppOpsManager mAppOps; 317 318 private boolean mHasNotifySubscriptionInfoChangedOccurred = false; 319 320 private boolean mHasNotifyOpportunisticSubscriptionInfoChangedOccurred = false; 321 322 private int mNumPhones; 323 324 private int[] mCallState; 325 326 private String[] mCallIncomingNumber; 327 328 private ServiceState[] mServiceState; 329 330 private int[] mVoiceActivationState; 331 332 private int[] mDataActivationState; 333 334 private boolean[] mUserMobileDataState; 335 336 private TelephonyDisplayInfo[] mTelephonyDisplayInfos; 337 338 private SignalStrength[] mSignalStrength; 339 340 private boolean[] mMessageWaiting; 341 342 private boolean[] mCallForwarding; 343 344 private int[] mDataActivity; 345 346 // Connection state of default APN type data (i.e. internet) of phones 347 private int[] mDataConnectionState; 348 349 private CellIdentity[] mCellIdentity; 350 351 private int[] mDataConnectionNetworkType; 352 353 private ArrayList<List<CellInfo>> mCellInfo; 354 355 private Map<Integer, List<EmergencyNumber>> mEmergencyNumberList; 356 357 private EmergencyNumber[] mOutgoingSmsEmergencyNumber; 358 359 private EmergencyNumber[] mOutgoingCallEmergencyNumber; 360 361 private CallQuality[] mCallQuality; 362 363 private List<SparseArray<MediaQualityStatus>> mMediaQualityStatus; 364 365 private ArrayList<List<CallState>> mCallStateLists; 366 367 // network type of the call associated with the mCallStateLists and mCallQuality 368 private int[] mCallNetworkType; 369 370 private int[] mSrvccState; 371 372 private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 373 374 private int mDefaultPhoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; 375 376 private int[] mRingingCallState; 377 378 private int[] mForegroundCallState; 379 380 private int[] mBackgroundCallState; 381 382 private PreciseCallState[] mPreciseCallState; 383 384 private int[] mCallDisconnectCause; 385 386 private List<ImsReasonInfo> mImsReasonInfo = null; 387 388 private int[] mCallPreciseDisconnectCause; 389 390 private List<BarringInfo> mBarringInfo = null; 391 392 private boolean[] mCarrierNetworkChangeState = null; 393 394 private PhoneCapability mPhoneCapability = null; 395 396 private int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 397 398 @RadioPowerState 399 private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE; 400 401 private final LocalLog mLocalLog = new LocalLog(200); 402 403 private final LocalLog mListenLog = new LocalLog(200); 404 405 private List<List<PhysicalChannelConfig>> mPhysicalChannelConfigs; 406 407 private boolean[] mIsDataEnabled; 408 409 private int[] mDataEnabledReason; 410 411 private int[] mAllowedNetworkTypeReason; 412 private long[] mAllowedNetworkTypeValue; 413 414 private static final List<LinkCapacityEstimate> INVALID_LCE_LIST = 415 new ArrayList<LinkCapacityEstimate>(Arrays.asList(new LinkCapacityEstimate( 416 LinkCapacityEstimate.LCE_TYPE_COMBINED, 417 LinkCapacityEstimate.INVALID, LinkCapacityEstimate.INVALID))); 418 private List<List<LinkCapacityEstimate>> mLinkCapacityEstimateLists; 419 420 private int[] mECBMReason; 421 private boolean[] mECBMStarted; 422 private int[] mSCBMReason; 423 private boolean[] mSCBMStarted; 424 425 /** 426 * Per-phone map of precise data connection state. The key of the map is the pair of transport 427 * type and APN setting. This is the cache to prevent redundant callbacks to the listeners. 428 * A precise data connection with state {@link TelephonyManager#DATA_DISCONNECTED} removes 429 * its entry from the map. 430 */ 431 private List<Map<Pair<Integer, ApnSetting>, PreciseDataConnectionState>> 432 mPreciseDataConnectionStates; 433 434 /** Per-phoneId snapshot of privileged packages (names + UIDs). */ 435 @NonNull private List<Pair<List<String>, int[]>> mCarrierPrivilegeStates; 436 /** Per-phoneId of CarrierService (PackageName, UID) pair. */ 437 @NonNull private List<Pair<String, Integer>> mCarrierServiceStates; 438 439 /** 440 * Support backward compatibility for {@link android.telephony.TelephonyDisplayInfo}. 441 */ 442 @ChangeId 443 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) 444 private static final long DISPLAY_INFO_NR_ADVANCED_SUPPORTED = 181658987L; 445 446 /** 447 * To check the SDK version for 448 * {@link android.telephony.TelephonyCallback.DisplayInfoListener} should remove 449 * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12. 450 */ 451 @ChangeId 452 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) 453 private static final long REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_DISPLAY_INFO = 183164979L; 454 455 /** 456 * To check the SDK version for 457 * {@link android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener} should add 458 * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12. 459 */ 460 @ChangeId 461 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) 462 private static final long REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_ACTIVE_DATA_SUB_ID 463 = 182478738L; 464 465 /** 466 * To check the SDK version for {@link android.telephony.TelephonyCallback.CellInfoListener} 467 * should add {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12. 468 */ 469 @ChangeId 470 @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) 471 private static final long REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_CELL_INFO = 184323934L; 472 473 private static final Set<Integer> REQUIRE_PRECISE_PHONE_STATE_PERMISSION; 474 static { 475 REQUIRE_PRECISE_PHONE_STATE_PERMISSION = new HashSet<Integer>(); 476 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 477 TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); 478 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 479 TelephonyCallback.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED); 480 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 481 TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED); 482 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 483 TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); 484 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 485 TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED); 486 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 487 TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); 488 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE); 489 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED); 490 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 491 TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED); 492 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 493 TelephonyCallback.EVENT_DATA_ENABLED_CHANGED); 494 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 495 TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED); 496 REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( 497 TelephonyCallback.EVENT_MEDIA_QUALITY_STATUS_CHANGED); 498 } 499 isLocationPermissionRequired(Set<Integer> events)500 private boolean isLocationPermissionRequired(Set<Integer> events) { 501 return events.contains(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED) 502 || events.contains(TelephonyCallback.EVENT_CELL_INFO_CHANGED); 503 } 504 isPhoneStatePermissionRequired(Set<Integer> events, String callingPackage, UserHandle userHandle)505 private boolean isPhoneStatePermissionRequired(Set<Integer> events, String callingPackage, 506 UserHandle userHandle) { 507 if (events.contains(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED) 508 || events.contains(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED) 509 || events.contains(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)) { 510 return true; 511 } 512 513 // Only check READ_PHONE_STATE for CALL_STATE_CHANGED for Android 12 or above. 514 if ((events.contains(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED) 515 || events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED)) 516 && mConfigurationProvider.isCallStateReadPhoneStateEnforcedInPlatformCompat( 517 callingPackage, userHandle)) { 518 return true; 519 } 520 521 // Only check READ_PHONE_STATE for ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED for Android 12 522 // or above. 523 if (events.contains(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED) 524 && mConfigurationProvider.isActiveDataSubIdReadPhoneStateEnforcedInPlatformCompat( 525 callingPackage, userHandle)) { 526 return true; 527 } 528 529 // Only check READ_PHONE_STATE for CELL_INFO_CHANGED for Android 12 or above. 530 if (events.contains(TelephonyCallback.EVENT_CELL_INFO_CHANGED) 531 && mConfigurationProvider.isCellInfoReadPhoneStateEnforcedInPlatformCompat( 532 callingPackage, userHandle)) { 533 return true; 534 } 535 536 // Only check READ_PHONE_STATE for DISPLAY_INFO_CHANGED for Android 11 or older. 537 // READ_PHONE_STATE is not required anymore after Android 12. 538 if (events.contains(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED) 539 && !mConfigurationProvider.isDisplayInfoReadPhoneStateEnforcedInPlatformCompat( 540 callingPackage, userHandle)) { 541 return true; 542 } 543 544 return false; 545 } 546 isPrecisePhoneStatePermissionRequired(Set<Integer> events)547 private boolean isPrecisePhoneStatePermissionRequired(Set<Integer> events) { 548 for (Integer requireEvent : REQUIRE_PRECISE_PHONE_STATE_PERMISSION) { 549 if (events.contains(requireEvent)) { 550 return true; 551 } 552 } 553 return false; 554 } 555 isActiveEmergencySessionPermissionRequired(Set<Integer> events)556 private boolean isActiveEmergencySessionPermissionRequired(Set<Integer> events) { 557 return events.contains(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL) 558 || events.contains(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS); 559 } 560 isPrivilegedPhoneStatePermissionRequired(Set<Integer> events)561 private boolean isPrivilegedPhoneStatePermissionRequired(Set<Integer> events) { 562 return events.contains(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED) 563 || events.contains(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED) 564 || events.contains(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED) 565 || events.contains(TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED) 566 || events.contains(TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED); 567 } 568 569 private static final int MSG_USER_SWITCHED = 1; 570 private static final int MSG_UPDATE_DEFAULT_SUB = 2; 571 572 private final Handler mHandler = new Handler() { 573 @Override 574 public void handleMessage(Message msg) { 575 switch (msg.what) { 576 case MSG_USER_SWITCHED: { 577 if (VDBG) log("MSG_USER_SWITCHED userId=" + msg.arg1); 578 int numPhones = getTelephonyManager().getActiveModemCount(); 579 for (int phoneId = 0; phoneId < numPhones; phoneId++) { 580 int subId = SubscriptionManager.getSubscriptionId(phoneId); 581 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 582 subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; 583 } 584 TelephonyRegistry.this.notifyCellLocationForSubscriber( 585 subId, mCellIdentity[phoneId], true /* hasUserSwitched */); 586 } 587 break; 588 } 589 case MSG_UPDATE_DEFAULT_SUB: { 590 int newDefaultPhoneId = msg.arg1; 591 int newDefaultSubId = msg.arg2; 592 if (VDBG) { 593 log("MSG_UPDATE_DEFAULT_SUB:current mDefaultSubId=" + mDefaultSubId 594 + " current mDefaultPhoneId=" + mDefaultPhoneId 595 + " newDefaultSubId=" + newDefaultSubId 596 + " newDefaultPhoneId=" + newDefaultPhoneId); 597 } 598 599 //Due to possible race condition,(notify call back using the new 600 //defaultSubId comes before new defaultSubId update) we need to recall all 601 //possible missed notify callback 602 synchronized (mRecords) { 603 for (Record r : mRecords) { 604 if(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 605 checkPossibleMissNotify(r, newDefaultPhoneId); 606 } 607 } 608 handleRemoveListLocked(); 609 } 610 mDefaultSubId = newDefaultSubId; 611 mDefaultPhoneId = newDefaultPhoneId; 612 mLocalLog.log("Default subscription updated: mDefaultPhoneId=" 613 + mDefaultPhoneId + ", mDefaultSubId=" + mDefaultSubId); 614 } 615 } 616 } 617 }; 618 619 private class TelephonyRegistryDeathRecipient implements IBinder.DeathRecipient { 620 621 private final IBinder binder; 622 TelephonyRegistryDeathRecipient(IBinder binder)623 TelephonyRegistryDeathRecipient(IBinder binder) { 624 this.binder = binder; 625 } 626 627 @Override binderDied()628 public void binderDied() { 629 if (DBG) log("binderDied " + binder); 630 remove(binder); 631 } 632 } 633 634 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 635 @Override 636 public void onReceive(Context context, Intent intent) { 637 String action = intent.getAction(); 638 if (VDBG) log("mBroadcastReceiver: action=" + action); 639 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 640 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 641 if (DBG) log("onReceive: userHandle=" + userHandle); 642 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED, userHandle, 0)); 643 } else if (action.equals(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) { 644 int newDefaultSubId = intent.getIntExtra( 645 SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 646 SubscriptionManager.getDefaultSubscriptionId()); 647 int newDefaultPhoneId = intent.getIntExtra( 648 SubscriptionManager.EXTRA_SLOT_INDEX, 649 getPhoneIdFromSubId(newDefaultSubId)); 650 if (DBG) { 651 log("onReceive:current mDefaultSubId=" + mDefaultSubId 652 + " current mDefaultPhoneId=" + mDefaultPhoneId 653 + " newDefaultSubId=" + newDefaultSubId 654 + " newDefaultPhoneId=" + newDefaultPhoneId); 655 } 656 657 if (validatePhoneId(newDefaultPhoneId) 658 && (newDefaultSubId != mDefaultSubId 659 || newDefaultPhoneId != mDefaultPhoneId)) { 660 mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_DEFAULT_SUB, 661 newDefaultPhoneId, newDefaultSubId)); 662 } 663 } else if (action.equals(ACTION_MULTI_SIM_CONFIG_CHANGED)) { 664 onMultiSimConfigChanged(); 665 } 666 } 667 }; 668 getTelephonyManager()669 private TelephonyManager getTelephonyManager() { 670 return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 671 } 672 onMultiSimConfigChanged()673 private void onMultiSimConfigChanged() { 674 synchronized (mRecords) { 675 int oldNumPhones = mNumPhones; 676 mNumPhones = getTelephonyManager().getActiveModemCount(); 677 if (oldNumPhones == mNumPhones) return; 678 679 if (DBG) { 680 log("TelephonyRegistry: activeModemCount changed from " + oldNumPhones 681 + " to " + mNumPhones); 682 } 683 mCallState = copyOf(mCallState, mNumPhones); 684 mDataActivity = copyOf(mCallState, mNumPhones); 685 mDataConnectionState = copyOf(mCallState, mNumPhones); 686 mDataConnectionNetworkType = copyOf(mCallState, mNumPhones); 687 mCallIncomingNumber = copyOf(mCallIncomingNumber, mNumPhones); 688 mServiceState = copyOf(mServiceState, mNumPhones); 689 mVoiceActivationState = copyOf(mVoiceActivationState, mNumPhones); 690 mDataActivationState = copyOf(mDataActivationState, mNumPhones); 691 mUserMobileDataState = copyOf(mUserMobileDataState, mNumPhones); 692 if (mSignalStrength != null) { 693 mSignalStrength = copyOf(mSignalStrength, mNumPhones); 694 } else { 695 mSignalStrength = new SignalStrength[mNumPhones]; 696 } 697 mMessageWaiting = copyOf(mMessageWaiting, mNumPhones); 698 mCallForwarding = copyOf(mCallForwarding, mNumPhones); 699 mCellIdentity = copyOf(mCellIdentity, mNumPhones); 700 mSrvccState = copyOf(mSrvccState, mNumPhones); 701 mPreciseCallState = copyOf(mPreciseCallState, mNumPhones); 702 mForegroundCallState = copyOf(mForegroundCallState, mNumPhones); 703 mBackgroundCallState = copyOf(mBackgroundCallState, mNumPhones); 704 mRingingCallState = copyOf(mRingingCallState, mNumPhones); 705 mCallDisconnectCause = copyOf(mCallDisconnectCause, mNumPhones); 706 mCallPreciseDisconnectCause = copyOf(mCallPreciseDisconnectCause, mNumPhones); 707 mCallQuality = copyOf(mCallQuality, mNumPhones); 708 mCallNetworkType = copyOf(mCallNetworkType, mNumPhones); 709 mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones); 710 mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones); 711 mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones); 712 mCarrierNetworkChangeState = copyOf(mCarrierNetworkChangeState, mNumPhones); 713 mIsDataEnabled = copyOf(mIsDataEnabled, mNumPhones); 714 mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones); 715 mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones); 716 mAllowedNetworkTypeValue = copyOf(mAllowedNetworkTypeValue, mNumPhones); 717 mECBMReason = copyOf(mECBMReason, mNumPhones); 718 mECBMStarted = copyOf(mECBMStarted, mNumPhones); 719 mSCBMReason = copyOf(mSCBMReason, mNumPhones); 720 mSCBMStarted = copyOf(mSCBMStarted, mNumPhones); 721 // ds -> ss switch. 722 if (mNumPhones < oldNumPhones) { 723 cutListToSize(mCellInfo, mNumPhones); 724 cutListToSize(mImsReasonInfo, mNumPhones); 725 cutListToSize(mPreciseDataConnectionStates, mNumPhones); 726 cutListToSize(mBarringInfo, mNumPhones); 727 cutListToSize(mPhysicalChannelConfigs, mNumPhones); 728 cutListToSize(mLinkCapacityEstimateLists, mNumPhones); 729 cutListToSize(mCarrierPrivilegeStates, mNumPhones); 730 cutListToSize(mCarrierServiceStates, mNumPhones); 731 cutListToSize(mCallStateLists, mNumPhones); 732 cutListToSize(mMediaQualityStatus, mNumPhones); 733 return; 734 } 735 736 // mNumPhones > oldNumPhones: ss -> ds switch 737 for (int i = oldNumPhones; i < mNumPhones; i++) { 738 mCallState[i] = TelephonyManager.CALL_STATE_IDLE; 739 mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; 740 mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN; 741 mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 742 mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 743 mCallIncomingNumber[i] = ""; 744 mServiceState[i] = new ServiceState(); 745 mSignalStrength[i] = null; 746 mUserMobileDataState[i] = false; 747 mMessageWaiting[i] = false; 748 mCallForwarding[i] = false; 749 mCellIdentity[i] = null; 750 mCellInfo.add(i, Collections.EMPTY_LIST); 751 mImsReasonInfo.add(i, null); 752 mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE; 753 mCallDisconnectCause[i] = DisconnectCause.NOT_VALID; 754 mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID; 755 mCallQuality[i] = createCallQuality(); 756 mMediaQualityStatus.add(i, new SparseArray<>()); 757 mCallStateLists.add(i, new ArrayList<>()); 758 mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN; 759 mPreciseCallState[i] = createPreciseCallState(); 760 mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; 761 mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; 762 mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; 763 mPreciseDataConnectionStates.add(new ArrayMap<>()); 764 mBarringInfo.add(i, new BarringInfo()); 765 mCarrierNetworkChangeState[i] = false; 766 mTelephonyDisplayInfos[i] = null; 767 mIsDataEnabled[i] = false; 768 mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER; 769 mPhysicalChannelConfigs.add(i, new ArrayList<>()); 770 mAllowedNetworkTypeReason[i] = -1; 771 mAllowedNetworkTypeValue[i] = -1; 772 mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST); 773 mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0])); 774 mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID)); 775 mECBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN; 776 mECBMStarted[i] = false; 777 mSCBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN; 778 mSCBMStarted[i] = false; 779 } 780 } 781 } 782 cutListToSize(List list, int size)783 private void cutListToSize(List list, int size) { 784 if (list == null) return; 785 786 while (list.size() > size) { 787 list.remove(list.size() - 1); 788 } 789 } 790 791 // we keep a copy of all of the state so we can send it out when folks 792 // register for it 793 // 794 // In these calls we call with the lock held. This is safe becasuse remote 795 // calls go through a oneway interface and local calls going through a 796 // handler before they get to app code. 797 798 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) TelephonyRegistry(Context context, ConfigurationProvider configurationProvider)799 public TelephonyRegistry(Context context, ConfigurationProvider configurationProvider) { 800 mContext = context; 801 mConfigurationProvider = configurationProvider; 802 mBatteryStats = BatteryStatsService.getService(); 803 804 int numPhones = getTelephonyManager().getActiveModemCount(); 805 if (DBG) log("TelephonyRegistry: ctor numPhones=" + numPhones); 806 mNumPhones = numPhones; 807 mCallState = new int[numPhones]; 808 mDataActivity = new int[numPhones]; 809 mDataConnectionState = new int[numPhones]; 810 mDataConnectionNetworkType = new int[numPhones]; 811 mCallIncomingNumber = new String[numPhones]; 812 mServiceState = new ServiceState[numPhones]; 813 mVoiceActivationState = new int[numPhones]; 814 mDataActivationState = new int[numPhones]; 815 mUserMobileDataState = new boolean[numPhones]; 816 mSignalStrength = new SignalStrength[numPhones]; 817 mMessageWaiting = new boolean[numPhones]; 818 mCallForwarding = new boolean[numPhones]; 819 mCellIdentity = new CellIdentity[numPhones]; 820 mSrvccState = new int[numPhones]; 821 mPreciseCallState = new PreciseCallState[numPhones]; 822 mForegroundCallState = new int[numPhones]; 823 mBackgroundCallState = new int[numPhones]; 824 mRingingCallState = new int[numPhones]; 825 mCallDisconnectCause = new int[numPhones]; 826 mCallPreciseDisconnectCause = new int[numPhones]; 827 mCallQuality = new CallQuality[numPhones]; 828 mMediaQualityStatus = new ArrayList<>(); 829 mCallNetworkType = new int[numPhones]; 830 mCallStateLists = new ArrayList<>(); 831 mPreciseDataConnectionStates = new ArrayList<>(); 832 mCellInfo = new ArrayList<>(numPhones); 833 mImsReasonInfo = new ArrayList<>(); 834 mEmergencyNumberList = new HashMap<>(); 835 mOutgoingCallEmergencyNumber = new EmergencyNumber[numPhones]; 836 mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones]; 837 mBarringInfo = new ArrayList<>(); 838 mCarrierNetworkChangeState = new boolean[numPhones]; 839 mTelephonyDisplayInfos = new TelephonyDisplayInfo[numPhones]; 840 mPhysicalChannelConfigs = new ArrayList<>(); 841 mAllowedNetworkTypeReason = new int[numPhones]; 842 mAllowedNetworkTypeValue = new long[numPhones]; 843 mIsDataEnabled = new boolean[numPhones]; 844 mDataEnabledReason = new int[numPhones]; 845 mLinkCapacityEstimateLists = new ArrayList<>(); 846 mCarrierPrivilegeStates = new ArrayList<>(); 847 mCarrierServiceStates = new ArrayList<>(); 848 mECBMReason = new int[numPhones]; 849 mECBMStarted = new boolean[numPhones]; 850 mSCBMReason = new int[numPhones]; 851 mSCBMStarted = new boolean[numPhones]; 852 853 for (int i = 0; i < numPhones; i++) { 854 mCallState[i] = TelephonyManager.CALL_STATE_IDLE; 855 mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; 856 mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN; 857 mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 858 mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 859 mCallIncomingNumber[i] = ""; 860 mServiceState[i] = new ServiceState(); 861 mSignalStrength[i] = null; 862 mUserMobileDataState[i] = false; 863 mMessageWaiting[i] = false; 864 mCallForwarding[i] = false; 865 mCellIdentity[i] = null; 866 mCellInfo.add(i, Collections.EMPTY_LIST); 867 mImsReasonInfo.add(i, new ImsReasonInfo()); 868 mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE; 869 mCallDisconnectCause[i] = DisconnectCause.NOT_VALID; 870 mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID; 871 mCallQuality[i] = createCallQuality(); 872 mMediaQualityStatus.add(i, new SparseArray<>()); 873 mCallStateLists.add(i, new ArrayList<>()); 874 mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN; 875 mPreciseCallState[i] = createPreciseCallState(); 876 mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; 877 mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; 878 mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; 879 mPreciseDataConnectionStates.add(new ArrayMap<>()); 880 mBarringInfo.add(i, new BarringInfo()); 881 mCarrierNetworkChangeState[i] = false; 882 mTelephonyDisplayInfos[i] = null; 883 mIsDataEnabled[i] = false; 884 mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER; 885 mPhysicalChannelConfigs.add(i, new ArrayList<>()); 886 mAllowedNetworkTypeReason[i] = -1; 887 mAllowedNetworkTypeValue[i] = -1; 888 mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST); 889 mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0])); 890 mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID)); 891 mECBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN; 892 mECBMStarted[i] = false; 893 mSCBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN; 894 mSCBMStarted[i] = false; 895 } 896 897 mAppOps = mContext.getSystemService(AppOpsManager.class); 898 } 899 systemRunning()900 public void systemRunning() { 901 // Watch for interesting updates 902 final IntentFilter filter = new IntentFilter(); 903 filter.addAction(Intent.ACTION_USER_SWITCHED); 904 filter.addAction(Intent.ACTION_USER_REMOVED); 905 filter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED); 906 filter.addAction(ACTION_MULTI_SIM_CONFIG_CHANGED); 907 log("systemRunning register for intents"); 908 mContext.registerReceiver(mBroadcastReceiver, filter); 909 } 910 911 //helper function to determine if limit on num listeners applies to callingUid doesLimitApplyForListeners(int callingUid, int exemptUid)912 private boolean doesLimitApplyForListeners(int callingUid, int exemptUid) { 913 return (callingUid != Process.SYSTEM_UID 914 && callingUid != Process.PHONE_UID 915 && callingUid != exemptUid); 916 } 917 918 @Override addOnSubscriptionsChangedListener(String callingPackage, String callingFeatureId, IOnSubscriptionsChangedListener callback)919 public void addOnSubscriptionsChangedListener(String callingPackage, String callingFeatureId, 920 IOnSubscriptionsChangedListener callback) { 921 int callerUserId = UserHandle.getCallingUserId(); 922 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 923 if (VDBG) { 924 log("listen oscl: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid() 925 + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId 926 + " callback=" + callback + " callback.asBinder=" + callback.asBinder()); 927 } 928 929 synchronized (mRecords) { 930 // register 931 IBinder b = callback.asBinder(); 932 boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(), 933 Process.myUid()); 934 Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); // 935 936 if (r == null) { 937 return; 938 } 939 940 r.context = mContext; 941 r.onSubscriptionsChangedListenerCallback = callback; 942 r.callingPackage = callingPackage; 943 r.callingFeatureId = callingFeatureId; 944 r.callerUid = Binder.getCallingUid(); 945 r.callerPid = Binder.getCallingPid(); 946 r.eventList = new ArraySet<>(); 947 if (DBG) { 948 log("listen oscl: Register r=" + r); 949 } 950 // Always notify when registration occurs if there has been a notification. 951 if (mHasNotifySubscriptionInfoChangedOccurred) { 952 try { 953 if (VDBG) log("listen oscl: send to r=" + r); 954 r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); 955 if (VDBG) log("listen oscl: sent to r=" + r); 956 } catch (RemoteException e) { 957 if (VDBG) log("listen oscl: remote exception sending to r=" + r + " e=" + e); 958 remove(r.binder); 959 } 960 } else { 961 log("listen oscl: mHasNotifySubscriptionInfoChangedOccurred==false no callback"); 962 } 963 } 964 } 965 966 @Override removeOnSubscriptionsChangedListener(String pkgForDebug, IOnSubscriptionsChangedListener callback)967 public void removeOnSubscriptionsChangedListener(String pkgForDebug, 968 IOnSubscriptionsChangedListener callback) { 969 if (DBG) log("listen oscl: Unregister"); 970 remove(callback.asBinder()); 971 } 972 973 974 @Override addOnOpportunisticSubscriptionsChangedListener(String callingPackage, String callingFeatureId, IOnSubscriptionsChangedListener callback)975 public void addOnOpportunisticSubscriptionsChangedListener(String callingPackage, 976 String callingFeatureId, IOnSubscriptionsChangedListener callback) { 977 int callerUserId = UserHandle.getCallingUserId(); 978 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 979 if (VDBG) { 980 log("listen ooscl: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid() 981 + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId 982 + " callback=" + callback + " callback.asBinder=" + callback.asBinder()); 983 } 984 985 synchronized (mRecords) { 986 // register 987 IBinder b = callback.asBinder(); 988 boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(), 989 Process.myUid()); 990 Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); // 991 992 if (r == null) { 993 return; 994 } 995 996 r.context = mContext; 997 r.onOpportunisticSubscriptionsChangedListenerCallback = callback; 998 r.callingPackage = callingPackage; 999 r.callingFeatureId = callingFeatureId; 1000 r.callerUid = Binder.getCallingUid(); 1001 r.callerPid = Binder.getCallingPid(); 1002 r.eventList = new ArraySet<>(); 1003 if (DBG) { 1004 log("listen ooscl: Register r=" + r); 1005 } 1006 // Always notify when registration occurs if there has been a notification. 1007 if (mHasNotifyOpportunisticSubscriptionInfoChangedOccurred) { 1008 try { 1009 if (VDBG) log("listen ooscl: send to r=" + r); 1010 r.onOpportunisticSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); 1011 if (VDBG) log("listen ooscl: sent to r=" + r); 1012 } catch (RemoteException e) { 1013 if (VDBG) log("listen ooscl: remote exception sending to r=" + r + " e=" + e); 1014 remove(r.binder); 1015 } 1016 } else { 1017 log("listen ooscl: hasNotifyOpptSubInfoChangedOccurred==false no callback"); 1018 } 1019 } 1020 } 1021 1022 @Override notifySubscriptionInfoChanged()1023 public void notifySubscriptionInfoChanged() { 1024 if (VDBG) log("notifySubscriptionInfoChanged:"); 1025 if (!checkNotifyPermission("notifySubscriptionInfoChanged()")) { 1026 return; 1027 } 1028 1029 synchronized (mRecords) { 1030 if (!mHasNotifySubscriptionInfoChangedOccurred) { 1031 log("notifySubscriptionInfoChanged: first invocation mRecords.size=" 1032 + mRecords.size()); 1033 } 1034 mHasNotifySubscriptionInfoChangedOccurred = true; 1035 mRemoveList.clear(); 1036 for (Record r : mRecords) { 1037 if (r.matchOnSubscriptionsChangedListener()) { 1038 try { 1039 if (VDBG) log("notifySubscriptionInfoChanged: call osc to r=" + r); 1040 r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); 1041 if (VDBG) log("notifySubscriptionInfoChanged: done osc to r=" + r); 1042 } catch (RemoteException ex) { 1043 if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r); 1044 mRemoveList.add(r.binder); 1045 } 1046 } 1047 } 1048 handleRemoveListLocked(); 1049 } 1050 } 1051 1052 @Override notifyOpportunisticSubscriptionInfoChanged()1053 public void notifyOpportunisticSubscriptionInfoChanged() { 1054 if (VDBG) log("notifyOpptSubscriptionInfoChanged:"); 1055 if (!checkNotifyPermission("notifyOpportunisticSubscriptionInfoChanged()")) { 1056 return; 1057 } 1058 1059 synchronized (mRecords) { 1060 if (!mHasNotifyOpportunisticSubscriptionInfoChangedOccurred) { 1061 log("notifyOpptSubscriptionInfoChanged: first invocation mRecords.size=" 1062 + mRecords.size()); 1063 } 1064 mHasNotifyOpportunisticSubscriptionInfoChangedOccurred = true; 1065 mRemoveList.clear(); 1066 for (Record r : mRecords) { 1067 if (r.matchOnOpportunisticSubscriptionsChangedListener()) { 1068 try { 1069 if (VDBG) log("notifyOpptSubChanged: call oosc to r=" + r); 1070 r.onOpportunisticSubscriptionsChangedListenerCallback 1071 .onSubscriptionsChanged(); 1072 if (VDBG) log("notifyOpptSubChanged: done oosc to r=" + r); 1073 } catch (RemoteException ex) { 1074 if (VDBG) log("notifyOpptSubChanged: RemoteException r=" + r); 1075 mRemoveList.add(r.binder); 1076 } 1077 } 1078 } 1079 handleRemoveListLocked(); 1080 } 1081 } 1082 1083 @Override listenWithEventList(boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, int subId, String callingPackage, String callingFeatureId, IPhoneStateListener callback, int[] events, boolean notifyNow)1084 public void listenWithEventList(boolean renounceFineLocationAccess, 1085 boolean renounceCoarseLocationAccess, int subId, String callingPackage, 1086 String callingFeatureId, IPhoneStateListener callback, 1087 int[] events, boolean notifyNow) { 1088 Set<Integer> eventList = Arrays.stream(events).boxed().collect(Collectors.toSet()); 1089 listen(renounceFineLocationAccess, renounceCoarseLocationAccess, callingPackage, 1090 callingFeatureId, callback, eventList, notifyNow, subId); 1091 } 1092 listen(boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, String callingPackage, @Nullable String callingFeatureId, IPhoneStateListener callback, Set<Integer> events, boolean notifyNow, int subId)1093 private void listen(boolean renounceFineLocationAccess, 1094 boolean renounceCoarseLocationAccess, String callingPackage, 1095 @Nullable String callingFeatureId, IPhoneStateListener callback, 1096 Set<Integer> events, boolean notifyNow, int subId) { 1097 int callerUserId = UserHandle.getCallingUserId(); 1098 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 1099 String str = "listen: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid() 1100 + " events=" + events + " notifyNow=" + notifyNow 1101 + " subId=" + subId + " myUserId=" + UserHandle.myUserId() 1102 + " callerUserId=" + callerUserId; 1103 mListenLog.log(str); 1104 if (VDBG) { 1105 log(str); 1106 } 1107 1108 if (events.isEmpty()) { 1109 if (DBG) { 1110 log("listen: Unregister"); 1111 } 1112 events.clear(); 1113 remove(callback.asBinder()); 1114 return; 1115 } 1116 1117 // Checks permission and throws SecurityException for disallowed operations. For pre-M 1118 // apps whose runtime permission has been revoked, we return immediately to skip sending 1119 // events to the app without crashing it. 1120 if (!checkListenerPermission(events, subId, callingPackage, callingFeatureId, "listen")) { 1121 return; 1122 } 1123 1124 synchronized (mRecords) { 1125 // register 1126 IBinder b = callback.asBinder(); 1127 boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(), 1128 Process.myUid()); 1129 Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); 1130 1131 if (r == null) { 1132 return; 1133 } 1134 1135 r.context = mContext; 1136 r.callback = callback; 1137 r.callingPackage = callingPackage; 1138 r.callingFeatureId = callingFeatureId; 1139 r.renounceCoarseLocationAccess = renounceCoarseLocationAccess; 1140 r.renounceFineLocationAccess = renounceFineLocationAccess; 1141 r.callerUid = Binder.getCallingUid(); 1142 r.callerPid = Binder.getCallingPid(); 1143 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID, 1144 // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID 1145 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 1146 if (DBG) { 1147 log("invalid subscription id, use default id"); 1148 } 1149 r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; 1150 } else {//APP specify subID 1151 r.subId = subId; 1152 } 1153 r.phoneId = getPhoneIdFromSubId(r.subId); 1154 r.eventList = events; 1155 1156 if (DBG) { 1157 log("listen: Register r=" + r + " r.subId=" + r.subId + " r.phoneId=" + r.phoneId); 1158 } 1159 if (notifyNow && validatePhoneId(r.phoneId)) { 1160 if (events.contains(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED)){ 1161 try { 1162 if (VDBG) log("listen: call onSSC state=" + mServiceState[r.phoneId]); 1163 ServiceState rawSs = new ServiceState(mServiceState[r.phoneId]); 1164 if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { 1165 r.callback.onServiceStateChanged(rawSs); 1166 } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { 1167 r.callback.onServiceStateChanged( 1168 rawSs.createLocationInfoSanitizedCopy(false)); 1169 } else { 1170 r.callback.onServiceStateChanged( 1171 rawSs.createLocationInfoSanitizedCopy(true)); 1172 } 1173 } catch (RemoteException ex) { 1174 remove(r.binder); 1175 } 1176 } 1177 if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)) { 1178 try { 1179 if (mSignalStrength[r.phoneId] != null) { 1180 int gsmSignalStrength = mSignalStrength[r.phoneId] 1181 .getGsmSignalStrength(); 1182 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 1183 : gsmSignalStrength)); 1184 } 1185 } catch (RemoteException ex) { 1186 remove(r.binder); 1187 } 1188 } 1189 if (events.contains( 1190 TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) { 1191 try { 1192 r.callback.onMessageWaitingIndicatorChanged( 1193 mMessageWaiting[r.phoneId]); 1194 } catch (RemoteException ex) { 1195 remove(r.binder); 1196 } 1197 } 1198 if (events.contains( 1199 TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) { 1200 try { 1201 r.callback.onCallForwardingIndicatorChanged( 1202 mCallForwarding[r.phoneId]); 1203 } catch (RemoteException ex) { 1204 remove(r.binder); 1205 } 1206 } 1207 if (validateEventAndUserLocked( 1208 r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)) { 1209 try { 1210 if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[r.phoneId]); 1211 if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) 1212 && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { 1213 // null will be translated to empty CellLocation object in client. 1214 r.callback.onCellLocationChanged(mCellIdentity[r.phoneId]); 1215 } 1216 } catch (RemoteException ex) { 1217 remove(r.binder); 1218 } 1219 } 1220 if (events.contains(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)) { 1221 try { 1222 r.callback.onLegacyCallStateChanged(mCallState[r.phoneId], 1223 getCallIncomingNumber(r, r.phoneId)); 1224 } catch (RemoteException ex) { 1225 remove(r.binder); 1226 } 1227 } 1228 if (events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED)) { 1229 try { 1230 r.callback.onCallStateChanged(mCallState[r.phoneId]); 1231 } catch (RemoteException ex) { 1232 remove(r.binder); 1233 } 1234 } 1235 if (events.contains(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)) { 1236 try { 1237 r.callback.onDataConnectionStateChanged(mDataConnectionState[r.phoneId], 1238 mDataConnectionNetworkType[r.phoneId]); 1239 } catch (RemoteException ex) { 1240 remove(r.binder); 1241 } 1242 } 1243 if (events.contains(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED)) { 1244 try { 1245 r.callback.onDataActivity(mDataActivity[r.phoneId]); 1246 } catch (RemoteException ex) { 1247 remove(r.binder); 1248 } 1249 } 1250 if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)) { 1251 try { 1252 if (mSignalStrength[r.phoneId] != null) { 1253 r.callback.onSignalStrengthsChanged(mSignalStrength[r.phoneId]); 1254 } 1255 } catch (RemoteException ex) { 1256 remove(r.binder); 1257 } 1258 } 1259 if (validateEventAndUserLocked( 1260 r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)) { 1261 try { 1262 if (DBG_LOC) { 1263 log("listen: mCellInfo[" + r.phoneId + "] = " 1264 + mCellInfo.get(r.phoneId)); 1265 } 1266 if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) 1267 && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { 1268 r.callback.onCellInfoChanged(mCellInfo.get(r.phoneId)); 1269 } 1270 } catch (RemoteException ex) { 1271 remove(r.binder); 1272 } 1273 } 1274 if (events.contains(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED)) { 1275 try { 1276 r.callback.onPreciseCallStateChanged(mPreciseCallState[r.phoneId]); 1277 } catch (RemoteException ex) { 1278 remove(r.binder); 1279 } 1280 } 1281 if (events.contains(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)) { 1282 try { 1283 r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[r.phoneId], 1284 mCallPreciseDisconnectCause[r.phoneId]); 1285 } catch (RemoteException ex) { 1286 remove(r.binder); 1287 } 1288 } 1289 if (events.contains(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)) { 1290 ImsReasonInfo imsReasonInfo = mImsReasonInfo.get(r.phoneId); 1291 if (imsReasonInfo != null) { 1292 try { 1293 r.callback.onImsCallDisconnectCauseChanged(imsReasonInfo); 1294 } catch (RemoteException ex) { 1295 remove(r.binder); 1296 } 1297 } 1298 } 1299 if (events.contains( 1300 TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)) { 1301 try { 1302 for (PreciseDataConnectionState pdcs 1303 : mPreciseDataConnectionStates.get(r.phoneId).values()) { 1304 r.callback.onPreciseDataConnectionStateChanged(pdcs); 1305 } 1306 } catch (RemoteException ex) { 1307 remove(r.binder); 1308 } 1309 } 1310 if (events.contains(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)) { 1311 try { 1312 r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState[r.phoneId]); 1313 } catch (RemoteException ex) { 1314 remove(r.binder); 1315 } 1316 } 1317 if (events.contains(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)) { 1318 try { 1319 r.callback.onVoiceActivationStateChanged( 1320 mVoiceActivationState[r.phoneId]); 1321 } catch (RemoteException ex) { 1322 remove(r.binder); 1323 } 1324 } 1325 if (events.contains(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED)) { 1326 try { 1327 r.callback.onDataActivationStateChanged(mDataActivationState[r.phoneId]); 1328 } catch (RemoteException ex) { 1329 remove(r.binder); 1330 } 1331 } 1332 if (events.contains(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) { 1333 try { 1334 r.callback.onUserMobileDataStateChanged(mUserMobileDataState[r.phoneId]); 1335 } catch (RemoteException ex) { 1336 remove(r.binder); 1337 } 1338 } 1339 if (events.contains(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)) { 1340 try { 1341 if (mTelephonyDisplayInfos[r.phoneId] != null) { 1342 r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[r.phoneId]); 1343 } 1344 } catch (RemoteException ex) { 1345 remove(r.binder); 1346 } 1347 } 1348 if (events.contains(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)) { 1349 try { 1350 r.callback.onEmergencyNumberListChanged(mEmergencyNumberList); 1351 } catch (RemoteException ex) { 1352 remove(r.binder); 1353 } 1354 } 1355 if (events.contains(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED)) { 1356 try { 1357 r.callback.onPhoneCapabilityChanged(mPhoneCapability); 1358 } catch (RemoteException ex) { 1359 remove(r.binder); 1360 } 1361 } 1362 if (events.contains( 1363 TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) { 1364 try { 1365 r.callback.onActiveDataSubIdChanged(mActiveDataSubId); 1366 } catch (RemoteException ex) { 1367 remove(r.binder); 1368 } 1369 } 1370 if (events.contains(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED)) { 1371 try { 1372 r.callback.onRadioPowerStateChanged(mRadioPowerState); 1373 } catch (RemoteException ex) { 1374 remove(r.binder); 1375 } 1376 } 1377 if (events.contains(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)) { 1378 try { 1379 r.callback.onSrvccStateChanged(mSrvccState[r.phoneId]); 1380 } catch (RemoteException ex) { 1381 remove(r.binder); 1382 } 1383 } 1384 if (events.contains(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)) { 1385 try { 1386 r.callback.onCallStatesChanged(mCallStateLists.get(r.phoneId)); 1387 } catch (RemoteException ex) { 1388 remove(r.binder); 1389 } 1390 } 1391 if (events.contains(TelephonyCallback.EVENT_BARRING_INFO_CHANGED)) { 1392 BarringInfo barringInfo = mBarringInfo.get(r.phoneId); 1393 if (VDBG) { 1394 log("listen: call onBarringInfoChanged=" + barringInfo); 1395 } 1396 if (barringInfo != null) { 1397 BarringInfo biNoLocation = barringInfo.createLocationInfoSanitizedCopy(); 1398 1399 try { 1400 r.callback.onBarringInfoChanged( 1401 checkFineLocationAccess(r, Build.VERSION_CODES.BASE) 1402 ? barringInfo : biNoLocation); 1403 } catch (RemoteException ex) { 1404 remove(r.binder); 1405 } 1406 } 1407 } 1408 if (events.contains( 1409 TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)) { 1410 try { 1411 r.callback.onPhysicalChannelConfigChanged( 1412 shouldSanitizeLocationForPhysicalChannelConfig(r) 1413 ? getLocationSanitizedConfigs( 1414 mPhysicalChannelConfigs.get(r.phoneId)) 1415 : mPhysicalChannelConfigs.get(r.phoneId)); 1416 } catch (RemoteException ex) { 1417 remove(r.binder); 1418 } 1419 } 1420 if (events.contains( 1421 TelephonyCallback.EVENT_DATA_ENABLED_CHANGED)) { 1422 try { 1423 r.callback.onDataEnabledChanged( 1424 mIsDataEnabled[r.phoneId], mDataEnabledReason[r.phoneId]); 1425 } catch (RemoteException ex) { 1426 remove(r.binder); 1427 } 1428 } 1429 if (events.contains( 1430 TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED)) { 1431 try { 1432 if (mLinkCapacityEstimateLists.get(r.phoneId) != null) { 1433 r.callback.onLinkCapacityEstimateChanged(mLinkCapacityEstimateLists 1434 .get(r.phoneId)); 1435 } 1436 } catch (RemoteException ex) { 1437 remove(r.binder); 1438 } 1439 } 1440 if (events.contains(TelephonyCallback.EVENT_MEDIA_QUALITY_STATUS_CHANGED)) { 1441 CallState callState = null; 1442 for (CallState cs : mCallStateLists.get(r.phoneId)) { 1443 if (cs.getCallState() == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) { 1444 callState = cs; 1445 break; 1446 } 1447 } 1448 if (callState != null) { 1449 String callId = callState.getImsCallSessionId(); 1450 try { 1451 MediaQualityStatus status = mMediaQualityStatus.get(r.phoneId).get( 1452 MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO); 1453 if (status != null && status.getCallSessionId().equals(callId)) { 1454 r.callback.onMediaQualityStatusChanged(status); 1455 } 1456 status = mMediaQualityStatus.get(r.phoneId).get( 1457 MediaQualityStatus.MEDIA_SESSION_TYPE_VIDEO); 1458 if (status != null && status.getCallSessionId().equals(callId)) { 1459 r.callback.onMediaQualityStatusChanged(status); 1460 } 1461 } catch (RemoteException ex) { 1462 remove(r.binder); 1463 } 1464 } 1465 } 1466 if (events.contains(TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) { 1467 try { 1468 boolean ecbmStarted = mECBMStarted[r.phoneId]; 1469 if (ecbmStarted) { 1470 r.callback.onCallBackModeStarted( 1471 TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL); 1472 } else { 1473 r.callback.onCallBackModeStopped( 1474 TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL, 1475 mECBMReason[r.phoneId]); 1476 } 1477 1478 boolean scbmStarted = mSCBMStarted[r.phoneId]; 1479 if (scbmStarted) { 1480 r.callback.onCallBackModeStarted( 1481 TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS); 1482 } else { 1483 r.callback.onCallBackModeStopped( 1484 TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS, 1485 mSCBMReason[r.phoneId]); 1486 } 1487 } catch (RemoteException ex) { 1488 remove(r.binder); 1489 } 1490 } 1491 } 1492 } 1493 } 1494 getCallIncomingNumber(Record record, int phoneId)1495 private String getCallIncomingNumber(Record record, int phoneId) { 1496 // Only reveal the incoming number if the record has read call log permission. 1497 return record.canReadCallLog() ? mCallIncomingNumber[phoneId] : ""; 1498 } 1499 add(IBinder binder, int callingUid, int callingPid, boolean doesLimitApply)1500 private Record add(IBinder binder, int callingUid, int callingPid, boolean doesLimitApply) { 1501 Record r; 1502 1503 synchronized (mRecords) { 1504 final int N = mRecords.size(); 1505 // While iterating through the records, keep track of how many we have from this pid. 1506 int numRecordsForPid = 0; 1507 for (int i = 0; i < N; i++) { 1508 r = mRecords.get(i); 1509 if (binder == r.binder) { 1510 // Already existed. 1511 return r; 1512 } 1513 if (r.callerPid == callingPid) { 1514 numRecordsForPid++; 1515 } 1516 } 1517 // If we've exceeded the limit for registrations, log an error and quit. 1518 int registrationLimit = mConfigurationProvider.getRegistrationLimit(); 1519 1520 if (doesLimitApply 1521 && registrationLimit >= 1 1522 && numRecordsForPid >= registrationLimit) { 1523 String errorMsg = "Pid " + callingPid + " has exceeded the number of permissible" 1524 + " registered listeners. Ignoring request to add."; 1525 loge(errorMsg); 1526 if (mConfigurationProvider 1527 .isRegistrationLimitEnabledInPlatformCompat(callingUid)) { 1528 throw new IllegalStateException(errorMsg); 1529 } 1530 } else if (numRecordsForPid 1531 >= TelephonyCallback.DEFAULT_PER_PID_REGISTRATION_LIMIT / 2) { 1532 // Log the warning independently of the dynamically set limit -- apps shouldn't be 1533 // doing this regardless of whether we're throwing them an exception for it. 1534 Rlog.w(TAG, "Pid " + callingPid + " has exceeded half the number of permissible" 1535 + " registered listeners. Now at " + numRecordsForPid); 1536 } 1537 1538 r = new Record(); 1539 r.binder = binder; 1540 r.deathRecipient = new TelephonyRegistryDeathRecipient(binder); 1541 1542 try { 1543 binder.linkToDeath(r.deathRecipient, 0); 1544 } catch (RemoteException e) { 1545 if (VDBG) log("LinkToDeath remote exception sending to r=" + r + " e=" + e); 1546 // Binder already died. Return null. 1547 return null; 1548 } 1549 1550 mRecords.add(r); 1551 if (DBG) log("add new record"); 1552 } 1553 1554 return r; 1555 } 1556 remove(IBinder binder)1557 private void remove(IBinder binder) { 1558 synchronized (mRecords) { 1559 final int recordCount = mRecords.size(); 1560 for (int i = 0; i < recordCount; i++) { 1561 Record r = mRecords.get(i); 1562 if (r.binder == binder) { 1563 if (DBG) { 1564 log("remove: binder=" + binder + " r.callingPackage " + r.callingPackage 1565 + " r.callback " + r.callback); 1566 } 1567 1568 if (r.deathRecipient != null) { 1569 try { 1570 binder.unlinkToDeath(r.deathRecipient, 0); 1571 } catch (NoSuchElementException e) { 1572 if (VDBG) log("UnlinkToDeath NoSuchElementException sending to r=" 1573 + r + " e=" + e); 1574 } 1575 } 1576 1577 mRecords.remove(i); 1578 return; 1579 } 1580 } 1581 } 1582 } 1583 notifyCallStateForAllSubs(int state, String phoneNumber)1584 public void notifyCallStateForAllSubs(int state, String phoneNumber) { 1585 if (!checkNotifyPermission("notifyCallState()")) { 1586 return; 1587 } 1588 1589 if (VDBG) { 1590 log("notifyCallStateForAllSubs: state=" + state + " phoneNumber=" + phoneNumber); 1591 } 1592 1593 synchronized (mRecords) { 1594 for (Record r : mRecords) { 1595 if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED) 1596 && (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 1597 try { 1598 // Ensure the listener has read call log permission; if they do not return 1599 // an empty phone number. 1600 // This is ONLY for legacy onCallStateChanged in PhoneStateListener. 1601 String phoneNumberOrEmpty = r.canReadCallLog() ? phoneNumber : ""; 1602 r.callback.onLegacyCallStateChanged(state, phoneNumberOrEmpty); 1603 } catch (RemoteException ex) { 1604 mRemoveList.add(r.binder); 1605 } 1606 } 1607 1608 if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED) 1609 && (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 1610 try { 1611 // The new callback does NOT provide the phone number. 1612 r.callback.onCallStateChanged(state); 1613 } catch (RemoteException ex) { 1614 mRemoveList.add(r.binder); 1615 } 1616 } 1617 } 1618 handleRemoveListLocked(); 1619 } 1620 1621 // Called only by Telecomm to communicate call state across different phone accounts. So 1622 // there is no need to add a valid subId or slotId. 1623 broadcastCallStateChanged(state, phoneNumber, 1624 SubscriptionManager.INVALID_SIM_SLOT_INDEX, 1625 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1626 } 1627 notifyCallState(int phoneId, int subId, int state, String incomingNumber)1628 public void notifyCallState(int phoneId, int subId, int state, String incomingNumber) { 1629 if (!checkNotifyPermission("notifyCallState()")) { 1630 return; 1631 } 1632 if (VDBG) { 1633 log("notifyCallState: subId=" + subId 1634 + " state=" + state + " incomingNumber=" + incomingNumber); 1635 } 1636 synchronized (mRecords) { 1637 if (validatePhoneId(phoneId)) { 1638 mCallState[phoneId] = state; 1639 mCallIncomingNumber[phoneId] = incomingNumber; 1640 for (Record r : mRecords) { 1641 if (r.matchTelephonyCallbackEvent( 1642 TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED) 1643 && (r.subId == subId) 1644 && (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 1645 try { 1646 // Only the legacy PhoneStateListener receives the phone number. 1647 String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId); 1648 r.callback.onLegacyCallStateChanged(state, incomingNumberOrEmpty); 1649 } catch (RemoteException ex) { 1650 mRemoveList.add(r.binder); 1651 } 1652 } 1653 if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED) 1654 && (r.subId == subId) 1655 && (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 1656 try { 1657 // The phone number is not included in the new call state changed 1658 // listener. 1659 r.callback.onCallStateChanged(state); 1660 } catch (RemoteException ex) { 1661 mRemoveList.add(r.binder); 1662 } 1663 } 1664 } 1665 } 1666 handleRemoveListLocked(); 1667 } 1668 broadcastCallStateChanged(state, incomingNumber, phoneId, subId); 1669 } 1670 notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state)1671 public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) { 1672 if (!checkNotifyPermission("notifyServiceState()")){ 1673 return; 1674 } 1675 1676 final long callingIdentity = Binder.clearCallingIdentity(); 1677 try { 1678 synchronized (mRecords) { 1679 String str = "notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" 1680 + phoneId + " state=" + state; 1681 if (VDBG) { 1682 log(str); 1683 } 1684 mLocalLog.log(str); 1685 // for service state updates, don't notify clients when subId is invalid. This 1686 // prevents us from sending incorrect notifications like b/133140128 1687 // In the future, we can remove this logic for every notification here and add a 1688 // callback so listeners know when their PhoneStateListener's subId becomes invalid, 1689 // but for now we use the simplest fix. 1690 if (validatePhoneId(phoneId) && SubscriptionManager.isValidSubscriptionId(subId)) { 1691 mServiceState[phoneId] = state; 1692 1693 for (Record r : mRecords) { 1694 if (VDBG) { 1695 log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId 1696 + " phoneId=" + phoneId + " state=" + state); 1697 } 1698 if (r.matchTelephonyCallbackEvent( 1699 TelephonyCallback.EVENT_SERVICE_STATE_CHANGED) 1700 && idMatch(r, subId, phoneId)) { 1701 1702 try { 1703 ServiceState stateToSend; 1704 if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { 1705 stateToSend = new ServiceState(state); 1706 } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { 1707 stateToSend = state.createLocationInfoSanitizedCopy(false); 1708 } else { 1709 stateToSend = state.createLocationInfoSanitizedCopy(true); 1710 } 1711 if (DBG) { 1712 log("notifyServiceStateForSubscriber: callback.onSSC r=" + r 1713 + " subId=" + subId + " phoneId=" + phoneId 1714 + " state=" + stateToSend); 1715 } 1716 r.callback.onServiceStateChanged(stateToSend); 1717 } catch (RemoteException ex) { 1718 mRemoveList.add(r.binder); 1719 } 1720 } 1721 } 1722 } else { 1723 log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId 1724 + " or subId=" + subId); 1725 } 1726 handleRemoveListLocked(); 1727 } 1728 broadcastServiceStateChanged(state, phoneId, subId); 1729 } finally { 1730 Binder.restoreCallingIdentity(callingIdentity); 1731 } 1732 } 1733 notifySimActivationStateChangedForPhoneId(int phoneId, int subId, int activationType, int activationState)1734 public void notifySimActivationStateChangedForPhoneId(int phoneId, int subId, 1735 int activationType, int activationState) { 1736 if (!checkNotifyPermission("notifySimActivationState()")){ 1737 return; 1738 } 1739 if (VDBG) { 1740 log("notifySimActivationStateForPhoneId: subId=" + subId + " phoneId=" + phoneId 1741 + "type=" + activationType + " state=" + activationState); 1742 } 1743 synchronized (mRecords) { 1744 if (validatePhoneId(phoneId)) { 1745 switch (activationType) { 1746 case SIM_ACTIVATION_TYPE_VOICE: 1747 mVoiceActivationState[phoneId] = activationState; 1748 break; 1749 case SIM_ACTIVATION_TYPE_DATA: 1750 mDataActivationState[phoneId] = activationState; 1751 break; 1752 default: 1753 return; 1754 } 1755 for (Record r : mRecords) { 1756 if (VDBG) { 1757 log("notifySimActivationStateForPhoneId: r=" + r + " subId=" + subId 1758 + " phoneId=" + phoneId + "type=" + activationType 1759 + " state=" + activationState); 1760 } 1761 try { 1762 if ((activationType == SIM_ACTIVATION_TYPE_VOICE) 1763 && r.matchTelephonyCallbackEvent( 1764 TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED) 1765 && idMatch(r, subId, phoneId)) { 1766 if (DBG) { 1767 log("notifyVoiceActivationStateForPhoneId: callback.onVASC r=" + r 1768 + " subId=" + subId + " phoneId=" + phoneId 1769 + " state=" + activationState); 1770 } 1771 r.callback.onVoiceActivationStateChanged(activationState); 1772 } 1773 if ((activationType == SIM_ACTIVATION_TYPE_DATA) 1774 && r.matchTelephonyCallbackEvent( 1775 TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED) 1776 && idMatch(r, subId, phoneId)) { 1777 if (DBG) { 1778 log("notifyDataActivationStateForPhoneId: callback.onDASC r=" + r 1779 + " subId=" + subId + " phoneId=" + phoneId 1780 + " state=" + activationState); 1781 } 1782 r.callback.onDataActivationStateChanged(activationState); 1783 } 1784 } catch (RemoteException ex) { 1785 mRemoveList.add(r.binder); 1786 } 1787 } 1788 } else { 1789 log("notifySimActivationStateForPhoneId: INVALID phoneId=" + phoneId); 1790 } 1791 handleRemoveListLocked(); 1792 } 1793 } 1794 notifySignalStrengthForPhoneId(int phoneId, int subId, SignalStrength signalStrength)1795 public void notifySignalStrengthForPhoneId(int phoneId, int subId, 1796 SignalStrength signalStrength) { 1797 if (!checkNotifyPermission("notifySignalStrength()")) { 1798 return; 1799 } 1800 if (VDBG) { 1801 log("notifySignalStrengthForPhoneId: subId=" + subId 1802 +" phoneId=" + phoneId + " signalStrength=" + signalStrength); 1803 } 1804 1805 synchronized (mRecords) { 1806 if (validatePhoneId(phoneId)) { 1807 if (VDBG) log("notifySignalStrengthForPhoneId: valid phoneId=" + phoneId); 1808 mSignalStrength[phoneId] = signalStrength; 1809 for (Record r : mRecords) { 1810 if (VDBG) { 1811 log("notifySignalStrengthForPhoneId: r=" + r + " subId=" + subId 1812 + " phoneId=" + phoneId + " ss=" + signalStrength); 1813 } 1814 if (r.matchTelephonyCallbackEvent( 1815 TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED) 1816 && idMatch(r, subId, phoneId)) { 1817 try { 1818 if (DBG) { 1819 log("notifySignalStrengthForPhoneId: callback.onSsS r=" + r 1820 + " subId=" + subId + " phoneId=" + phoneId 1821 + " ss=" + signalStrength); 1822 } 1823 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 1824 } catch (RemoteException ex) { 1825 mRemoveList.add(r.binder); 1826 } 1827 } 1828 if (r.matchTelephonyCallbackEvent( 1829 TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED) 1830 && idMatch(r, subId, phoneId)) { 1831 try { 1832 int gsmSignalStrength = signalStrength.getGsmSignalStrength(); 1833 int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 1834 if (DBG) { 1835 log("notifySignalStrengthForPhoneId: callback.onSS r=" + r 1836 + " subId=" + subId + " phoneId=" + phoneId 1837 + " gsmSS=" + gsmSignalStrength + " ss=" + ss); 1838 } 1839 r.callback.onSignalStrengthChanged(ss); 1840 } catch (RemoteException ex) { 1841 mRemoveList.add(r.binder); 1842 } 1843 } 1844 } 1845 } else { 1846 log("notifySignalStrengthForPhoneId: invalid phoneId=" + phoneId); 1847 } 1848 handleRemoveListLocked(); 1849 } 1850 broadcastSignalStrengthChanged(signalStrength, phoneId, subId); 1851 } 1852 1853 @Override notifyCarrierNetworkChange(boolean active)1854 public void notifyCarrierNetworkChange(boolean active) { 1855 // only CarrierService with carrier privilege rule should have the permission 1856 int[] subIds = Arrays.stream(SubscriptionManager.from(mContext) 1857 .getCompleteActiveSubscriptionIdList()) 1858 .filter(i -> TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, 1859 i)).toArray(); 1860 if (ArrayUtils.isEmpty(subIds)) { 1861 loge("notifyCarrierNetworkChange without carrier privilege"); 1862 // the active subId does not have carrier privilege. 1863 throw new SecurityException("notifyCarrierNetworkChange without carrier privilege"); 1864 } 1865 1866 for (int subId : subIds) { 1867 notifyCarrierNetworkChangeWithPermission(subId, active); 1868 } 1869 } 1870 1871 @Override notifyCarrierNetworkChangeWithSubId(int subId, boolean active)1872 public void notifyCarrierNetworkChangeWithSubId(int subId, boolean active) { 1873 if (!TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, subId)) { 1874 throw new SecurityException( 1875 "notifyCarrierNetworkChange without carrier privilege on subId " + subId); 1876 } 1877 1878 notifyCarrierNetworkChangeWithPermission(subId, active); 1879 } 1880 notifyCarrierNetworkChangeWithPermission(int subId, boolean active)1881 private void notifyCarrierNetworkChangeWithPermission(int subId, boolean active) { 1882 synchronized (mRecords) { 1883 int phoneId = getPhoneIdFromSubId(subId); 1884 mCarrierNetworkChangeState[phoneId] = active; 1885 1886 if (VDBG) { 1887 log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId); 1888 } 1889 for (Record r : mRecords) { 1890 if (r.matchTelephonyCallbackEvent( 1891 TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED) 1892 && idMatch(r, subId, phoneId)) { 1893 try { 1894 r.callback.onCarrierNetworkChange(active); 1895 } catch (RemoteException ex) { 1896 mRemoveList.add(r.binder); 1897 } 1898 } 1899 } 1900 handleRemoveListLocked(); 1901 } 1902 } 1903 notifyCellInfo(List<CellInfo> cellInfo)1904 public void notifyCellInfo(List<CellInfo> cellInfo) { 1905 notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellInfo); 1906 } 1907 notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo)1908 public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) { 1909 if (!checkNotifyPermission("notifyCellInfoForSubscriber()")) { 1910 return; 1911 } 1912 1913 if (VDBG) { 1914 log("notifyCellInfoForSubscriber: subId=" + subId 1915 + " cellInfo=" + cellInfo); 1916 } 1917 1918 if (cellInfo == null) { 1919 loge("notifyCellInfoForSubscriber() received a null list"); 1920 cellInfo = Collections.EMPTY_LIST; 1921 } 1922 1923 int phoneId = getPhoneIdFromSubId(subId); 1924 synchronized (mRecords) { 1925 if (validatePhoneId(phoneId)) { 1926 mCellInfo.set(phoneId, cellInfo); 1927 for (Record r : mRecords) { 1928 if (validateEventAndUserLocked( 1929 r, TelephonyCallback.EVENT_CELL_INFO_CHANGED) 1930 && idMatch(r, subId, phoneId) 1931 && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) 1932 && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) { 1933 try { 1934 if (DBG_LOC) { 1935 log("notifyCellInfoForSubscriber: mCellInfo=" + cellInfo 1936 + " r=" + r); 1937 } 1938 r.callback.onCellInfoChanged(cellInfo); 1939 } catch (RemoteException ex) { 1940 mRemoveList.add(r.binder); 1941 } 1942 } 1943 } 1944 } 1945 handleRemoveListLocked(); 1946 } 1947 } 1948 1949 @Override notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi)1950 public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) { 1951 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) { 1952 return; 1953 } 1954 if (VDBG) { 1955 log("notifyMessageWaitingChangedForSubscriberPhoneID: subId=" + phoneId 1956 + " mwi=" + mwi); 1957 } 1958 synchronized (mRecords) { 1959 if (validatePhoneId(phoneId)) { 1960 mMessageWaiting[phoneId] = mwi; 1961 for (Record r : mRecords) { 1962 if (r.matchTelephonyCallbackEvent( 1963 TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED) 1964 && idMatch(r, subId, phoneId)) { 1965 try { 1966 r.callback.onMessageWaitingIndicatorChanged(mwi); 1967 } catch (RemoteException ex) { 1968 mRemoveList.add(r.binder); 1969 } 1970 } 1971 } 1972 } 1973 handleRemoveListLocked(); 1974 } 1975 } 1976 notifyUserMobileDataStateChangedForPhoneId(int phoneId, int subId, boolean state)1977 public void notifyUserMobileDataStateChangedForPhoneId(int phoneId, int subId, boolean state) { 1978 if (!checkNotifyPermission("notifyUserMobileDataStateChanged()")) { 1979 return; 1980 } 1981 if (VDBG) { 1982 log("notifyUserMobileDataStateChangedForSubscriberPhoneID: PhoneId=" + phoneId 1983 + " subId=" + subId + " state=" + state); 1984 } 1985 synchronized (mRecords) { 1986 if (validatePhoneId(phoneId)) { 1987 mUserMobileDataState[phoneId] = state; 1988 for (Record r : mRecords) { 1989 if (r.matchTelephonyCallbackEvent( 1990 TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED) 1991 && idMatch(r, subId, phoneId)) { 1992 try { 1993 r.callback.onUserMobileDataStateChanged(state); 1994 } catch (RemoteException ex) { 1995 mRemoveList.add(r.binder); 1996 } 1997 } 1998 } 1999 } 2000 handleRemoveListLocked(); 2001 } 2002 } 2003 2004 /** 2005 * Notify display network info changed. 2006 * 2007 * @param phoneId Phone id 2008 * @param subId Subscription id 2009 * @param telephonyDisplayInfo Display network info 2010 * 2011 * @see PhoneStateListener#onDisplayInfoChanged(TelephonyDisplayInfo) 2012 */ notifyDisplayInfoChanged(int phoneId, int subId, @NonNull TelephonyDisplayInfo telephonyDisplayInfo)2013 public void notifyDisplayInfoChanged(int phoneId, int subId, 2014 @NonNull TelephonyDisplayInfo telephonyDisplayInfo) { 2015 if (!checkNotifyPermission("notifyDisplayInfoChanged()")) { 2016 return; 2017 } 2018 String str = "notifyDisplayInfoChanged: PhoneId=" + phoneId + " subId=" + subId 2019 + " telephonyDisplayInfo=" + telephonyDisplayInfo; 2020 if (VDBG) { 2021 log(str); 2022 } 2023 mLocalLog.log(str); 2024 synchronized (mRecords) { 2025 if (validatePhoneId(phoneId)) { 2026 mTelephonyDisplayInfos[phoneId] = telephonyDisplayInfo; 2027 for (Record r : mRecords) { 2028 if (r.matchTelephonyCallbackEvent( 2029 TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED) 2030 && idMatch(r, subId, phoneId)) { 2031 try { 2032 if (!mConfigurationProvider.isDisplayInfoNrAdvancedSupported( 2033 r.callingPackage, Binder.getCallingUserHandle())) { 2034 r.callback.onDisplayInfoChanged( 2035 getBackwardCompatibleTelephonyDisplayInfo( 2036 telephonyDisplayInfo)); 2037 } else { 2038 r.callback.onDisplayInfoChanged(telephonyDisplayInfo); 2039 } 2040 } catch (RemoteException ex) { 2041 mRemoveList.add(r.binder); 2042 } 2043 } 2044 } 2045 } 2046 handleRemoveListLocked(); 2047 } 2048 } 2049 getBackwardCompatibleTelephonyDisplayInfo( @onNull TelephonyDisplayInfo telephonyDisplayInfo)2050 private TelephonyDisplayInfo getBackwardCompatibleTelephonyDisplayInfo( 2051 @NonNull TelephonyDisplayInfo telephonyDisplayInfo) { 2052 int networkType = telephonyDisplayInfo.getNetworkType(); 2053 int overrideNetworkType = telephonyDisplayInfo.getOverrideNetworkType(); 2054 if (networkType == TelephonyManager.NETWORK_TYPE_NR) { 2055 overrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE; 2056 } else if (networkType == TelephonyManager.NETWORK_TYPE_LTE 2057 && overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED) { 2058 overrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE; 2059 } 2060 boolean isRoaming = telephonyDisplayInfo.isRoaming(); 2061 return new TelephonyDisplayInfo(networkType, overrideNetworkType, isRoaming); 2062 } 2063 notifyCallForwardingChanged(boolean cfi)2064 public void notifyCallForwardingChanged(boolean cfi) { 2065 notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi); 2066 } 2067 notifyCallForwardingChangedForSubscriber(int subId, boolean cfi)2068 public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) { 2069 if (!checkNotifyPermission("notifyCallForwardingChanged()")) { 2070 return; 2071 } 2072 if (VDBG) { 2073 log("notifyCallForwardingChangedForSubscriber: subId=" + subId 2074 + " cfi=" + cfi); 2075 } 2076 int phoneId = getPhoneIdFromSubId(subId); 2077 synchronized (mRecords) { 2078 if (validatePhoneId(phoneId)) { 2079 mCallForwarding[phoneId] = cfi; 2080 for (Record r : mRecords) { 2081 if (r.matchTelephonyCallbackEvent( 2082 TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED) 2083 && idMatch(r, subId, phoneId)) { 2084 try { 2085 r.callback.onCallForwardingIndicatorChanged(cfi); 2086 } catch (RemoteException ex) { 2087 mRemoveList.add(r.binder); 2088 } 2089 } 2090 } 2091 } 2092 handleRemoveListLocked(); 2093 } 2094 } 2095 notifyDataActivity(int state)2096 public void notifyDataActivity(int state) { 2097 notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state); 2098 } 2099 notifyDataActivityForSubscriber(int subId, int state)2100 public void notifyDataActivityForSubscriber(int subId, int state) { 2101 if (!checkNotifyPermission("notifyDataActivity()" )) { 2102 return; 2103 } 2104 int phoneId = getPhoneIdFromSubId(subId); 2105 synchronized (mRecords) { 2106 if (validatePhoneId(phoneId)) { 2107 mDataActivity[phoneId] = state; 2108 for (Record r : mRecords) { 2109 // Notify by correct subId. 2110 if (r.matchTelephonyCallbackEvent( 2111 TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED) 2112 && idMatch(r, subId, phoneId)) { 2113 try { 2114 r.callback.onDataActivity(state); 2115 } catch (RemoteException ex) { 2116 mRemoveList.add(r.binder); 2117 } 2118 } 2119 } 2120 } 2121 handleRemoveListLocked(); 2122 } 2123 } 2124 2125 /** 2126 * Send a notification to registrants that the data connection state has changed. 2127 * 2128 * @param phoneId the phoneId carrying the data connection 2129 * @param subId the subscriptionId for the data connection 2130 * @param preciseState a PreciseDataConnectionState that has info about the data connection 2131 */ 2132 @Override notifyDataConnectionForSubscriber(int phoneId, int subId, @NonNull PreciseDataConnectionState preciseState)2133 public void notifyDataConnectionForSubscriber(int phoneId, int subId, 2134 @NonNull PreciseDataConnectionState preciseState) { 2135 if (!checkNotifyPermission("notifyDataConnection()" )) { 2136 return; 2137 } 2138 2139 synchronized (mRecords) { 2140 if (validatePhoneId(phoneId) && preciseState.getApnSetting() != null) { 2141 Pair<Integer, ApnSetting> key = Pair.create(preciseState.getTransportType(), 2142 preciseState.getApnSetting()); 2143 PreciseDataConnectionState oldState = mPreciseDataConnectionStates.get(phoneId) 2144 .remove(key); 2145 if (!Objects.equals(oldState, preciseState)) { 2146 for (Record r : mRecords) { 2147 if (r.matchTelephonyCallbackEvent( 2148 TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED) 2149 && idMatch(r, subId, phoneId)) { 2150 try { 2151 r.callback.onPreciseDataConnectionStateChanged(preciseState); 2152 } catch (RemoteException ex) { 2153 mRemoveList.add(r.binder); 2154 } 2155 } 2156 } 2157 handleRemoveListLocked(); 2158 2159 broadcastDataConnectionStateChanged(phoneId, subId, preciseState); 2160 2161 String str = "notifyDataConnectionForSubscriber: phoneId=" + phoneId + " subId=" 2162 + subId + " " + preciseState; 2163 log(str); 2164 mLocalLog.log(str); 2165 } 2166 2167 // If the state is disconnected, it would be the end of life cycle of a data 2168 // connection, so remove it from the cache. 2169 if (preciseState.getState() != TelephonyManager.DATA_DISCONNECTED) { 2170 mPreciseDataConnectionStates.get(phoneId).put(key, preciseState); 2171 } 2172 2173 // Note that below is just the workaround for reporting the correct data connection 2174 // state. The actual fix should be put in the new data stack in T. 2175 // TODO: Remove the code below in T. 2176 2177 // Collect all possible candidate data connection state for internet. Key is the 2178 // data connection state, value is the precise data connection state. 2179 Map<Integer, PreciseDataConnectionState> internetConnections = new ArrayMap<>(); 2180 if (preciseState.getState() == TelephonyManager.DATA_DISCONNECTED 2181 && preciseState.getApnSetting().getApnTypes() 2182 .contains(ApnSetting.TYPE_DEFAULT)) { 2183 internetConnections.put(TelephonyManager.DATA_DISCONNECTED, preciseState); 2184 } 2185 for (Map.Entry<Pair<Integer, ApnSetting>, PreciseDataConnectionState> entry : 2186 mPreciseDataConnectionStates.get(phoneId).entrySet()) { 2187 if (entry.getKey().first == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 2188 && entry.getKey().second.getApnTypes() 2189 .contains(ApnSetting.TYPE_DEFAULT)) { 2190 internetConnections.put(entry.getValue().getState(), entry.getValue()); 2191 } 2192 } 2193 2194 // If any internet data is in connected state, then report connected, then check 2195 // suspended, connecting, disconnecting, and disconnected. The order is very 2196 // important. 2197 int[] statesInPriority = new int[]{TelephonyManager.DATA_CONNECTED, 2198 TelephonyManager.DATA_SUSPENDED, TelephonyManager.DATA_CONNECTING, 2199 TelephonyManager.DATA_DISCONNECTING, 2200 TelephonyManager.DATA_DISCONNECTED}; 2201 int state = TelephonyManager.DATA_DISCONNECTED; 2202 int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 2203 for (int s : statesInPriority) { 2204 if (internetConnections.containsKey(s)) { 2205 state = s; 2206 networkType = internetConnections.get(s).getNetworkType(); 2207 break; 2208 } 2209 } 2210 2211 if (mDataConnectionState[phoneId] != state 2212 || mDataConnectionNetworkType[phoneId] != networkType) { 2213 String str = "onDataConnectionStateChanged(" 2214 + TelephonyUtils.dataStateToString(state) 2215 + ", " + TelephonyManager.getNetworkTypeName(networkType) 2216 + ") subId=" + subId + ", phoneId=" + phoneId; 2217 log(str); 2218 mLocalLog.log(str); 2219 for (Record r : mRecords) { 2220 if (r.matchTelephonyCallbackEvent( 2221 TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED) 2222 && idMatch(r, subId, phoneId)) { 2223 try { 2224 if (DBG) { 2225 log("Notify data connection state changed on sub: " + subId); 2226 } 2227 r.callback.onDataConnectionStateChanged(state, networkType); 2228 } catch (RemoteException ex) { 2229 mRemoveList.add(r.binder); 2230 } 2231 } 2232 } 2233 2234 mDataConnectionState[phoneId] = state; 2235 mDataConnectionNetworkType[phoneId] = networkType; 2236 2237 handleRemoveListLocked(); 2238 } 2239 } 2240 } 2241 } 2242 2243 @Override notifyCellLocationForSubscriber(int subId, CellIdentity cellIdentity)2244 public void notifyCellLocationForSubscriber(int subId, CellIdentity cellIdentity) { 2245 notifyCellLocationForSubscriber(subId, cellIdentity, false /* hasUserSwitched */); 2246 } 2247 notifyCellLocationForSubscriber(int subId, CellIdentity cellIdentity, boolean hasUserSwitched)2248 private void notifyCellLocationForSubscriber(int subId, CellIdentity cellIdentity, 2249 boolean hasUserSwitched) { 2250 log("notifyCellLocationForSubscriber: subId=" + subId + " cellIdentity=" 2251 + Rlog.pii(DBG || VDBG || DBG_LOC, cellIdentity)); 2252 if (!checkNotifyPermission("notifyCellLocation()")) { 2253 return; 2254 } 2255 int phoneId = getPhoneIdFromSubId(subId); 2256 synchronized (mRecords) { 2257 if (validatePhoneId(phoneId) 2258 && (hasUserSwitched || !Objects.equals(cellIdentity, mCellIdentity[phoneId]))) { 2259 mCellIdentity[phoneId] = cellIdentity; 2260 for (Record r : mRecords) { 2261 if (validateEventAndUserLocked( 2262 r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED) 2263 && idMatch(r, subId, phoneId) 2264 && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) 2265 && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) { 2266 try { 2267 if (DBG_LOC) { 2268 log("notifyCellLocation: cellIdentity=" + cellIdentity 2269 + " r=" + r); 2270 } 2271 r.callback.onCellLocationChanged(cellIdentity); 2272 } catch (RemoteException ex) { 2273 mRemoveList.add(r.binder); 2274 } 2275 } 2276 } 2277 } 2278 handleRemoveListLocked(); 2279 } 2280 } 2281 2282 /** 2283 * Send a notification to registrants that the precise call state has changed. 2284 * 2285 * @param phoneId the phoneId carrying the data connection 2286 * @param subId the subscriptionId for the data connection 2287 * @param callStates Array of PreciseCallState of foreground, background & ringing calls. 2288 * @param imsCallIds Array of IMS call session ID{@link ImsCallSession#getCallId()} for 2289 * ringing, foreground & background calls. 2290 * @param imsServiceTypes Array of IMS call service type for ringing, foreground & 2291 * background calls. 2292 * @param imsCallTypes Array of IMS call type for ringing, foreground & background calls. 2293 */ notifyPreciseCallState(int phoneId, int subId, @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds, @Annotation.ImsCallServiceType int[] imsServiceTypes, @Annotation.ImsCallType int[] imsCallTypes)2294 public void notifyPreciseCallState(int phoneId, int subId, 2295 @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds, 2296 @Annotation.ImsCallServiceType int[] imsServiceTypes, 2297 @Annotation.ImsCallType int[] imsCallTypes) { 2298 if (!checkNotifyPermission("notifyPreciseCallState()")) { 2299 return; 2300 } 2301 2302 int ringingCallState = callStates[CallState.CALL_CLASSIFICATION_RINGING]; 2303 int foregroundCallState = callStates[CallState.CALL_CLASSIFICATION_FOREGROUND]; 2304 int backgroundCallState = callStates[CallState.CALL_CLASSIFICATION_BACKGROUND]; 2305 2306 synchronized (mRecords) { 2307 if (validatePhoneId(phoneId)) { 2308 boolean preciseCallStateChanged = false; 2309 mRingingCallState[phoneId] = ringingCallState; 2310 mForegroundCallState[phoneId] = foregroundCallState; 2311 mBackgroundCallState[phoneId] = backgroundCallState; 2312 PreciseCallState preciseCallState = new PreciseCallState( 2313 ringingCallState, foregroundCallState, 2314 backgroundCallState, 2315 DisconnectCause.NOT_VALID, 2316 PreciseDisconnectCause.NOT_VALID); 2317 if (!preciseCallState.equals(mPreciseCallState[phoneId])) { 2318 preciseCallStateChanged = true; 2319 mPreciseCallState[phoneId] = preciseCallState; 2320 } 2321 boolean notifyCallState = true; 2322 if (mCallQuality == null) { 2323 log("notifyPreciseCallState: mCallQuality is null, " 2324 + "skipping call attributes"); 2325 notifyCallState = false; 2326 } else { 2327 // If the precise call state is no longer active, reset the call network type 2328 // and call quality. 2329 if (mPreciseCallState[phoneId].getForegroundCallState() 2330 != PreciseCallState.PRECISE_CALL_STATE_ACTIVE) { 2331 mCallNetworkType[phoneId] = TelephonyManager.NETWORK_TYPE_UNKNOWN; 2332 mCallQuality[phoneId] = createCallQuality(); 2333 } 2334 List<CallState> prevCallStateList = new ArrayList<>(); 2335 prevCallStateList.addAll(mCallStateLists.get(phoneId)); 2336 mCallStateLists.get(phoneId).clear(); 2337 if (foregroundCallState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID 2338 && foregroundCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) { 2339 CallQuality callQuality = mCallQuality[phoneId]; 2340 CallState.Builder builder = new CallState.Builder( 2341 callStates[CallState.CALL_CLASSIFICATION_FOREGROUND]) 2342 .setNetworkType(mCallNetworkType[phoneId]) 2343 .setCallQuality(callQuality) 2344 .setCallClassification( 2345 CallState.CALL_CLASSIFICATION_FOREGROUND); 2346 if (imsCallIds != null && imsServiceTypes != null && imsCallTypes != null) { 2347 builder = builder 2348 .setImsCallSessionId(imsCallIds[ 2349 CallState.CALL_CLASSIFICATION_FOREGROUND]) 2350 .setImsCallServiceType(imsServiceTypes[ 2351 CallState.CALL_CLASSIFICATION_FOREGROUND]) 2352 .setImsCallType(imsCallTypes[ 2353 CallState.CALL_CLASSIFICATION_FOREGROUND]); 2354 } 2355 mCallStateLists.get(phoneId).add(builder.build()); 2356 } 2357 if (backgroundCallState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID 2358 && backgroundCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) { 2359 CallState.Builder builder = new CallState.Builder( 2360 callStates[CallState.CALL_CLASSIFICATION_BACKGROUND]) 2361 .setNetworkType(mCallNetworkType[phoneId]) 2362 .setCallQuality(createCallQuality()) 2363 .setCallClassification( 2364 CallState.CALL_CLASSIFICATION_BACKGROUND); 2365 if (imsCallIds != null && imsServiceTypes != null && imsCallTypes != null) { 2366 builder = builder 2367 .setImsCallSessionId(imsCallIds[ 2368 CallState.CALL_CLASSIFICATION_BACKGROUND]) 2369 .setImsCallServiceType(imsServiceTypes[ 2370 CallState.CALL_CLASSIFICATION_BACKGROUND]) 2371 .setImsCallType(imsCallTypes[ 2372 CallState.CALL_CLASSIFICATION_BACKGROUND]); 2373 } 2374 mCallStateLists.get(phoneId).add(builder.build()); 2375 } 2376 if (ringingCallState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID 2377 && ringingCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) { 2378 CallState.Builder builder = new CallState.Builder( 2379 callStates[CallState.CALL_CLASSIFICATION_RINGING]) 2380 .setNetworkType(mCallNetworkType[phoneId]) 2381 .setCallQuality(createCallQuality()) 2382 .setCallClassification( 2383 CallState.CALL_CLASSIFICATION_RINGING); 2384 if (imsCallIds != null && imsServiceTypes != null && imsCallTypes != null) { 2385 builder = builder 2386 .setImsCallSessionId(imsCallIds[ 2387 CallState.CALL_CLASSIFICATION_RINGING]) 2388 .setImsCallServiceType(imsServiceTypes[ 2389 CallState.CALL_CLASSIFICATION_RINGING]) 2390 .setImsCallType(imsCallTypes[ 2391 CallState.CALL_CLASSIFICATION_RINGING]); 2392 } 2393 mCallStateLists.get(phoneId).add(builder.build()); 2394 } 2395 if (prevCallStateList.equals(mCallStateLists.get(phoneId))) { 2396 notifyCallState = false; 2397 } 2398 boolean hasOngoingCall = false; 2399 for (CallState cs : mCallStateLists.get(phoneId)) { 2400 if (cs.getCallState() != PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED) { 2401 hasOngoingCall = true; 2402 break; 2403 } 2404 } 2405 if (!hasOngoingCall) { 2406 //no ongoing call. clear media quality status cached. 2407 mMediaQualityStatus.get(phoneId).clear(); 2408 } 2409 } 2410 2411 if (preciseCallStateChanged) { 2412 for (Record r : mRecords) { 2413 if (r.matchTelephonyCallbackEvent( 2414 TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED) 2415 && idMatch(r, subId, phoneId)) { 2416 try { 2417 r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]); 2418 } catch (RemoteException ex) { 2419 mRemoveList.add(r.binder); 2420 } 2421 } 2422 } 2423 } 2424 2425 if (notifyCallState) { 2426 for (Record r : mRecords) { 2427 if (r.matchTelephonyCallbackEvent( 2428 TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED) 2429 && idMatch(r, subId, phoneId)) { 2430 try { 2431 r.callback.onCallStatesChanged(mCallStateLists.get(phoneId)); 2432 } catch (RemoteException ex) { 2433 mRemoveList.add(r.binder); 2434 } 2435 } 2436 } 2437 } 2438 } 2439 handleRemoveListLocked(); 2440 } 2441 } 2442 notifyDisconnectCause(int phoneId, int subId, int disconnectCause, int preciseDisconnectCause)2443 public void notifyDisconnectCause(int phoneId, int subId, int disconnectCause, 2444 int preciseDisconnectCause) { 2445 if (!checkNotifyPermission("notifyDisconnectCause()")) { 2446 return; 2447 } 2448 synchronized (mRecords) { 2449 if (validatePhoneId(phoneId)) { 2450 mCallDisconnectCause[phoneId] = disconnectCause; 2451 mCallPreciseDisconnectCause[phoneId] = preciseDisconnectCause; 2452 for (Record r : mRecords) { 2453 if (r.matchTelephonyCallbackEvent( 2454 TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED) 2455 && idMatch(r, subId, phoneId)) { 2456 try { 2457 r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId], 2458 mCallPreciseDisconnectCause[phoneId]); 2459 } catch (RemoteException ex) { 2460 mRemoveList.add(r.binder); 2461 } 2462 } 2463 } 2464 } 2465 handleRemoveListLocked(); 2466 } 2467 } 2468 notifyImsDisconnectCause(int subId, ImsReasonInfo imsReasonInfo)2469 public void notifyImsDisconnectCause(int subId, ImsReasonInfo imsReasonInfo) { 2470 if (!checkNotifyPermission("notifyImsCallDisconnectCause()")) { 2471 return; 2472 } 2473 int phoneId = getPhoneIdFromSubId(subId); 2474 synchronized (mRecords) { 2475 if (validatePhoneId(phoneId)) { 2476 if (imsReasonInfo == null) { 2477 loge("ImsReasonInfo is null, subId=" + subId + ", phoneId=" + phoneId); 2478 mImsReasonInfo.set(phoneId, new ImsReasonInfo()); 2479 return; 2480 } 2481 mImsReasonInfo.set(phoneId, imsReasonInfo); 2482 for (Record r : mRecords) { 2483 if (r.matchTelephonyCallbackEvent( 2484 TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED) 2485 && idMatch(r, subId, phoneId)) { 2486 try { 2487 if (DBG_LOC) { 2488 log("notifyImsCallDisconnectCause: mImsReasonInfo=" 2489 + imsReasonInfo + " r=" + r); 2490 } 2491 r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId)); 2492 } catch (RemoteException ex) { 2493 mRemoveList.add(r.binder); 2494 } 2495 } 2496 } 2497 } 2498 handleRemoveListLocked(); 2499 } 2500 } 2501 2502 @Override notifySrvccStateChanged(int subId, @SrvccState int state)2503 public void notifySrvccStateChanged(int subId, @SrvccState int state) { 2504 if (!checkNotifyPermission("notifySrvccStateChanged()")) { 2505 return; 2506 } 2507 if (VDBG) { 2508 log("notifySrvccStateChanged: subId=" + subId + " srvccState=" + state); 2509 } 2510 int phoneId = getPhoneIdFromSubId(subId); 2511 synchronized (mRecords) { 2512 if (validatePhoneId(phoneId)) { 2513 mSrvccState[phoneId] = state; 2514 for (Record r : mRecords) { 2515 if (r.matchTelephonyCallbackEvent( 2516 TelephonyCallback.EVENT_SRVCC_STATE_CHANGED) 2517 && idMatch(r, subId, phoneId)) { 2518 try { 2519 if (DBG_LOC) { 2520 log("notifySrvccStateChanged: mSrvccState=" + state + " r=" + r); 2521 } 2522 r.callback.onSrvccStateChanged(state); 2523 } catch (RemoteException ex) { 2524 mRemoveList.add(r.binder); 2525 } 2526 } 2527 } 2528 } 2529 handleRemoveListLocked(); 2530 } 2531 } 2532 notifyOemHookRawEventForSubscriber(int phoneId, int subId, byte[] rawData)2533 public void notifyOemHookRawEventForSubscriber(int phoneId, int subId, byte[] rawData) { 2534 if (!checkNotifyPermission("notifyOemHookRawEventForSubscriber")) { 2535 return; 2536 } 2537 2538 synchronized (mRecords) { 2539 if (validatePhoneId(phoneId)) { 2540 for (Record r : mRecords) { 2541 if (VDBG) { 2542 log("notifyOemHookRawEventForSubscriber: r=" + r + " subId=" + subId); 2543 } 2544 if ((r.matchTelephonyCallbackEvent( 2545 TelephonyCallback.EVENT_OEM_HOOK_RAW)) 2546 && idMatch(r, subId, phoneId)) { 2547 try { 2548 r.callback.onOemHookRawEvent(rawData); 2549 } catch (RemoteException ex) { 2550 mRemoveList.add(r.binder); 2551 } 2552 } 2553 } 2554 } 2555 handleRemoveListLocked(); 2556 } 2557 } 2558 notifyPhoneCapabilityChanged(PhoneCapability capability)2559 public void notifyPhoneCapabilityChanged(PhoneCapability capability) { 2560 if (!checkNotifyPermission("notifyPhoneCapabilityChanged()")) { 2561 return; 2562 } 2563 2564 if (VDBG) { 2565 log("notifyPhoneCapabilityChanged: capability=" + capability); 2566 } 2567 2568 synchronized (mRecords) { 2569 mPhoneCapability = capability; 2570 2571 for (Record r : mRecords) { 2572 if (r.matchTelephonyCallbackEvent( 2573 TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED)) { 2574 try { 2575 r.callback.onPhoneCapabilityChanged(capability); 2576 } catch (RemoteException ex) { 2577 mRemoveList.add(r.binder); 2578 } 2579 } 2580 } 2581 handleRemoveListLocked(); 2582 } 2583 } 2584 notifyActiveDataSubIdChanged(int activeDataSubId)2585 public void notifyActiveDataSubIdChanged(int activeDataSubId) { 2586 if (!checkNotifyPermission("notifyActiveDataSubIdChanged()")) { 2587 return; 2588 } 2589 2590 log("notifyActiveDataSubIdChanged: activeDataSubId=" + activeDataSubId); 2591 mLocalLog.log("notifyActiveDataSubIdChanged: activeDataSubId=" + activeDataSubId); 2592 2593 mActiveDataSubId = activeDataSubId; 2594 synchronized (mRecords) { 2595 for (Record r : mRecords) { 2596 if (r.matchTelephonyCallbackEvent( 2597 TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) { 2598 try { 2599 r.callback.onActiveDataSubIdChanged(activeDataSubId); 2600 } catch (RemoteException ex) { 2601 mRemoveList.add(r.binder); 2602 } 2603 } 2604 } 2605 handleRemoveListLocked(); 2606 } 2607 } 2608 notifyRadioPowerStateChanged(int phoneId, int subId, @RadioPowerState int state)2609 public void notifyRadioPowerStateChanged(int phoneId, int subId, @RadioPowerState int state) { 2610 if (!checkNotifyPermission("notifyRadioPowerStateChanged()")) { 2611 return; 2612 } 2613 2614 if (VDBG) { 2615 log("notifyRadioPowerStateChanged: state= " + state + " subId=" + subId); 2616 } 2617 2618 synchronized (mRecords) { 2619 if (validatePhoneId(phoneId)) { 2620 mRadioPowerState = state; 2621 2622 for (Record r : mRecords) { 2623 if (r.matchTelephonyCallbackEvent( 2624 TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED) 2625 && idMatch(r, subId, phoneId)) { 2626 try { 2627 r.callback.onRadioPowerStateChanged(state); 2628 } catch (RemoteException ex) { 2629 mRemoveList.add(r.binder); 2630 } 2631 } 2632 } 2633 2634 } 2635 handleRemoveListLocked(); 2636 } 2637 } 2638 2639 @Override notifyEmergencyNumberList(int phoneId, int subId)2640 public void notifyEmergencyNumberList(int phoneId, int subId) { 2641 if (!checkNotifyPermission("notifyEmergencyNumberList()")) { 2642 return; 2643 } 2644 2645 synchronized (mRecords) { 2646 if (validatePhoneId(phoneId)) { 2647 TelephonyManager tm = (TelephonyManager) mContext.getSystemService( 2648 Context.TELEPHONY_SERVICE); 2649 mEmergencyNumberList = tm.getEmergencyNumberList(); 2650 2651 for (Record r : mRecords) { 2652 if (r.matchTelephonyCallbackEvent( 2653 TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED) 2654 && idMatch(r, subId, phoneId)) { 2655 try { 2656 r.callback.onEmergencyNumberListChanged(mEmergencyNumberList); 2657 if (VDBG) { 2658 log("notifyEmergencyNumberList: emergencyNumberList= " 2659 + mEmergencyNumberList); 2660 } 2661 } catch (RemoteException ex) { 2662 mRemoveList.add(r.binder); 2663 } 2664 } 2665 } 2666 } 2667 2668 handleRemoveListLocked(); 2669 } 2670 } 2671 2672 @Override notifyOutgoingEmergencyCall(int phoneId, int subId, EmergencyNumber emergencyNumber)2673 public void notifyOutgoingEmergencyCall(int phoneId, int subId, 2674 EmergencyNumber emergencyNumber) { 2675 if (!checkNotifyPermission("notifyOutgoingEmergencyCall()")) { 2676 return; 2677 } 2678 synchronized (mRecords) { 2679 if (validatePhoneId(phoneId)) { 2680 mOutgoingCallEmergencyNumber[phoneId] = emergencyNumber; 2681 } 2682 for (Record r : mRecords) { 2683 // Send to all listeners regardless of subscription 2684 if (r.matchTelephonyCallbackEvent( 2685 TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL)) { 2686 try { 2687 r.callback.onOutgoingEmergencyCall(emergencyNumber, subId); 2688 } catch (RemoteException ex) { 2689 mRemoveList.add(r.binder); 2690 } 2691 } 2692 } 2693 } 2694 handleRemoveListLocked(); 2695 } 2696 2697 @Override notifyOutgoingEmergencySms(int phoneId, int subId, EmergencyNumber emergencyNumber)2698 public void notifyOutgoingEmergencySms(int phoneId, int subId, 2699 EmergencyNumber emergencyNumber) { 2700 if (!checkNotifyPermission("notifyOutgoingEmergencySms()")) { 2701 return; 2702 } 2703 2704 synchronized (mRecords) { 2705 if (validatePhoneId(phoneId)) { 2706 mOutgoingSmsEmergencyNumber[phoneId] = emergencyNumber; 2707 for (Record r : mRecords) { 2708 // Send to all listeners regardless of subscription 2709 if (r.matchTelephonyCallbackEvent( 2710 TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS)) { 2711 try { 2712 r.callback.onOutgoingEmergencySms(emergencyNumber, subId); 2713 } catch (RemoteException ex) { 2714 mRemoveList.add(r.binder); 2715 } 2716 } 2717 } 2718 } 2719 handleRemoveListLocked(); 2720 } 2721 } 2722 2723 @Override notifyCallQualityChanged(CallQuality callQuality, int phoneId, int subId, int callNetworkType)2724 public void notifyCallQualityChanged(CallQuality callQuality, int phoneId, int subId, 2725 int callNetworkType) { 2726 if (!checkNotifyPermission("notifyCallQualityChanged()")) { 2727 return; 2728 } 2729 2730 synchronized (mRecords) { 2731 if (validatePhoneId(phoneId)) { 2732 // merge CallQuality with PreciseCallState and network type 2733 mCallQuality[phoneId] = callQuality; 2734 mCallNetworkType[phoneId] = callNetworkType; 2735 if (mCallStateLists.get(phoneId).size() > 0 2736 && mCallStateLists.get(phoneId).get(0).getCallState() 2737 == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) { 2738 CallState prev = mCallStateLists.get(phoneId).remove(0); 2739 mCallStateLists.get(phoneId).add( 2740 0, new CallState.Builder(prev.getCallState()) 2741 .setNetworkType(callNetworkType) 2742 .setCallQuality(callQuality) 2743 .setCallClassification(prev.getCallClassification()) 2744 .setImsCallSessionId(prev.getImsCallSessionId()) 2745 .setImsCallServiceType(prev.getImsCallServiceType()) 2746 .setImsCallType(prev.getImsCallType()).build()); 2747 } else { 2748 log("There is no active call to report CallQuality"); 2749 return; 2750 } 2751 2752 for (Record r : mRecords) { 2753 if (r.matchTelephonyCallbackEvent( 2754 TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED) 2755 && idMatch(r, subId, phoneId)) { 2756 try { 2757 r.callback.onCallStatesChanged(mCallStateLists.get(phoneId)); 2758 } catch (RemoteException ex) { 2759 mRemoveList.add(r.binder); 2760 } 2761 } 2762 } 2763 } 2764 handleRemoveListLocked(); 2765 } 2766 } 2767 2768 @Override notifyRegistrationFailed(int phoneId, int subId, @NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode)2769 public void notifyRegistrationFailed(int phoneId, int subId, @NonNull CellIdentity cellIdentity, 2770 @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode) { 2771 if (!checkNotifyPermission("notifyRegistrationFailed()")) { 2772 return; 2773 } 2774 2775 // In case callers don't have fine location access, pre-construct a location-free version 2776 // of the CellIdentity. This will still have the PLMN ID, which should be sufficient for 2777 // most purposes. 2778 final CellIdentity noLocationCi = cellIdentity.sanitizeLocationInfo(); 2779 2780 2781 // This shouldn't be necessary, but better to not take the chance 2782 final String primaryPlmn = (cellIdentity != null) ? cellIdentity.getPlmn() : "<UNKNOWN>"; 2783 2784 final String logStr = "Registration Failed for phoneId=" + phoneId 2785 + " subId=" + subId + "primaryPlmn=" + primaryPlmn 2786 + " chosenPlmn=" + chosenPlmn + " domain=" + domain 2787 + " causeCode=" + causeCode + " additionalCauseCode=" + additionalCauseCode; 2788 2789 mLocalLog.log(logStr); 2790 if (DBG) log(logStr); 2791 2792 synchronized (mRecords) { 2793 if (validatePhoneId(phoneId)) { 2794 for (Record r : mRecords) { 2795 if (r.matchTelephonyCallbackEvent( 2796 TelephonyCallback.EVENT_REGISTRATION_FAILURE) 2797 && idMatch(r, subId, phoneId)) { 2798 try { 2799 r.callback.onRegistrationFailed( 2800 checkFineLocationAccess(r, Build.VERSION_CODES.BASE) 2801 ? cellIdentity : noLocationCi, 2802 chosenPlmn, domain, causeCode, 2803 additionalCauseCode); 2804 } catch (RemoteException ex) { 2805 mRemoveList.add(r.binder); 2806 } 2807 } 2808 } 2809 } 2810 handleRemoveListLocked(); 2811 } 2812 } 2813 2814 /** 2815 * Send a notification of changes to barring status to PhoneStateListener registrants. 2816 * 2817 * @param phoneId the phoneId 2818 * @param subId the subId 2819 * @param barringInfo a structure containing the complete updated barring info. 2820 */ notifyBarringInfoChanged(int phoneId, int subId, @NonNull BarringInfo barringInfo)2821 public void notifyBarringInfoChanged(int phoneId, int subId, @NonNull BarringInfo barringInfo) { 2822 if (!checkNotifyPermission("notifyBarringInfo()")) { 2823 return; 2824 } 2825 if (!validatePhoneId(phoneId)) { 2826 loge("Received invalid phoneId for BarringInfo = " + phoneId); 2827 return; 2828 } 2829 2830 synchronized (mRecords) { 2831 if (barringInfo == null) { 2832 loge("Received null BarringInfo for subId=" + subId + ", phoneId=" + phoneId); 2833 mBarringInfo.set(phoneId, new BarringInfo()); 2834 return; 2835 } 2836 if (barringInfo.equals(mBarringInfo.get(phoneId))) { 2837 if (VDBG) log("Ignoring duplicate barring info."); 2838 return; 2839 } 2840 mBarringInfo.set(phoneId, barringInfo); 2841 // Barring info is non-null 2842 BarringInfo biNoLocation = barringInfo.createLocationInfoSanitizedCopy(); 2843 if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo); 2844 for (Record r : mRecords) { 2845 if (r.matchTelephonyCallbackEvent( 2846 TelephonyCallback.EVENT_BARRING_INFO_CHANGED) 2847 && idMatch(r, subId, phoneId)) { 2848 try { 2849 if (DBG_LOC) { 2850 log("notifyBarringInfo: mBarringInfo=" 2851 + barringInfo + " r=" + r); 2852 } 2853 r.callback.onBarringInfoChanged( 2854 checkFineLocationAccess(r, Build.VERSION_CODES.BASE) 2855 ? barringInfo : biNoLocation); 2856 } catch (RemoteException ex) { 2857 mRemoveList.add(r.binder); 2858 } 2859 } 2860 } 2861 handleRemoveListLocked(); 2862 } 2863 } 2864 2865 /** 2866 * Send a notification to registrants that the configs of physical channel has changed for 2867 * a particular subscription. 2868 * 2869 * @param phoneId the phone id. 2870 * @param subId the subId 2871 * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel. 2872 */ notifyPhysicalChannelConfigForSubscriber(int phoneId, int subId, List<PhysicalChannelConfig> configs)2873 public void notifyPhysicalChannelConfigForSubscriber(int phoneId, int subId, 2874 List<PhysicalChannelConfig> configs) { 2875 if (!checkNotifyPermission("notifyPhysicalChannelConfig()")) { 2876 return; 2877 } 2878 2879 List<PhysicalChannelConfig> sanitizedConfigs = getLocationSanitizedConfigs(configs); 2880 if (VDBG) { 2881 log("notifyPhysicalChannelConfig: subId=" + subId + " configs=" + configs 2882 + " sanitizedConfigs=" + sanitizedConfigs); 2883 } 2884 2885 synchronized (mRecords) { 2886 if (validatePhoneId(phoneId)) { 2887 mPhysicalChannelConfigs.set(phoneId, configs); 2888 for (Record r : mRecords) { 2889 if (r.matchTelephonyCallbackEvent( 2890 TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED) 2891 && idMatch(r, subId, phoneId)) { 2892 try { 2893 if (DBG_LOC) { 2894 log("notifyPhysicalChannelConfig: mPhysicalChannelConfigs=" 2895 + (shouldSanitizeLocationForPhysicalChannelConfig(r) 2896 ? sanitizedConfigs : configs) 2897 + " r=" + r); 2898 } 2899 r.callback.onPhysicalChannelConfigChanged( 2900 shouldSanitizeLocationForPhysicalChannelConfig(r) 2901 ? sanitizedConfigs : configs); 2902 } catch (RemoteException ex) { 2903 mRemoveList.add(r.binder); 2904 } 2905 } 2906 } 2907 } 2908 handleRemoveListLocked(); 2909 } 2910 } 2911 shouldSanitizeLocationForPhysicalChannelConfig(Record record)2912 private static boolean shouldSanitizeLocationForPhysicalChannelConfig(Record record) { 2913 // Always redact location info from PhysicalChannelConfig if the registrant is from neither 2914 // PHONE nor SYSTEM process. There is no user case that the registrant needs the location 2915 // info (e.g. physicalCellId). This also remove the need for the location permissions check. 2916 return record.callerUid != Process.PHONE_UID && record.callerUid != Process.SYSTEM_UID; 2917 } 2918 2919 /** 2920 * Return a copy of the PhysicalChannelConfig list but with location info removed. 2921 */ getLocationSanitizedConfigs( List<PhysicalChannelConfig> configs)2922 private static List<PhysicalChannelConfig> getLocationSanitizedConfigs( 2923 List<PhysicalChannelConfig> configs) { 2924 List<PhysicalChannelConfig> sanitizedConfigs = new ArrayList<>(configs.size()); 2925 for (PhysicalChannelConfig config : configs) { 2926 sanitizedConfigs.add(config.createLocationInfoSanitizedCopy()); 2927 } 2928 return sanitizedConfigs; 2929 } 2930 2931 /** 2932 * Notify that the data enabled has changed. 2933 * 2934 * @param phoneId the phone id. 2935 * @param subId the subId. 2936 * @param enabled True if data is enabled, otherwise disabled. 2937 * @param reason Reason for data enabled/disabled. See {@code DATA_*} in 2938 * {@link TelephonyManager}. 2939 */ notifyDataEnabled(int phoneId, int subId, boolean enabled, @TelephonyManager.DataEnabledReason int reason)2940 public void notifyDataEnabled(int phoneId, int subId, boolean enabled, 2941 @TelephonyManager.DataEnabledReason int reason) { 2942 if (!checkNotifyPermission("notifyDataEnabled()")) { 2943 return; 2944 } 2945 2946 if (VDBG) { 2947 log("notifyDataEnabled: PhoneId=" + phoneId + " subId=" + subId + 2948 " enabled=" + enabled + " reason=" + reason); 2949 } 2950 2951 synchronized (mRecords) { 2952 if (validatePhoneId(phoneId)) { 2953 mIsDataEnabled[phoneId] = enabled; 2954 mDataEnabledReason[phoneId] = reason; 2955 for (Record r : mRecords) { 2956 if (r.matchTelephonyCallbackEvent( 2957 TelephonyCallback.EVENT_DATA_ENABLED_CHANGED) 2958 && idMatch(r, subId, phoneId)) { 2959 try { 2960 r.callback.onDataEnabledChanged(enabled, reason); 2961 } catch (RemoteException ex) { 2962 mRemoveList.add(r.binder); 2963 } 2964 } 2965 } 2966 } 2967 handleRemoveListLocked(); 2968 } 2969 } 2970 2971 /** 2972 * Notify that the allowed network type has changed. 2973 * 2974 * @param phoneId the phone id. 2975 * @param subId the subId. 2976 * @param reason the allowed network type reason. 2977 * @param allowedNetworkType the allowed network type value. 2978 */ notifyAllowedNetworkTypesChanged(int phoneId, int subId, int reason, long allowedNetworkType)2979 public void notifyAllowedNetworkTypesChanged(int phoneId, int subId, int reason, 2980 long allowedNetworkType) { 2981 if (!checkNotifyPermission("notifyAllowedNetworkTypesChanged()")) { 2982 return; 2983 } 2984 2985 synchronized (mRecords) { 2986 if (validatePhoneId(phoneId)) { 2987 mAllowedNetworkTypeReason[phoneId] = reason; 2988 mAllowedNetworkTypeValue[phoneId] = allowedNetworkType; 2989 2990 for (Record r : mRecords) { 2991 if (r.matchTelephonyCallbackEvent( 2992 TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED) 2993 && idMatch(r, subId, phoneId)) { 2994 try { 2995 if (VDBG) { 2996 log("notifyAllowedNetworkTypesChanged: reason= " + reason 2997 + ", allowed network type:" 2998 + TelephonyManager.convertNetworkTypeBitmaskToString( 2999 allowedNetworkType)); 3000 } 3001 r.callback.onAllowedNetworkTypesChanged(reason, allowedNetworkType); 3002 } catch (RemoteException ex) { 3003 mRemoveList.add(r.binder); 3004 } 3005 } 3006 } 3007 } 3008 handleRemoveListLocked(); 3009 } 3010 } 3011 3012 /** 3013 * Notify that the link capacity estimate has changed. 3014 * @param phoneId the phone id. 3015 * @param subId the subscription id. 3016 * @param linkCapacityEstimateList a list of {@link LinkCapacityEstimate} 3017 */ notifyLinkCapacityEstimateChanged(int phoneId, int subId, List<LinkCapacityEstimate> linkCapacityEstimateList)3018 public void notifyLinkCapacityEstimateChanged(int phoneId, int subId, 3019 List<LinkCapacityEstimate> linkCapacityEstimateList) { 3020 if (!checkNotifyPermission("notifyLinkCapacityEstimateChanged()")) { 3021 return; 3022 } 3023 3024 if (VDBG) { 3025 log("notifyLinkCapacityEstimateChanged: linkCapacityEstimateList =" 3026 + linkCapacityEstimateList); 3027 } 3028 3029 synchronized (mRecords) { 3030 if (validatePhoneId(phoneId)) { 3031 mLinkCapacityEstimateLists.set(phoneId, linkCapacityEstimateList); 3032 for (Record r : mRecords) { 3033 if (r.matchTelephonyCallbackEvent( 3034 TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED) 3035 && idMatch(r, subId, phoneId)) { 3036 try { 3037 r.callback.onLinkCapacityEstimateChanged(linkCapacityEstimateList); 3038 } catch (RemoteException ex) { 3039 mRemoveList.add(r.binder); 3040 } 3041 } 3042 } 3043 } 3044 handleRemoveListLocked(); 3045 } 3046 } 3047 3048 @Override addCarrierPrivilegesCallback( int phoneId, @NonNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage, @NonNull String callingFeatureId)3049 public void addCarrierPrivilegesCallback( 3050 int phoneId, 3051 @NonNull ICarrierPrivilegesCallback callback, 3052 @NonNull String callingPackage, 3053 @NonNull String callingFeatureId) { 3054 int callerUserId = UserHandle.getCallingUserId(); 3055 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 3056 mContext.enforceCallingOrSelfPermission( 3057 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 3058 "addCarrierPrivilegesCallback"); 3059 if (VDBG) { 3060 log( 3061 "listen carrier privs: E pkg=" + pii(callingPackage) + " phoneId=" + phoneId 3062 + " uid=" + Binder.getCallingUid() 3063 + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId 3064 + " callback=" + callback 3065 + " callback.asBinder=" + callback.asBinder()); 3066 } 3067 3068 // In case this is triggered from the caller who has handled multiple SIM config change 3069 // firstly, we need to update the status (mNumPhone and mCarrierPrivilegeStates) firstly. 3070 // This is almost a no-op if there is no multiple SIM config change in advance. 3071 onMultiSimConfigChanged(); 3072 3073 synchronized (mRecords) { 3074 if (!validatePhoneId(phoneId)) { 3075 throw new IllegalArgumentException("Invalid slot index: " + phoneId); 3076 } 3077 Record r = add( 3078 callback.asBinder(), Binder.getCallingUid(), Binder.getCallingPid(), false); 3079 3080 if (r == null) return; 3081 3082 r.context = mContext; 3083 r.carrierPrivilegesCallback = callback; 3084 r.callingPackage = callingPackage; 3085 r.callingFeatureId = callingFeatureId; 3086 r.callerUid = Binder.getCallingUid(); 3087 r.callerPid = Binder.getCallingPid(); 3088 r.phoneId = phoneId; 3089 r.eventList = new ArraySet<>(); 3090 if (DBG) { 3091 log("listen carrier privs: Register r=" + r); 3092 } 3093 3094 Pair<List<String>, int[]> state = mCarrierPrivilegeStates.get(phoneId); 3095 Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(phoneId); 3096 try { 3097 if (r.matchCarrierPrivilegesCallback()) { 3098 // Here, two callbacks are triggered in quick succession on the same binder. 3099 // In typical case, we expect the callers to care about only one or the other. 3100 r.carrierPrivilegesCallback.onCarrierPrivilegesChanged( 3101 Collections.unmodifiableList(state.first), 3102 Arrays.copyOf(state.second, state.second.length)); 3103 3104 r.carrierPrivilegesCallback.onCarrierServiceChanged(carrierServiceState.first, 3105 carrierServiceState.second); 3106 } 3107 } catch (RemoteException ex) { 3108 remove(r.binder); 3109 } 3110 } 3111 } 3112 3113 @Override removeCarrierPrivilegesCallback( @onNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage)3114 public void removeCarrierPrivilegesCallback( 3115 @NonNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage) { 3116 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 3117 mContext.enforceCallingOrSelfPermission( 3118 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 3119 "removeCarrierPrivilegesCallback"); 3120 remove(callback.asBinder()); 3121 } 3122 3123 @Override notifyCarrierPrivilegesChanged( int phoneId, List<String> privilegedPackageNames, int[] privilegedUids)3124 public void notifyCarrierPrivilegesChanged( 3125 int phoneId, List<String> privilegedPackageNames, int[] privilegedUids) { 3126 if (!checkNotifyPermission("notifyCarrierPrivilegesChanged")) { 3127 return; 3128 } 3129 if (VDBG) { 3130 log( 3131 "notifyCarrierPrivilegesChanged: phoneId=" + phoneId 3132 + ", <packages=" + pii(privilegedPackageNames) 3133 + ", uids=" + Arrays.toString(privilegedUids) + ">"); 3134 } 3135 3136 // In case this is triggered from the caller who has handled multiple SIM config change 3137 // firstly, we need to update the status (mNumPhone and mCarrierPrivilegeStates) firstly. 3138 // This is almost a no-op if there is no multiple SIM config change in advance. 3139 onMultiSimConfigChanged(); 3140 3141 synchronized (mRecords) { 3142 if (!validatePhoneId(phoneId)) { 3143 throw new IllegalArgumentException("Invalid slot index: " + phoneId); 3144 } 3145 mCarrierPrivilegeStates.set( 3146 phoneId, new Pair<>(privilegedPackageNames, privilegedUids)); 3147 for (Record r : mRecords) { 3148 // Listeners are per-slot, not per-subscription. This is to provide a stable 3149 // view across SIM profile switches. 3150 if (!r.matchCarrierPrivilegesCallback() 3151 || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) { 3152 continue; 3153 } 3154 try { 3155 // Make sure even in-process listeners can't modify the values. 3156 r.carrierPrivilegesCallback.onCarrierPrivilegesChanged( 3157 Collections.unmodifiableList(privilegedPackageNames), 3158 Arrays.copyOf(privilegedUids, privilegedUids.length)); 3159 } catch (RemoteException ex) { 3160 mRemoveList.add(r.binder); 3161 } 3162 } 3163 handleRemoveListLocked(); 3164 } 3165 } 3166 3167 @Override notifyCarrierServiceChanged(int phoneId, @Nullable String packageName, int uid)3168 public void notifyCarrierServiceChanged(int phoneId, @Nullable String packageName, int uid) { 3169 if (!checkNotifyPermission("notifyCarrierServiceChanged")) return; 3170 if (!validatePhoneId(phoneId)) return; 3171 if (VDBG) { 3172 log("notifyCarrierServiceChanged: phoneId=" + phoneId 3173 + ", package=" + pii(packageName) + ", uid=" + uid); 3174 } 3175 3176 // In case this is triggered from the caller who has handled multiple SIM config change 3177 // firstly, we need to update the status (mNumPhone and mCarrierServiceStates) firstly. 3178 // This is almost a no-op if there is no multiple SIM config change in advance. 3179 onMultiSimConfigChanged(); 3180 3181 synchronized (mRecords) { 3182 mCarrierServiceStates.set( 3183 phoneId, new Pair<>(packageName, uid)); 3184 for (Record r : mRecords) { 3185 // Listeners are per-slot, not per-subscription. 3186 if (!r.matchCarrierPrivilegesCallback() 3187 || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) { 3188 continue; 3189 } 3190 try { 3191 r.carrierPrivilegesCallback.onCarrierServiceChanged(packageName, uid); 3192 } catch (RemoteException ex) { 3193 mRemoveList.add(r.binder); 3194 } 3195 } 3196 handleRemoveListLocked(); 3197 } 3198 } 3199 3200 @Override addCarrierConfigChangeListener(ICarrierConfigChangeListener listener, String pkg, String featureId)3201 public void addCarrierConfigChangeListener(ICarrierConfigChangeListener listener, 3202 String pkg, String featureId) { 3203 final int callerUserId = UserHandle.getCallingUserId(); 3204 mAppOps.checkPackage(Binder.getCallingUid(), pkg); 3205 if (VDBG) { 3206 log("addCarrierConfigChangeListener pkg=" + pii(pkg) + " uid=" + Binder.getCallingUid() 3207 + " myUserId=" + UserHandle.myUserId() + " callerUerId" + callerUserId 3208 + " listener=" + listener + " listener.asBinder=" + listener.asBinder()); 3209 } 3210 3211 synchronized (mRecords) { 3212 IBinder b = listener.asBinder(); 3213 boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(), 3214 Process.myUid()); 3215 Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); 3216 3217 if (r == null) { 3218 loge("Can not create Record instance!"); 3219 return; 3220 } 3221 3222 r.context = mContext; 3223 r.carrierConfigChangeListener = listener; 3224 r.callingPackage = pkg; 3225 r.callingFeatureId = featureId; 3226 r.callerUid = Binder.getCallingUid(); 3227 r.callerPid = Binder.getCallingPid(); 3228 r.eventList = new ArraySet<>(); 3229 if (DBG) { 3230 log("addCarrierConfigChangeListener: Register r=" + r); 3231 } 3232 } 3233 } 3234 3235 @Override removeCarrierConfigChangeListener(ICarrierConfigChangeListener listener, String pkg)3236 public void removeCarrierConfigChangeListener(ICarrierConfigChangeListener listener, 3237 String pkg) { 3238 if (DBG) log("removeCarrierConfigChangeListener listener=" + listener + ", pkg=" + pkg); 3239 mAppOps.checkPackage(Binder.getCallingUid(), pkg); 3240 remove(listener.asBinder()); 3241 } 3242 3243 @Override notifyCarrierConfigChanged(int phoneId, int subId, int carrierId, int specificCarrierId)3244 public void notifyCarrierConfigChanged(int phoneId, int subId, int carrierId, 3245 int specificCarrierId) { 3246 if (!validatePhoneId(phoneId)) { 3247 throw new IllegalArgumentException("Invalid phoneId: " + phoneId); 3248 } 3249 if (!checkNotifyPermission("notifyCarrierConfigChanged")) { 3250 loge("Caller has no notify permission!"); 3251 return; 3252 } 3253 if (VDBG) { 3254 log("notifyCarrierConfigChanged: phoneId=" + phoneId + ", subId=" + subId 3255 + ", carrierId=" + carrierId + ", specificCarrierId=" + specificCarrierId); 3256 } 3257 3258 synchronized (mRecords) { 3259 mRemoveList.clear(); 3260 for (Record r : mRecords) { 3261 // Listeners are "global", neither per-slot nor per-sub, so no idMatch check here 3262 if (!r.matchCarrierConfigChangeListener()) { 3263 continue; 3264 } 3265 try { 3266 r.carrierConfigChangeListener.onCarrierConfigChanged(phoneId, subId, carrierId, 3267 specificCarrierId); 3268 } catch (RemoteException re) { 3269 mRemoveList.add(r.binder); 3270 } 3271 } 3272 handleRemoveListLocked(); 3273 } 3274 } 3275 3276 @Override notifyMediaQualityStatusChanged(int phoneId, int subId, MediaQualityStatus status)3277 public void notifyMediaQualityStatusChanged(int phoneId, int subId, MediaQualityStatus status) { 3278 if (!checkNotifyPermission("notifyMediaQualityStatusChanged()")) { 3279 return; 3280 } 3281 3282 synchronized (mRecords) { 3283 if (validatePhoneId(phoneId)) { 3284 if (mCallStateLists.get(phoneId).size() > 0) { 3285 CallState callState = null; 3286 for (CallState cs : mCallStateLists.get(phoneId)) { 3287 if (cs.getCallState() == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) { 3288 callState = cs; 3289 break; 3290 } 3291 } 3292 if (callState != null) { 3293 String callSessionId = callState.getImsCallSessionId(); 3294 if (callSessionId != null 3295 && callSessionId.equals(status.getCallSessionId())) { 3296 mMediaQualityStatus.get(phoneId) 3297 .put(status.getMediaSessionType(), status); 3298 } else { 3299 log("SessionId mismatch active call:" + callSessionId 3300 + " media quality:" + status.getCallSessionId()); 3301 return; 3302 } 3303 } else { 3304 log("There is no active call to report CallQaulity"); 3305 return; 3306 } 3307 } 3308 3309 for (Record r : mRecords) { 3310 if (r.matchTelephonyCallbackEvent( 3311 TelephonyCallback.EVENT_MEDIA_QUALITY_STATUS_CHANGED) 3312 && idMatch(r, subId, phoneId)) { 3313 try { 3314 r.callback.onMediaQualityStatusChanged(status); 3315 } catch (RemoteException ex) { 3316 mRemoveList.add(r.binder); 3317 } 3318 } 3319 } 3320 } 3321 handleRemoveListLocked(); 3322 } 3323 } 3324 3325 @Override notifyCallbackModeStarted(int phoneId, int subId, int type)3326 public void notifyCallbackModeStarted(int phoneId, int subId, int type) { 3327 if (!checkNotifyPermission("notifyCallbackModeStarted()")) { 3328 return; 3329 } 3330 if (VDBG) { 3331 log("notifyCallbackModeStarted: phoneId=" + phoneId + ", subId=" + subId 3332 + ", type=" + type); 3333 } 3334 synchronized (mRecords) { 3335 if (validatePhoneId(phoneId)) { 3336 if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL) { 3337 mECBMStarted[phoneId] = true; 3338 } else if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS) { 3339 mSCBMStarted[phoneId] = true; 3340 } 3341 } 3342 for (Record r : mRecords) { 3343 // Send to all listeners regardless of subscription 3344 if (r.matchTelephonyCallbackEvent( 3345 TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) { 3346 try { 3347 r.callback.onCallBackModeStarted(type); 3348 } catch (RemoteException ex) { 3349 mRemoveList.add(r.binder); 3350 } 3351 } 3352 } 3353 } 3354 handleRemoveListLocked(); 3355 } 3356 3357 @Override notifyCallbackModeStopped(int phoneId, int subId, int type, int reason)3358 public void notifyCallbackModeStopped(int phoneId, int subId, int type, int reason) { 3359 if (!checkNotifyPermission("notifyCallbackModeStopped()")) { 3360 return; 3361 } 3362 if (VDBG) { 3363 log("notifyCallbackModeStopped: phoneId=" + phoneId + ", subId=" + subId 3364 + ", type=" + type + ", reason=" + reason); 3365 } 3366 synchronized (mRecords) { 3367 if (validatePhoneId(phoneId)) { 3368 if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL) { 3369 mECBMStarted[phoneId] = false; 3370 mECBMReason[phoneId] = reason; 3371 } else if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS) { 3372 mSCBMStarted[phoneId] = false; 3373 mSCBMReason[phoneId] = reason; 3374 } 3375 } 3376 for (Record r : mRecords) { 3377 // Send to all listeners regardless of subscription 3378 if (r.matchTelephonyCallbackEvent( 3379 TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) { 3380 try { 3381 r.callback.onCallBackModeStopped(type, reason); 3382 } catch (RemoteException ex) { 3383 mRemoveList.add(r.binder); 3384 } 3385 } 3386 } 3387 } 3388 handleRemoveListLocked(); 3389 } 3390 3391 @NeverCompile // Avoid size overhead of debugging code. 3392 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)3393 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 3394 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 3395 3396 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 3397 3398 synchronized (mRecords) { 3399 final int recordCount = mRecords.size(); 3400 pw.println("last known state:"); 3401 pw.increaseIndent(); 3402 for (int i = 0; i < getTelephonyManager().getActiveModemCount(); i++) { 3403 pw.println("Phone Id=" + i); 3404 pw.increaseIndent(); 3405 pw.println("mCallState=" + mCallState[i]); 3406 pw.println("mRingingCallState=" + mRingingCallState[i]); 3407 pw.println("mForegroundCallState=" + mForegroundCallState[i]); 3408 pw.println("mBackgroundCallState=" + mBackgroundCallState[i]); 3409 pw.println("mPreciseCallState=" + mPreciseCallState[i]); 3410 pw.println("mCallDisconnectCause=" + mCallDisconnectCause[i]); 3411 pw.println("mCallIncomingNumber=" + mCallIncomingNumber[i]); 3412 pw.println("mServiceState=" + mServiceState[i]); 3413 pw.println("mVoiceActivationState= " + mVoiceActivationState[i]); 3414 pw.println("mDataActivationState= " + mDataActivationState[i]); 3415 pw.println("mUserMobileDataState= " + mUserMobileDataState[i]); 3416 pw.println("mSignalStrength=" + mSignalStrength[i]); 3417 pw.println("mMessageWaiting=" + mMessageWaiting[i]); 3418 pw.println("mCallForwarding=" + mCallForwarding[i]); 3419 pw.println("mDataActivity=" + mDataActivity[i]); 3420 pw.println("mDataConnectionState=" + mDataConnectionState[i]); 3421 pw.println("mCellIdentity=" + mCellIdentity[i]); 3422 pw.println("mCellInfo=" + mCellInfo.get(i)); 3423 pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i)); 3424 pw.println("mSrvccState=" + mSrvccState[i]); 3425 pw.println("mCallPreciseDisconnectCause=" + mCallPreciseDisconnectCause[i]); 3426 pw.println("mCallQuality=" + mCallQuality[i]); 3427 pw.println("mCallNetworkType=" + mCallNetworkType[i]); 3428 pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i)); 3429 pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]); 3430 pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]); 3431 pw.println("mBarringInfo=" + mBarringInfo.get(i)); 3432 pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState[i]); 3433 pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfos[i]); 3434 pw.println("mIsDataEnabled=" + mIsDataEnabled[i]); 3435 pw.println("mDataEnabledReason=" + mDataEnabledReason[i]); 3436 pw.println("mAllowedNetworkTypeReason=" + mAllowedNetworkTypeReason[i]); 3437 pw.println("mAllowedNetworkTypeValue=" + mAllowedNetworkTypeValue[i]); 3438 pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs.get(i)); 3439 pw.println("mLinkCapacityEstimateList=" + mLinkCapacityEstimateLists.get(i)); 3440 pw.println("mECBMReason=" + mECBMReason[i]); 3441 pw.println("mECBMStarted=" + mECBMStarted[i]); 3442 pw.println("mSCBMReason=" + mSCBMReason[i]); 3443 pw.println("mSCBMStarted=" + mSCBMStarted[i]); 3444 3445 // We need to obfuscate package names, and primitive arrays' native toString is ugly 3446 Pair<List<String>, int[]> carrierPrivilegeState = mCarrierPrivilegeStates.get(i); 3447 pw.println( 3448 "mCarrierPrivilegeState=<packages=" + pii(carrierPrivilegeState.first) 3449 + ", uids=" + Arrays.toString(carrierPrivilegeState.second) + ">"); 3450 Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(i); 3451 pw.println("mCarrierServiceState=<package=" + pii(carrierServiceState.first) 3452 + ", uid=" + carrierServiceState.second + ">"); 3453 pw.decreaseIndent(); 3454 } 3455 3456 pw.println("mPhoneCapability=" + mPhoneCapability); 3457 pw.println("mActiveDataSubId=" + mActiveDataSubId); 3458 pw.println("mRadioPowerState=" + mRadioPowerState); 3459 pw.println("mEmergencyNumberList=" + mEmergencyNumberList); 3460 pw.println("mDefaultPhoneId=" + mDefaultPhoneId); 3461 pw.println("mDefaultSubId=" + mDefaultSubId); 3462 3463 pw.decreaseIndent(); 3464 3465 pw.println("local logs:"); 3466 pw.increaseIndent(); 3467 mLocalLog.dump(fd, pw, args); 3468 pw.decreaseIndent(); 3469 pw.println("listen logs:"); 3470 pw.increaseIndent(); 3471 mListenLog.dump(fd, pw, args); 3472 pw.decreaseIndent(); 3473 pw.println("registrations: count=" + recordCount); 3474 pw.increaseIndent(); 3475 for (Record r : mRecords) { 3476 pw.println(r); 3477 } 3478 pw.decreaseIndent(); 3479 } 3480 } 3481 3482 // 3483 // the legacy intent broadcasting 3484 // 3485 3486 // Legacy intent action. 3487 /** Fired when a subscription's phone state changes. */ 3488 private static final String ACTION_SUBSCRIPTION_PHONE_STATE_CHANGED = 3489 "android.intent.action.SUBSCRIPTION_PHONE_STATE"; 3490 /** 3491 * Broadcast Action: The data connection state has changed for any one of the 3492 * phone's mobile data connections (eg, default, MMS or GPS specific connection). 3493 */ 3494 private static final String ACTION_ANY_DATA_CONNECTION_STATE_CHANGED = 3495 "android.intent.action.ANY_DATA_STATE"; 3496 3497 // Legacy intent extra keys, copied from PhoneConstants. 3498 // Used in legacy intents sent here, for backward compatibility. 3499 private static final String PHONE_CONSTANTS_DATA_APN_TYPE_KEY = "apnType"; 3500 private static final String PHONE_CONSTANTS_DATA_APN_KEY = "apn"; 3501 private static final String PHONE_CONSTANTS_SLOT_KEY = "slot"; 3502 private static final String PHONE_CONSTANTS_STATE_KEY = "state"; 3503 private static final String PHONE_CONSTANTS_SUBSCRIPTION_KEY = "subscription"; 3504 3505 /** 3506 * Broadcast Action: The phone's signal strength has changed. The intent will have the 3507 * following extra values: 3508 * phoneName - A string version of the phone name. 3509 * asu - A numeric value for the signal strength. 3510 * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu). 3511 * The following special values are defined: 3512 * 0 means "-113 dBm or less".31 means "-51 dBm or greater". 3513 */ 3514 public static final String ACTION_SIGNAL_STRENGTH_CHANGED = "android.intent.action.SIG_STR"; 3515 broadcastServiceStateChanged(ServiceState state, int phoneId, int subId)3516 private void broadcastServiceStateChanged(ServiceState state, int phoneId, int subId) { 3517 try { 3518 mBatteryStats.notePhoneState(state.getState()); 3519 } catch (RemoteException re) { 3520 // Can't do much 3521 } 3522 3523 // Send the broadcast exactly once to all possible disjoint sets of apps. 3524 // If the location master switch is on, broadcast the ServiceState 4 times: 3525 // - Full ServiceState sent to apps with ACCESS_FINE_LOCATION and READ_PHONE_STATE 3526 // - Full ServiceState sent to apps with ACCESS_FINE_LOCATION and 3527 // READ_PRIVILEGED_PHONE_STATE but not READ_PHONE_STATE 3528 // - Sanitized ServiceState sent to apps with READ_PHONE_STATE but not ACCESS_FINE_LOCATION 3529 // - Sanitized ServiceState sent to apps with READ_PRIVILEGED_PHONE_STATE but neither 3530 // READ_PHONE_STATE nor ACCESS_FINE_LOCATION 3531 // If the location master switch is off, broadcast the ServiceState multiple times: 3532 // - Full ServiceState sent to all apps permitted to bypass the location master switch if 3533 // they have either READ_PHONE_STATE or READ_PRIVILEGED_PHONE_STATE 3534 // - Sanitized ServiceState sent to all other apps with READ_PHONE_STATE 3535 // - Sanitized ServiceState sent to all other apps with READ_PRIVILEGED_PHONE_STATE but not 3536 // READ_PHONE_STATE 3537 // 3538 // Create a unique delivery group key for each variant for SERVICE_STATE broadcast so 3539 // that a new broadcast only replaces the pending broadcasts of the same variant. 3540 // In order to create a unique delivery group key, append tag of the form 3541 // "I:Included-permissions[,E:Excluded-permissions][,lbp]" 3542 // Note: Given that location-bypass-packages are static, we can just append "lbp" to the 3543 // tag to create a unique delivery group but if location-bypass-packages become dynamic 3544 // in the future, we would need to create a unique key for each group of 3545 // location-bypass-packages. 3546 if (LocationAccessPolicy.isLocationModeEnabled(mContext, mContext.getUserId())) { 3547 Intent fullIntent = createServiceStateIntent(state, subId, phoneId, false); 3548 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions( 3549 fullIntent, 3550 new String[]{Manifest.permission.READ_PHONE_STATE, 3551 Manifest.permission.ACCESS_FINE_LOCATION}, 3552 createServiceStateBroadcastOptions(subId, phoneId, "I:RA")); 3553 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions( 3554 fullIntent, 3555 new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 3556 Manifest.permission.ACCESS_FINE_LOCATION}, 3557 new String[]{Manifest.permission.READ_PHONE_STATE}, 3558 null, 3559 createServiceStateBroadcastOptions(subId, phoneId, "I:RPA,E:R")); 3560 3561 Intent sanitizedIntent = createServiceStateIntent(state, subId, phoneId, true); 3562 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions( 3563 sanitizedIntent, 3564 new String[]{Manifest.permission.READ_PHONE_STATE}, 3565 new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 3566 null, 3567 createServiceStateBroadcastOptions(subId, phoneId, "I:R,E:A")); 3568 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions( 3569 sanitizedIntent, 3570 new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE}, 3571 new String[]{Manifest.permission.READ_PHONE_STATE, 3572 Manifest.permission.ACCESS_FINE_LOCATION}, 3573 null, 3574 createServiceStateBroadcastOptions(subId, phoneId, "I:RP,E:RA")); 3575 } else { 3576 String[] locationBypassPackages = Binder.withCleanCallingIdentity(() -> 3577 LocationAccessPolicy.getLocationBypassPackages(mContext)); 3578 for (String locationBypassPackage : locationBypassPackages) { 3579 Intent fullIntent = createServiceStateIntent(state, subId, phoneId, false); 3580 fullIntent.setPackage(locationBypassPackage); 3581 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions( 3582 fullIntent, 3583 new String[]{Manifest.permission.READ_PHONE_STATE}, 3584 createServiceStateBroadcastOptions(subId, phoneId, "I:R")); 3585 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions( 3586 fullIntent, 3587 new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE}, 3588 new String[]{Manifest.permission.READ_PHONE_STATE}, 3589 null, 3590 createServiceStateBroadcastOptions(subId, phoneId, "I:RP,E:R")); 3591 } 3592 3593 Intent sanitizedIntent = createServiceStateIntent(state, subId, phoneId, true); 3594 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions( 3595 sanitizedIntent, 3596 new String[]{Manifest.permission.READ_PHONE_STATE}, 3597 new String[]{/* no excluded permissions */}, 3598 locationBypassPackages, 3599 createServiceStateBroadcastOptions(subId, phoneId, "I:R,lbp")); 3600 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions( 3601 sanitizedIntent, 3602 new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE}, 3603 new String[]{Manifest.permission.READ_PHONE_STATE}, 3604 locationBypassPackages, 3605 createServiceStateBroadcastOptions(subId, phoneId, "I:RP,E:R,lbp")); 3606 } 3607 } 3608 createServiceStateIntent(ServiceState state, int subId, int phoneId, boolean sanitizeLocation)3609 private Intent createServiceStateIntent(ServiceState state, int subId, int phoneId, 3610 boolean sanitizeLocation) { 3611 Intent intent = new Intent(Intent.ACTION_SERVICE_STATE); 3612 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 3613 Bundle data = new Bundle(); 3614 if (sanitizeLocation) { 3615 state.createLocationInfoSanitizedCopy(true).fillInNotifierBundle(data); 3616 } else { 3617 state.fillInNotifierBundle(data); 3618 } 3619 intent.putExtras(data); 3620 intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId); 3621 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); 3622 intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId); 3623 intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId); 3624 return intent; 3625 } 3626 createServiceStateBroadcastOptions(int subId, int phoneId, String tag)3627 private BroadcastOptions createServiceStateBroadcastOptions(int subId, int phoneId, 3628 String tag) { 3629 return new BroadcastOptions() 3630 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT) 3631 // Use a combination of subId and phoneId as the key so that older broadcasts 3632 // with same subId and phoneId will get discarded. 3633 .setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE, 3634 subId + "-" + phoneId + "-" + tag) 3635 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 3636 } 3637 broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId, int subId)3638 private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId, 3639 int subId) { 3640 final long ident = Binder.clearCallingIdentity(); 3641 try { 3642 mBatteryStats.notePhoneSignalStrength(signalStrength); 3643 } catch (RemoteException e) { 3644 /* The remote entity disappeared, we can safely ignore the exception. */ 3645 } finally { 3646 Binder.restoreCallingIdentity(ident); 3647 } 3648 3649 Intent intent = new Intent(ACTION_SIGNAL_STRENGTH_CHANGED); 3650 Bundle data = new Bundle(); 3651 fillInSignalStrengthNotifierBundle(signalStrength, data); 3652 intent.putExtras(data); 3653 intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId); 3654 intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId); 3655 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 3656 } 3657 fillInSignalStrengthNotifierBundle(SignalStrength signalStrength, Bundle bundle)3658 private void fillInSignalStrengthNotifierBundle(SignalStrength signalStrength, Bundle bundle) { 3659 List<CellSignalStrength> cellSignalStrengths = signalStrength.getCellSignalStrengths(); 3660 for (CellSignalStrength cellSignalStrength : cellSignalStrengths) { 3661 if (cellSignalStrength instanceof CellSignalStrengthLte) { 3662 bundle.putParcelable("Lte", (CellSignalStrengthLte) cellSignalStrength); 3663 } else if (cellSignalStrength instanceof CellSignalStrengthCdma) { 3664 bundle.putParcelable("Cdma", (CellSignalStrengthCdma) cellSignalStrength); 3665 } else if (cellSignalStrength instanceof CellSignalStrengthGsm) { 3666 bundle.putParcelable("Gsm", (CellSignalStrengthGsm) cellSignalStrength); 3667 } else if (cellSignalStrength instanceof CellSignalStrengthWcdma) { 3668 bundle.putParcelable("Wcdma", (CellSignalStrengthWcdma) cellSignalStrength); 3669 } else if (cellSignalStrength instanceof CellSignalStrengthTdscdma) { 3670 bundle.putParcelable("Tdscdma", (CellSignalStrengthTdscdma) cellSignalStrength); 3671 } else if (cellSignalStrength instanceof CellSignalStrengthNr) { 3672 bundle.putParcelable("Nr", (CellSignalStrengthNr) cellSignalStrength); 3673 } 3674 } 3675 } 3676 3677 /** 3678 * Broadcasts an intent notifying apps of a phone state change. {@code subId} can be 3679 * a valid subId, in which case this function fires a subId-specific intent, or it 3680 * can be {@code SubscriptionManager.INVALID_SUBSCRIPTION_ID}, in which case we send 3681 * a global state change broadcast ({@code TelephonyManager.ACTION_PHONE_STATE_CHANGED}). 3682 */ broadcastCallStateChanged(int state, String incomingNumber, int phoneId, int subId)3683 private void broadcastCallStateChanged(int state, String incomingNumber, int phoneId, 3684 int subId) { 3685 final long ident = Binder.clearCallingIdentity(); 3686 try { 3687 if (state == TelephonyManager.CALL_STATE_IDLE) { 3688 mBatteryStats.notePhoneOff(); 3689 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_STATE_CHANGED, 3690 FrameworkStatsLog.PHONE_STATE_CHANGED__STATE__OFF); 3691 } else { 3692 mBatteryStats.notePhoneOn(); 3693 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_STATE_CHANGED, 3694 FrameworkStatsLog.PHONE_STATE_CHANGED__STATE__ON); 3695 } 3696 } catch (RemoteException e) { 3697 /* The remote entity disappeared, we can safely ignore the exception. */ 3698 } finally { 3699 Binder.restoreCallingIdentity(ident); 3700 } 3701 3702 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 3703 intent.putExtra(TelephonyManager.EXTRA_STATE, callStateToString(state)); 3704 3705 // If a valid subId was specified, we should fire off a subId-specific state 3706 // change intent and include the subId. 3707 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 3708 intent.setAction(ACTION_SUBSCRIPTION_PHONE_STATE_CHANGED); 3709 intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId); 3710 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); 3711 } 3712 // If the phoneId is invalid, the broadcast is for overall call state. 3713 if (phoneId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { 3714 intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId); 3715 intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId); 3716 } 3717 3718 // Wakeup apps for the (SUBSCRIPTION_)PHONE_STATE broadcast. 3719 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 3720 3721 // Create a version of the intent with the number always populated. 3722 Intent intentWithPhoneNumber = new Intent(intent); 3723 intentWithPhoneNumber.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber); 3724 3725 // Send broadcast twice, once for apps that have PRIVILEGED permission and once for those 3726 // that have the runtime one 3727 mContext.sendBroadcastAsUser(intentWithPhoneNumber, UserHandle.ALL, 3728 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE); 3729 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 3730 android.Manifest.permission.READ_PHONE_STATE, 3731 AppOpsManager.OP_READ_PHONE_STATE); 3732 mContext.sendBroadcastAsUserMultiplePermissions(intentWithPhoneNumber, UserHandle.ALL, 3733 new String[] { android.Manifest.permission.READ_PHONE_STATE, 3734 android.Manifest.permission.READ_CALL_LOG}); 3735 } 3736 3737 /** Converts TelephonyManager#CALL_STATE_* to TelephonyManager#EXTRA_STATE_*. */ callStateToString(int callState)3738 private static String callStateToString(int callState) { 3739 switch (callState) { 3740 case TelephonyManager.CALL_STATE_RINGING: 3741 return TelephonyManager.EXTRA_STATE_RINGING; 3742 case TelephonyManager.CALL_STATE_OFFHOOK: 3743 return TelephonyManager.EXTRA_STATE_OFFHOOK; 3744 default: 3745 return TelephonyManager.EXTRA_STATE_IDLE; 3746 } 3747 } 3748 broadcastDataConnectionStateChanged(int slotIndex, int subId, @NonNull PreciseDataConnectionState pdcs)3749 private void broadcastDataConnectionStateChanged(int slotIndex, int subId, 3750 @NonNull PreciseDataConnectionState pdcs) { 3751 // Note: not reporting to the battery stats service here, because the 3752 // status bar takes care of that after taking into account all of the 3753 // required info. 3754 Intent intent = new Intent(ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 3755 intent.putExtra(PHONE_CONSTANTS_STATE_KEY, 3756 TelephonyUtils.dataStateToString(pdcs.getState())); 3757 intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, pdcs.getApnSetting().getApnName()); 3758 intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY, 3759 getApnTypesStringFromBitmask(pdcs.getApnSetting().getApnTypeBitmask())); 3760 intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, slotIndex); 3761 intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId); 3762 // Send the broadcast twice -- once for all apps with READ_PHONE_STATE, then again 3763 // for all apps with READ_PRIV but not READ_PHONE_STATE. This ensures that any app holding 3764 // either READ_PRIV or READ_PHONE get this broadcast exactly once. 3765 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE); 3766 mContext.createContextAsUser(UserHandle.ALL, 0) 3767 .sendBroadcastMultiplePermissions(intent, 3768 new String[] { Manifest.permission.READ_PRIVILEGED_PHONE_STATE }, 3769 new String[] { Manifest.permission.READ_PHONE_STATE }); 3770 } 3771 3772 /** 3773 * Reimplementation of {@link ApnSetting#getApnTypesStringFromBitmask}. 3774 */ 3775 @VisibleForTesting getApnTypesStringFromBitmask(int apnTypeBitmask)3776 public static String getApnTypesStringFromBitmask(int apnTypeBitmask) { 3777 List<String> types = new ArrayList<>(); 3778 int remainingApnTypes = apnTypeBitmask; 3779 // special case for DEFAULT since it's not a pure bit 3780 if ((remainingApnTypes & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) { 3781 types.add(ApnSetting.TYPE_DEFAULT_STRING); 3782 remainingApnTypes &= ~ApnSetting.TYPE_DEFAULT; 3783 } 3784 while (remainingApnTypes != 0) { 3785 int highestApnTypeBit = Integer.highestOneBit(remainingApnTypes); 3786 String apnString = ApnSetting.getApnTypeString(highestApnTypeBit); 3787 if (!TextUtils.isEmpty(apnString)) types.add(apnString); 3788 remainingApnTypes &= ~highestApnTypeBit; 3789 } 3790 return TextUtils.join(",", types); 3791 } 3792 enforceNotifyPermissionOrCarrierPrivilege(String method)3793 private void enforceNotifyPermissionOrCarrierPrivilege(String method) { 3794 if (checkNotifyPermission()) { 3795 return; 3796 } 3797 3798 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mContext, 3799 SubscriptionManager.getDefaultSubscriptionId(), method); 3800 } 3801 checkNotifyPermission(String method)3802 private boolean checkNotifyPermission(String method) { 3803 if (checkNotifyPermission()) { 3804 return true; 3805 } 3806 String msg = "Modify Phone State Permission Denial: " + method + " from pid=" 3807 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); 3808 if (DBG) log(msg); 3809 return false; 3810 } 3811 checkNotifyPermission()3812 private boolean checkNotifyPermission() { 3813 return mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 3814 == PackageManager.PERMISSION_GRANTED; 3815 } 3816 checkListenerPermission(Set<Integer> events, int subId, String callingPackage, @Nullable String callingFeatureId, String message)3817 private boolean checkListenerPermission(Set<Integer> events, int subId, String callingPackage, 3818 @Nullable String callingFeatureId, String message) { 3819 boolean isPermissionCheckSuccessful = true; 3820 if (isLocationPermissionRequired(events)) { 3821 LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder = 3822 new LocationAccessPolicy.LocationPermissionQuery.Builder() 3823 .setCallingPackage(callingPackage) 3824 .setCallingFeatureId(callingFeatureId) 3825 .setMethod(message + " events: " + events) 3826 .setCallingPid(Binder.getCallingPid()) 3827 .setCallingUid(Binder.getCallingUid()); 3828 // Everything that requires fine location started in Q. So far... 3829 locationQueryBuilder.setMinSdkVersionForFine(Build.VERSION_CODES.Q); 3830 // If we're enforcing fine starting in Q, we also want to enforce coarse even for 3831 // older SDK versions. 3832 locationQueryBuilder.setMinSdkVersionForCoarse(0); 3833 locationQueryBuilder.setMinSdkVersionForEnforcement(0); 3834 LocationAccessPolicy.LocationPermissionResult result = 3835 LocationAccessPolicy.checkLocationPermission( 3836 mContext, locationQueryBuilder.build()); 3837 switch (result) { 3838 case DENIED_HARD: 3839 throw new SecurityException("Unable to listen for events " + events + " due to " 3840 + "insufficient location permissions."); 3841 case DENIED_SOFT: 3842 isPermissionCheckSuccessful = false; 3843 } 3844 } 3845 3846 if (isPhoneStatePermissionRequired(events, callingPackage, Binder.getCallingUserHandle())) { 3847 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( 3848 mContext, subId, callingPackage, callingFeatureId, message)) { 3849 isPermissionCheckSuccessful = false; 3850 } 3851 } 3852 3853 if (isPrecisePhoneStatePermissionRequired(events)) { 3854 // check if calling app has either permission READ_PRECISE_PHONE_STATE 3855 // or with carrier privileges 3856 try { 3857 mContext.enforceCallingOrSelfPermission( 3858 android.Manifest.permission.READ_PRECISE_PHONE_STATE, null); 3859 } catch (SecurityException se) { 3860 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mContext, subId, message); 3861 } 3862 } 3863 3864 if (isActiveEmergencySessionPermissionRequired(events)) { 3865 mContext.enforceCallingOrSelfPermission( 3866 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null); 3867 } 3868 3869 if (isPrivilegedPhoneStatePermissionRequired(events)) { 3870 mContext.enforceCallingOrSelfPermission( 3871 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); 3872 } 3873 return isPermissionCheckSuccessful; 3874 } 3875 handleRemoveListLocked()3876 private void handleRemoveListLocked() { 3877 int size = mRemoveList.size(); 3878 if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size); 3879 if (size > 0) { 3880 for (IBinder b : mRemoveList) { 3881 remove(b); 3882 } 3883 mRemoveList.clear(); 3884 } 3885 } 3886 validateEventAndUserLocked(Record r, int event)3887 private boolean validateEventAndUserLocked(Record r, int event) { 3888 int foregroundUser; 3889 final long callingIdentity = Binder.clearCallingIdentity(); 3890 boolean valid = false; 3891 try { 3892 foregroundUser = ActivityManager.getCurrentUser(); 3893 valid = UserHandle.getUserId(r.callerUid) == foregroundUser 3894 && r.matchTelephonyCallbackEvent(event); 3895 if (DBG | DBG_LOC) { 3896 log("validateEventAndUserLocked: valid=" + valid 3897 + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser 3898 + " r.eventList=" + r.eventList + " event=" + event); 3899 } 3900 } finally { 3901 Binder.restoreCallingIdentity(callingIdentity); 3902 } 3903 return valid; 3904 } 3905 validatePhoneId(int phoneId)3906 private boolean validatePhoneId(int phoneId) { 3907 // Call getActiveModemCount to get the latest value instead of depending on mNumPhone 3908 boolean valid = (phoneId >= 0) && (phoneId < getTelephonyManager().getActiveModemCount()); 3909 if (VDBG) log("validatePhoneId: " + valid); 3910 return valid; 3911 } 3912 log(String s)3913 private static void log(String s) { 3914 Rlog.d(TAG, s); 3915 } 3916 loge(String s)3917 private static void loge(String s) { 3918 Rlog.e(TAG, s); 3919 } 3920 3921 /** 3922 * Match the sub id or phone id of the event to the record 3923 * 3924 * We follow the rules below: 3925 * 1) If sub id of the event is invalid, phone id should be used. 3926 * 2) The event on default sub should be notified to the records 3927 * which register the default sub id. 3928 * 3) Sub id should be exactly matched for all other cases. 3929 */ idMatch(Record r, int subId, int phoneId)3930 boolean idMatch(Record r, int subId, int phoneId) { 3931 3932 if (subId < 0) { 3933 // Invalid case, we need compare phoneId. 3934 return (r.phoneId == phoneId); 3935 } 3936 if (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 3937 return (subId == mDefaultSubId); 3938 } else { 3939 return (r.subId == subId); 3940 } 3941 } 3942 checkFineLocationAccess(Record r)3943 private boolean checkFineLocationAccess(Record r) { 3944 return checkFineLocationAccess(r, Build.VERSION_CODES.BASE); 3945 } 3946 checkCoarseLocationAccess(Record r)3947 private boolean checkCoarseLocationAccess(Record r) { 3948 return checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE); 3949 } 3950 3951 /** 3952 * Note -- this method should only be used at the site of a permission check if you need to 3953 * explicitly allow apps below a certain SDK level access regardless of location permissions. 3954 * If you don't need app compat logic, use {@link #checkFineLocationAccess(Record)}. 3955 */ checkFineLocationAccess(Record r, int minSdk)3956 private boolean checkFineLocationAccess(Record r, int minSdk) { 3957 if (r.renounceFineLocationAccess) { 3958 return false; 3959 } 3960 LocationAccessPolicy.LocationPermissionQuery query = 3961 new LocationAccessPolicy.LocationPermissionQuery.Builder() 3962 .setCallingPackage(r.callingPackage) 3963 .setCallingFeatureId(r.callingFeatureId) 3964 .setCallingPid(r.callerPid) 3965 .setCallingUid(r.callerUid) 3966 .setMethod("TelephonyRegistry push") 3967 .setLogAsInfo(true) // we don't need to log an error every time we push 3968 .setMinSdkVersionForFine(minSdk) 3969 .setMinSdkVersionForCoarse(minSdk) 3970 .setMinSdkVersionForEnforcement(minSdk) 3971 .build(); 3972 3973 return Binder.withCleanCallingIdentity(() -> { 3974 LocationAccessPolicy.LocationPermissionResult locationResult = 3975 LocationAccessPolicy.checkLocationPermission(mContext, query); 3976 return locationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED; 3977 }); 3978 } 3979 3980 /** 3981 * Note -- this method should only be used at the site of a permission check if you need to 3982 * explicitly allow apps below a certain SDK level access regardless of location permissions. 3983 * If you don't need app compat logic, use {@link #checkCoarseLocationAccess(Record)}. 3984 */ checkCoarseLocationAccess(Record r, int minSdk)3985 private boolean checkCoarseLocationAccess(Record r, int minSdk) { 3986 if (r.renounceCoarseLocationAccess) { 3987 return false; 3988 } 3989 LocationAccessPolicy.LocationPermissionQuery query = 3990 new LocationAccessPolicy.LocationPermissionQuery.Builder() 3991 .setCallingPackage(r.callingPackage) 3992 .setCallingFeatureId(r.callingFeatureId) 3993 .setCallingPid(r.callerPid) 3994 .setCallingUid(r.callerUid) 3995 .setMethod("TelephonyRegistry push") 3996 .setLogAsInfo(true) // we don't need to log an error every time we push 3997 .setMinSdkVersionForCoarse(minSdk) 3998 .setMinSdkVersionForFine(Integer.MAX_VALUE) 3999 .setMinSdkVersionForEnforcement(minSdk) 4000 .build(); 4001 4002 return Binder.withCleanCallingIdentity(() -> { 4003 LocationAccessPolicy.LocationPermissionResult locationResult = 4004 LocationAccessPolicy.checkLocationPermission(mContext, query); 4005 return locationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED; 4006 }); 4007 } 4008 4009 private void checkPossibleMissNotify(Record r, int phoneId) { 4010 Set<Integer> events = r.eventList; 4011 4012 if (events == null || events.isEmpty()) { 4013 log("checkPossibleMissNotify: events = null."); 4014 return; 4015 } 4016 4017 if ((events.contains(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED))) { 4018 try { 4019 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" + 4020 mServiceState[phoneId]); 4021 ServiceState ss = new ServiceState(mServiceState[phoneId]); 4022 if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { 4023 r.callback.onServiceStateChanged(ss); 4024 } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { 4025 r.callback.onServiceStateChanged( 4026 ss.createLocationInfoSanitizedCopy(false)); 4027 } else { 4028 r.callback.onServiceStateChanged( 4029 ss.createLocationInfoSanitizedCopy(true)); 4030 } 4031 } catch (RemoteException ex) { 4032 mRemoveList.add(r.binder); 4033 } 4034 } 4035 4036 if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)) { 4037 try { 4038 if (mSignalStrength[phoneId] != null) { 4039 SignalStrength signalStrength = mSignalStrength[phoneId]; 4040 if (DBG) { 4041 log("checkPossibleMissNotify: onSignalStrengthsChanged SS=" 4042 + signalStrength); 4043 } 4044 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 4045 } 4046 } catch (RemoteException ex) { 4047 mRemoveList.add(r.binder); 4048 } 4049 } 4050 4051 if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)) { 4052 try { 4053 if (mSignalStrength[phoneId] != null) { 4054 int gsmSignalStrength = mSignalStrength[phoneId] 4055 .getGsmSignalStrength(); 4056 if (DBG) { 4057 log("checkPossibleMissNotify: onSignalStrengthChanged SS=" 4058 + gsmSignalStrength); 4059 } 4060 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 4061 : gsmSignalStrength)); 4062 } 4063 } catch (RemoteException ex) { 4064 mRemoveList.add(r.binder); 4065 } 4066 } 4067 4068 if (validateEventAndUserLocked(r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)) { 4069 try { 4070 if (DBG_LOC) { 4071 log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " 4072 + mCellInfo.get(phoneId)); 4073 } 4074 if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) 4075 && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { 4076 r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); 4077 } 4078 } catch (RemoteException ex) { 4079 mRemoveList.add(r.binder); 4080 } 4081 } 4082 4083 if (events.contains(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) { 4084 try { 4085 if (VDBG) { 4086 log("checkPossibleMissNotify: onUserMobileDataStateChanged phoneId=" 4087 + phoneId + " umds=" + mUserMobileDataState[phoneId]); 4088 } 4089 r.callback.onUserMobileDataStateChanged(mUserMobileDataState[phoneId]); 4090 } catch (RemoteException ex) { 4091 mRemoveList.add(r.binder); 4092 } 4093 } 4094 4095 if (events.contains(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)) { 4096 try { 4097 if (VDBG) { 4098 log("checkPossibleMissNotify: onDisplayInfoChanged phoneId=" 4099 + phoneId + " dpi=" + mTelephonyDisplayInfos[phoneId]); 4100 } 4101 if (mTelephonyDisplayInfos[phoneId] != null) { 4102 r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[phoneId]); 4103 } 4104 } catch (RemoteException ex) { 4105 mRemoveList.add(r.binder); 4106 } 4107 } 4108 4109 if (events.contains(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) { 4110 try { 4111 if (VDBG) { 4112 log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId=" 4113 + phoneId + " mwi=" + mMessageWaiting[phoneId]); 4114 } 4115 r.callback.onMessageWaitingIndicatorChanged( 4116 mMessageWaiting[phoneId]); 4117 } catch (RemoteException ex) { 4118 mRemoveList.add(r.binder); 4119 } 4120 } 4121 4122 if (events.contains(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) { 4123 try { 4124 if (VDBG) { 4125 log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId=" 4126 + phoneId + " cfi=" + mCallForwarding[phoneId]); 4127 } 4128 r.callback.onCallForwardingIndicatorChanged( 4129 mCallForwarding[phoneId]); 4130 } catch (RemoteException ex) { 4131 mRemoveList.add(r.binder); 4132 } 4133 } 4134 4135 if (validateEventAndUserLocked(r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)) { 4136 try { 4137 if (DBG_LOC) { 4138 log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = " 4139 + mCellIdentity[phoneId]); 4140 } 4141 if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) 4142 && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { 4143 // null will be translated to empty CellLocation object in client. 4144 r.callback.onCellLocationChanged(mCellIdentity[phoneId]); 4145 } 4146 } catch (RemoteException ex) { 4147 mRemoveList.add(r.binder); 4148 } 4149 } 4150 4151 if (events.contains(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)) { 4152 try { 4153 if (DBG) { 4154 log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState" 4155 + "=" + mDataConnectionState[phoneId] 4156 + ", mDataConnectionNetworkType=" + mDataConnectionNetworkType[phoneId] 4157 + ")"); 4158 } 4159 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 4160 mDataConnectionNetworkType[phoneId]); 4161 } catch (RemoteException ex) { 4162 mRemoveList.add(r.binder); 4163 } 4164 } 4165 } 4166 4167 /** 4168 * Returns a string representation of the radio technology (network type) 4169 * currently in use on the device. 4170 * @param type for which network type is returned 4171 * @return the name of the radio technology 4172 * 4173 */ 4174 private String getNetworkTypeName(@Annotation.NetworkType int type) { 4175 switch (type) { 4176 case TelephonyManager.NETWORK_TYPE_GPRS: 4177 return "GPRS"; 4178 case TelephonyManager.NETWORK_TYPE_EDGE: 4179 return "EDGE"; 4180 case TelephonyManager.NETWORK_TYPE_UMTS: 4181 return "UMTS"; 4182 case TelephonyManager.NETWORK_TYPE_HSDPA: 4183 return "HSDPA"; 4184 case TelephonyManager.NETWORK_TYPE_HSUPA: 4185 return "HSUPA"; 4186 case TelephonyManager.NETWORK_TYPE_HSPA: 4187 return "HSPA"; 4188 case TelephonyManager.NETWORK_TYPE_CDMA: 4189 return "CDMA"; 4190 case TelephonyManager.NETWORK_TYPE_EVDO_0: 4191 return "CDMA - EvDo rev. 0"; 4192 case TelephonyManager.NETWORK_TYPE_EVDO_A: 4193 return "CDMA - EvDo rev. A"; 4194 case TelephonyManager.NETWORK_TYPE_EVDO_B: 4195 return "CDMA - EvDo rev. B"; 4196 case TelephonyManager.NETWORK_TYPE_1xRTT: 4197 return "CDMA - 1xRTT"; 4198 case TelephonyManager.NETWORK_TYPE_LTE: 4199 return "LTE"; 4200 case TelephonyManager.NETWORK_TYPE_EHRPD: 4201 return "CDMA - eHRPD"; 4202 case TelephonyManager.NETWORK_TYPE_IDEN: 4203 return "iDEN"; 4204 case TelephonyManager.NETWORK_TYPE_HSPAP: 4205 return "HSPA+"; 4206 case TelephonyManager.NETWORK_TYPE_GSM: 4207 return "GSM"; 4208 case TelephonyManager.NETWORK_TYPE_TD_SCDMA: 4209 return "TD_SCDMA"; 4210 case TelephonyManager.NETWORK_TYPE_IWLAN: 4211 return "IWLAN"; 4212 4213 //TODO: This network type is marked as hidden because it is not a 4214 // true network type and we are looking to remove it completely from the available list 4215 // of network types. Since this method is only used for logging, in the event that this 4216 // network type is selected, the log will read as "Unknown." 4217 //case TelephonyManager.NETWORK_TYPE_LTE_CA: 4218 // return "LTE_CA"; 4219 4220 case TelephonyManager.NETWORK_TYPE_NR: 4221 return "NR"; 4222 default: 4223 return "UNKNOWN"; 4224 } 4225 } 4226 4227 /** Returns a new PreciseCallState object with default values. */ 4228 private static PreciseCallState createPreciseCallState() { 4229 return new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_NOT_VALID, 4230 PreciseCallState.PRECISE_CALL_STATE_NOT_VALID, 4231 PreciseCallState.PRECISE_CALL_STATE_NOT_VALID, 4232 DisconnectCause.NOT_VALID, 4233 PreciseDisconnectCause.NOT_VALID); 4234 } 4235 4236 /** Returns a new CallQuality object with default values. */ 4237 private static CallQuality createCallQuality() { 4238 return new CallQuality(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 4239 } 4240 4241 private int getPhoneIdFromSubId(int subId) { 4242 SubscriptionManager subManager = (SubscriptionManager) 4243 mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 4244 if (subManager == null) return INVALID_SIM_SLOT_INDEX; 4245 4246 if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 4247 subId = SubscriptionManager.getDefaultSubscriptionId(); 4248 } 4249 4250 SubscriptionInfo info = subManager.getActiveSubscriptionInfo(subId); 4251 if (info == null) return INVALID_SIM_SLOT_INDEX; 4252 return info.getSimSlotIndex(); 4253 } 4254 4255 /** 4256 * On certain build types, we should redact information by default. UID information will be 4257 * preserved in the same log line, so no debugging capability is lost in full bug reports. 4258 * However, privacy-constrained bug report types (e.g. connectivity) cannot display raw 4259 * package names on user builds as it's considered an information leak. 4260 */ 4261 private static String pii(String packageName) { 4262 return Build.IS_DEBUGGABLE ? packageName : "***"; 4263 } 4264 4265 /** Redacts an entire list of package names if necessary. */ 4266 private static String pii(List<String> packageNames) { 4267 if (packageNames.isEmpty() || Build.IS_DEBUGGABLE) return packageNames.toString(); 4268 return "[***, size=" + packageNames.size() + "]"; 4269 } 4270 } 4271