Merge "Add setNtnSmsSupported API in SatelliteManager." into main
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 2e1a89f..a91000e 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -42,7 +42,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import android.database.SQLException;
import android.hardware.radio.modem.ImeiInfo;
import android.net.Uri;
@@ -470,12 +469,6 @@
}
};
- private boolean hasCalling() {
- if (!TelephonyCapabilities.minimalTelephonyCdmCheck(mFeatureFlags)) return true;
- return mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_TELEPHONY_CALLING);
- }
-
private void initOnce(CommandsInterface ci) {
if (ci instanceof SimulatedRadioControl) {
mSimulatedRadioControl = (SimulatedRadioControl) ci;
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index 3141406..9eebc60 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -48,6 +48,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
+import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.uicc.IccConstants;
@@ -1511,8 +1512,7 @@
@VisibleForTesting
public void notifyIfOutgoingEmergencySms(String destAddr) {
Phone[] allPhones = mPhoneFactoryProxy.getPhones();
- EmergencyNumber emergencyNumber = mPhone.getEmergencyNumberTracker().getEmergencyNumber(
- destAddr);
+ EmergencyNumber emergencyNumber = getEmergencyNumber(mPhone, destAddr);
if (emergencyNumber != null) {
mPhone.notifyOutgoingEmergencySms(emergencyNumber);
} else if (allPhones.length > 1) {
@@ -1522,8 +1522,7 @@
if (phone.getPhoneId() == mPhone.getPhoneId()) {
continue;
}
- emergencyNumber = phone.getEmergencyNumberTracker()
- .getEmergencyNumber(destAddr);
+ emergencyNumber = getEmergencyNumber(phone, destAddr);
if (emergencyNumber != null) {
mPhone.notifyOutgoingEmergencySms(emergencyNumber);
break;
@@ -1532,6 +1531,13 @@
}
}
+ private EmergencyNumber getEmergencyNumber(Phone phone, String number) {
+ if (!phone.hasCalling()) return null;
+ EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
+ if (tracker == null) return null;
+ return tracker.getEmergencyNumber(number);
+ }
+
private void returnUnspecifiedFailure(PendingIntent pi) {
if (pi != null) {
try {
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 011e67b..90766d6 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -772,8 +772,7 @@
if (result != Intents.RESULT_SMS_HANDLED && result != Activity.RESULT_OK) {
mMetrics.writeIncomingSmsError(mPhone.getPhoneId(), is3gpp2(), smsSource, result);
mPhone.getSmsStats().onIncomingSmsError(is3gpp2(), smsSource, result,
- TelephonyManager.from(mContext)
- .isEmergencyNumber(smsb.getOriginatingAddress()));
+ isEmergencyNumber(smsb.getOriginatingAddress()));
if (mPhone != null) {
TelephonyAnalytics telephonyAnalytics = mPhone.getTelephonyAnalytics();
if (telephonyAnalytics != null) {
@@ -1052,7 +1051,7 @@
logeWithLocalLog(errorMsg, tracker.getMessageId());
mPhone.getSmsStats().onIncomingSmsError(
is3gpp2(), tracker.getSource(), RESULT_SMS_NULL_PDU,
- TelephonyManager.from(mContext).isEmergencyNumber(tracker.getAddress()));
+ isEmergencyNumber(tracker.getAddress()));
if (mPhone != null) {
TelephonyAnalytics telephonyAnalytics = mPhone.getTelephonyAnalytics();
if (telephonyAnalytics != null) {
@@ -1082,8 +1081,7 @@
tracker.getMessageId());
mPhone.getSmsStats().onIncomingSmsWapPush(tracker.getSource(),
messageCount, RESULT_SMS_NULL_MESSAGE, tracker.getMessageId(),
- TelephonyManager.from(mContext)
- .isEmergencyNumber(tracker.getAddress()));
+ isEmergencyNumber(tracker.getAddress()));
return false;
}
}
@@ -1118,8 +1116,7 @@
mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), tracker.getSource(),
format, timestamps, wapPushResult, tracker.getMessageId());
mPhone.getSmsStats().onIncomingSmsWapPush(tracker.getSource(), messageCount,
- result, tracker.getMessageId(), TelephonyManager.from(mContext)
- .isEmergencyNumber(tracker.getAddress()));
+ result, tracker.getMessageId(), isEmergencyNumber(tracker.getAddress()));
// result is Activity.RESULT_OK if an ordered broadcast was sent
if (result == Activity.RESULT_OK) {
return true;
@@ -1140,7 +1137,7 @@
format, timestamps, block, tracker.getMessageId());
mPhone.getSmsStats().onIncomingSmsSuccess(is3gpp2(), tracker.getSource(),
messageCount, block, tracker.getMessageId(),
- TelephonyManager.from(mContext).isEmergencyNumber(tracker.getAddress()));
+ isEmergencyNumber(tracker.getAddress()));
CarrierRoamingSatelliteSessionStats sessionStats =
CarrierRoamingSatelliteSessionStats.getInstance(mPhone.getSubId());
sessionStats.onIncomingSms(mPhone.getSubId());
@@ -1178,6 +1175,13 @@
return true;
}
+ private boolean isEmergencyNumber(String number) {
+ if (!mPhone.hasCalling()) return false;
+ TelephonyManager manager = TelephonyManager.from(mContext);
+ if (manager == null) return false;
+ return manager.isEmergencyNumber(number);
+ }
+
/**
* Processes the message part while the credential-encrypted storage is still locked.
*
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index ea5d99d..ab9be76 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -661,7 +661,7 @@
mSmsStorageMonitor = mTelephonyComponentFactory.inject(SmsStorageMonitor.class.getName())
.makeSmsStorageMonitor(this, mFeatureFlags);
mSmsUsageMonitor = mTelephonyComponentFactory.inject(SmsUsageMonitor.class.getName())
- .makeSmsUsageMonitor(context);
+ .makeSmsUsageMonitor(context, mFeatureFlags);
mUiccController = UiccController.getInstance();
mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
mSimActivationTracker = mTelephonyComponentFactory
@@ -1967,6 +1967,13 @@
}
/**
+ * @return true if this device supports calling, false otherwise.
+ */
+ public boolean hasCalling() {
+ return TelephonyCapabilities.supportsTelephonyCalling(mFeatureFlags, mContext);
+ }
+
+ /**
* Retrieves the EmergencyNumberTracker of the phone instance.
*/
public EmergencyNumberTracker getEmergencyNumberTracker() {
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 8a2d5bf..871cabc 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -2120,7 +2120,7 @@
}
}
- if (mTelephonyManager.isEmergencyNumber(trackers[0].mDestAddress)) {
+ if (mPhone.hasCalling() && mTelephonyManager.isEmergencyNumber(trackers[0].mDestAddress)) {
new AsyncEmergencyContactNotifier(mContext).execute();
}
}
diff --git a/src/java/com/android/internal/telephony/SmsController.java b/src/java/com/android/internal/telephony/SmsController.java
index e3c409d..051fbbd 100644
--- a/src/java/com/android/internal/telephony/SmsController.java
+++ b/src/java/com/android/internal/telephony/SmsController.java
@@ -276,6 +276,7 @@
}
UserHandle callingUser = Binder.getCallingUserHandle();
+
Rlog.d(LOG_TAG, "sendTextForSubscriber caller=" + callingPackage);
if (skipFdnCheck || skipShortCodeCheck) {
@@ -1194,8 +1195,9 @@
}
// Skip FDN check for emergency numbers
+ if (!TelephonyCapabilities.supportsTelephonyCalling(mFlags, mContext)) return false;
TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
- if (tm.isEmergencyNumber(destAddr)) {
+ if (tm != null && tm.isEmergencyNumber(destAddr)) {
return false;
}
diff --git a/src/java/com/android/internal/telephony/SmsDispatchersController.java b/src/java/com/android/internal/telephony/SmsDispatchersController.java
index 5bcb085..77fd1f6 100644
--- a/src/java/com/android/internal/telephony/SmsDispatchersController.java
+++ b/src/java/com/android/internal/telephony/SmsDispatchersController.java
@@ -829,8 +829,7 @@
if (!tracker.mUsesImsServiceForIms) {
if (isSmsDomainSelectionEnabled()) {
- TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
- boolean isEmergency = tm.isEmergencyNumber(tracker.mDestAddress);
+ boolean isEmergency = isEmergencyNumber(tracker.mDestAddress);
// This may be invoked by another thread, so this operation is posted and
// handled through the execution flow of SmsDispatchersController.
SomeArgs args = SomeArgs.obtain();
@@ -1219,8 +1218,7 @@
private void handleSmsSentCompletedUsingDomainSelection(@NonNull String destAddr,
long messageId, boolean success, boolean isOverIms, boolean isLastSmsPart) {
if (mEmergencyStateTracker != null) {
- TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
- if (tm.isEmergencyNumber(destAddr)) {
+ if (isEmergencyNumber(destAddr)) {
mEmergencyStateTracker.endSms(String.valueOf(messageId), success,
isOverIms ? NetworkRegistrationInfo.DOMAIN_PS
: NetworkRegistrationInfo.DOMAIN_CS,
@@ -1269,8 +1267,7 @@
*/
private void handleSmsReceivedViaIms(@Nullable String origAddr) {
if (mEmergencyStateTracker != null) {
- TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
- if (origAddr != null && tm.isEmergencyNumber(origAddr)) {
+ if (origAddr != null && isEmergencyNumber(origAddr)) {
mEmergencyStateTracker.onEmergencySmsReceived();
}
}
@@ -1288,7 +1285,9 @@
private boolean isTestEmergencyNumber(String number) {
try {
+ if (!mPhone.hasCalling()) return false;
TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+ if (tm == null) return false;
Map<Integer, List<EmergencyNumber>> eMap = tm.getEmergencyNumberList();
return eMap.values().stream().flatMap(Collection::stream).anyMatch(eNumber ->
eNumber.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST)
@@ -1878,8 +1877,7 @@
logd("sendTextInternal: messageId=" + request.messageId
+ ", uniqueMessageId=" + request.uniqueMessageId);
if (isSmsDomainSelectionEnabled()) {
- TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
- boolean isEmergency = tm.isEmergencyNumber(request.destAddr);
+ boolean isEmergency = isEmergencyNumber(request.destAddr);
sendSmsUsingDomainSelection(getDomainSelectionConnectionHolder(isEmergency),
request, "sendText");
return;
@@ -2039,11 +2037,17 @@
sendMultipartTextInternal(pendingRequest);
}
+ private boolean isEmergencyNumber(String number) {
+ if (!mPhone.hasCalling()) return false;
+ TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+ if (tm == null) return false;
+ return tm.isEmergencyNumber(number);
+ }
+
private void sendMultipartTextInternal(PendingRequest request) {
logd("sendMultipartTextInternal: messageId=" + request.messageId);
if (isSmsDomainSelectionEnabled()) {
- TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
- boolean isEmergency = tm.isEmergencyNumber(request.destAddr);
+ boolean isEmergency = isEmergencyNumber(request.destAddr);
sendSmsUsingDomainSelection(getDomainSelectionConnectionHolder(isEmergency),
request, "sendMultipartText");
return;
diff --git a/src/java/com/android/internal/telephony/SmsUsageMonitor.java b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
index 8e4ac60..7fb5811 100644
--- a/src/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
@@ -35,6 +35,7 @@
import android.util.AtomicFile;
import android.util.Xml;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.util.XmlUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.telephony.Rlog;
@@ -113,6 +114,8 @@
/** Context for retrieving regexes from XML resource. */
private final Context mContext;
+ private final FeatureFlags mFeatureFlags;
+
/** Country code for the cached short code pattern matcher. */
private String mCurrentCountry;
@@ -255,8 +258,9 @@
* @param context the context to use to load resources and get TelephonyManager service
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public SmsUsageMonitor(Context context) {
+ public SmsUsageMonitor(Context context, FeatureFlags flags) {
mContext = context;
+ mFeatureFlags = flags;
ContentResolver resolver = context.getContentResolver();
mRoleManager = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
@@ -404,7 +408,8 @@
synchronized (mSettingsObserverHandler) {
TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
// always allow emergency numbers
- if (tm.isEmergencyNumber(destAddress)) {
+ if (TelephonyCapabilities.supportsTelephonyCalling(mFeatureFlags, mContext)
+ && tm != null && tm.isEmergencyNumber(destAddress)) {
if (DBG) Rlog.d(TAG, "isEmergencyNumber");
return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
}
diff --git a/src/java/com/android/internal/telephony/TelephonyCapabilities.java b/src/java/com/android/internal/telephony/TelephonyCapabilities.java
index 71d3b14..b650b43 100644
--- a/src/java/com/android/internal/telephony/TelephonyCapabilities.java
+++ b/src/java/com/android/internal/telephony/TelephonyCapabilities.java
@@ -18,6 +18,8 @@
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Build;
import android.os.SystemProperties;
@@ -209,4 +211,14 @@
return featureFlags.minimalTelephonyCdmCheck();
}
+
+ /**
+ * @return true if this device supports telephony calling, false if it does not.
+ */
+ public static boolean supportsTelephonyCalling(@NonNull FeatureFlags featureFlags,
+ Context context) {
+ if (!TelephonyCapabilities.minimalTelephonyCdmCheck(featureFlags)) return true;
+ return context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TELEPHONY_CALLING);
+ }
}
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index 10e97b6..b4a3ee6 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -301,8 +301,8 @@
return new SmsStorageMonitor(phone, flags);
}
- public SmsUsageMonitor makeSmsUsageMonitor(Context context) {
- return new SmsUsageMonitor(context);
+ public SmsUsageMonitor makeSmsUsageMonitor(Context context, FeatureFlags flags) {
+ return new SmsUsageMonitor(context, flags);
}
public ServiceStateTracker makeServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci,
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index 62d33d9..079e705 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -1834,16 +1834,18 @@
if (phone == null) {
return false;
}
-
+ Call bgCall = phone.getBackgroundCall();
+ Call fgCall = phone.getForegroundCall();
+ if (bgCall == null || fgCall == null) {
+ return false;
+ }
// A phone in voice call might trigger data being switched to it.
// Exclude dialing to give modem time to process an EMC first before dealing with DDS switch
// Include alerting because modem RLF leads to delay in switch, so carrier required to
// switch in alerting phase.
// TODO: check ringing call for vDADA
- return (!phone.getBackgroundCall().isIdle()
- && phone.getBackgroundCall().getState() != Call.State.DIALING)
- || (!phone.getForegroundCall().isIdle()
- && phone.getForegroundCall().getState() != Call.State.DIALING);
+ return (!bgCall.isIdle() && bgCall.getState() != Call.State.DIALING)
+ || (!fgCall.isIdle() && fgCall.getState() != Call.State.DIALING);
}
private void updateHalCommandToUse() {
diff --git a/src/java/com/android/internal/telephony/ims/ImsResolver.java b/src/java/com/android/internal/telephony/ims/ImsResolver.java
index d8b0fd4..b95911f 100644
--- a/src/java/com/android/internal/telephony/ims/ImsResolver.java
+++ b/src/java/com/android/internal/telephony/ims/ImsResolver.java
@@ -164,14 +164,19 @@
}
private static class OverrideConfig {
+ public final String packageName;
public final int slotId;
+ public final int userId;
public final boolean isCarrierService;
- public final Map<Integer, String> featureTypeToPackageMap;
+ public final int[] featureTypes;
- OverrideConfig(int slotIndex, boolean isCarrier, Map<Integer, String> feature) {
+ OverrideConfig(String pkgName, int slotIndex, int userIndex, boolean isCarrier,
+ int[] features) {
+ packageName = pkgName;
slotId = slotIndex;
+ userId = userIndex;
isCarrierService = isCarrier;
- featureTypeToPackageMap = feature;
+ featureTypes = features;
}
}
@@ -552,11 +557,15 @@
}
case HANDLER_OVERRIDE_IMS_SERVICE_CONFIG: {
OverrideConfig config = (OverrideConfig) msg.obj;
+ setPackageNameUserOverride(config.packageName, config.userId);
+ Map<Integer, String> featureConfig = new HashMap<>();
+ for (int featureType : config.featureTypes) {
+ featureConfig.put(featureType, config.packageName);
+ }
if (config.isCarrierService) {
- overrideCarrierService(config.slotId,
- config.featureTypeToPackageMap);
+ overrideCarrierService(config.slotId, featureConfig);
} else {
- overrideDeviceService(config.featureTypeToPackageMap);
+ overrideDeviceService(featureConfig);
}
break;
}
@@ -618,6 +627,8 @@
// Array index corresponds to slot, per slot there is a feature->package name mapping.
// should only be accessed from handler
private final SparseArray<SparseArray<String>> mOverrideServices;
+ //Used during testing, restricts the ImsService to be bound on a specific user.
+ private final Map<String, UserHandle> mImsServiceTestUserRestrictions = new HashMap<>();
// Outer array index corresponds to Slot Id, Maps ImsFeature.FEATURE->bound ImsServiceController
// Locked on mBoundServicesLock
private final SparseArray<SparseArray<ImsServiceController>> mBoundImsServicesByFeature;
@@ -899,14 +910,15 @@
}
// Used for testing only.
- public boolean overrideImsServiceConfiguration(int slotId, boolean isCarrierService,
- Map<Integer, String> featureConfig) {
+ public boolean overrideImsServiceConfiguration(String packageName, int slotId, int userId,
+ boolean isCarrierService, int[] overrideFeatureTypes) {
if (slotId < 0 || slotId >= mNumSlots) {
Log.w(TAG, "overrideImsServiceConfiguration: invalid slotId!");
return false;
}
- OverrideConfig overrideConfig = new OverrideConfig(slotId, isCarrierService, featureConfig);
+ OverrideConfig overrideConfig = new OverrideConfig(packageName, slotId, userId,
+ isCarrierService, overrideFeatureTypes);
Message.obtain(mHandler, HANDLER_OVERRIDE_IMS_SERVICE_CONFIG, overrideConfig)
.sendToTarget();
return true;
@@ -947,10 +959,14 @@
}
// not synchronized, access in handler ONLY.
- private void removeOverridePackageName(int slotId) {
+ private Set<String> removeOverridePackageName(int slotId) {
+ Set<String> removedOverrides = new HashSet<>();
for (int f = ImsFeature.FEATURE_EMERGENCY_MMTEL; f < ImsFeature.FEATURE_MAX; f++) {
- getOverridePackageName(slotId).remove(f);
+ SparseArray<String> overrides = getOverridePackageName(slotId);
+ String packageName = overrides.removeReturnOld(f);
+ if (packageName != null) removedOverrides.add(packageName);
}
+ return removedOverrides;
}
// not synchronized, access in handler ONLY.
@@ -960,6 +976,22 @@
}
// not synchronized, access in handler ONLY.
+ private void setPackageNameUserOverride(String packageName, int userId) {
+ if (packageName == null || packageName.isEmpty() || userId == UserHandle.USER_NULL) return;
+ Log.i(TAG, "setPackageNameUserOverride: set for " + packageName + ", user= " + userId);
+ mImsServiceTestUserRestrictions.put(packageName, UserHandle.of(userId));
+ }
+
+ // not synchronized, access in handler ONLY.
+ private void clearPackageNameUserOverride(String packageName) {
+ UserHandle handle = mImsServiceTestUserRestrictions.remove(packageName);
+ if (handle != null) {
+ Log.i(TAG, "clearPackageNameUserOverride: cleared for " + packageName
+ + "on user " + handle);
+ }
+ }
+
+ // not synchronized, access in handler ONLY.
private @Nullable String getOverridePackageName(int slotId,
@ImsFeature.FeatureType int featureType) {
return getOverridePackageName(slotId).get(featureType);
@@ -1266,6 +1298,7 @@
match.controllerFactory);
ImsServiceInfo newMatch = imsServices.isEmpty() ? null : imsServices.getFirst();
if (newMatch == null) {
+ clearPackageNameUserOverride(match.name.getPackageName());
// The package doesn't exist anymore on any user, so remove
mInstalledServicesCache.remove(match.name);
mEventLog.log("maybeRemovedImsService - removing ImsService: " + match);
@@ -1327,11 +1360,10 @@
private List<Integer> getSlotsForActiveCarrierService(ImsServiceInfo info) {
if (info == null) return Collections.emptyList();
if (mFeatureFlags.imsResolverUserAware()) {
- Set<UserHandle> activeUsers = getActiveUsers();
- activeUsers.retainAll(info.users);
- if (activeUsers.isEmpty()) {
+ UserHandle activeUser = getUserForBind(info);
+ if (activeUser == null) {
Log.d(TAG, "getSlotsForActiveCarrierService: ImsService " + info.name + "is not "
- + "configured to run for users " + activeUsers + ", skipping...");
+ + "configured to run for any users, skipping...");
return Collections.emptyList();
}
}
@@ -1542,7 +1574,10 @@
private void clearCarrierServiceOverrides(int slotId) {
Log.i(TAG, "clearing carrier ImsService overrides");
mEventLog.log("clearing carrier ImsService overrides");
- removeOverridePackageName(slotId);
+ Set<String> removedPackages = removeOverridePackageName(slotId);
+ for (String pkg : removedPackages) {
+ clearPackageNameUserOverride(pkg);
+ }
carrierConfigChanged(slotId, getSubId(slotId));
}
@@ -1560,6 +1595,7 @@
+ oldPackageName + " -> " + overridePackageName);
mEventLog.log("overrideDeviceService - device package changed (override): "
+ oldPackageName + " -> " + overridePackageName);
+ clearPackageNameUserOverride(oldPackageName);
setDeviceConfiguration(overridePackageName, featureType);
ImsServiceInfo info = getVisibleImsServiceInfoFromCache(overridePackageName);
if (info == null || info.featureFromMetadata) {
@@ -1908,6 +1944,13 @@
List<UserHandle> activeUsers = getActiveUsers().stream()
.filter(info.users::contains).toList();
if (activeUsers.isEmpty()) return null;
+ // If there is a test restriction in place for this package, prioritize that restriction
+ UserHandle testRestriction = mImsServiceTestUserRestrictions.getOrDefault(
+ info.name.getPackageName(), null);
+ if (testRestriction != null && activeUsers.stream()
+ .anyMatch(u -> Objects.equals(u, testRestriction))) {
+ return testRestriction;
+ }
// Prioritize the User that Telephony is in, since it is always running
if (activeUsers.stream()
.anyMatch(u -> Objects.equals(u, mContext.getUser()))) {
@@ -1955,11 +1998,10 @@
return match;
}
if (match == null) return null;
- Set<UserHandle> activeUsers = getActiveUsers();
- activeUsers.retainAll(match.users);
+ UserHandle targetUser = getUserForBind(match);
Log.d(TAG, "getVisibleImsServiceInfoFromCache: " + packageName + ", match=" + match
- + ", activeUsers=" + activeUsers);
- if (!activeUsers.isEmpty()) return match; else return null;
+ + ", targetUser=" + targetUser);
+ if (targetUser != null) return match; else return null;
}
/**
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index bbf9b71..f181852 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -3947,14 +3947,25 @@
return false;
}
- if (!isCarrierRoamingNtnEligible(phone)) {
- plogd("isInCarrierRoamingNbIotNtn: phone associated with subId "
- + phone.getSubId()
- + " is not carrier roaming ntn eligible.");
+ if (phone == null) {
+ plogd("isInCarrierRoamingNbIotNtn: phone is null");
return false;
}
int subId = phone.getSubId();
+ if (!isSatelliteSupportedViaCarrier(subId)) {
+ plogd("isInCarrierRoamingNbIotNtn[phoneId=" + phone.getPhoneId()
+ + "]: satellite is not supported via carrier");
+ return false;
+ }
+
+ int carrierRoamingNtnConnectType = getCarrierRoamingNtnConnectType(subId);
+ if (carrierRoamingNtnConnectType != CARRIER_ROAMING_NTN_CONNECT_MANUAL) {
+ plogd("isInCarrierRoamingNbIotNtn[phoneId=" + phone.getPhoneId() + "]: not manual "
+ + "connect. carrierRoamingNtnConnectType = " + carrierRoamingNtnConnectType);
+ return false;
+ }
+
if (subId != getSelectedSatelliteSubId()) {
plogd("isInCarrierRoamingNbIotNtn: subId=" + subId
+ " does not match satellite subId=" + getSelectedSatelliteSubId());
@@ -4309,7 +4320,7 @@
RequestSatelliteEnabledArgument argument =
(RequestSatelliteEnabledArgument) request.argument;
handlePersistentLoggingOnSessionStart(argument);
- selectBindingSatelliteSubscription(true);
+ selectBindingSatelliteSubscription(argument.enableSatellite);
SatelliteModemEnableRequestAttributes enableRequestAttributes =
createModemEnableRequest(argument);
if (enableRequestAttributes == null) {
@@ -7219,6 +7230,11 @@
return false;
}
+ if (!mIsRadioOn) {
+ plogd("isCarrierRoamingNtnEligible: radio is off");
+ return false;
+ }
+
if (phone == null) {
plogd("isCarrierRoamingNtnEligible: phone is null");
return false;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index dd71c44..9db25b6 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -80,6 +80,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -162,8 +163,7 @@
// this needs to be here, because on bootup we dont know which index maps to which UiccSlot
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private CommandsInterface[] mCis;
- @VisibleForTesting
- public UiccSlot[] mUiccSlots;
+ private UiccSlot[] mUiccSlots;
private int[] mPhoneIdToSlotId;
private boolean mIsSlotStatusSupported = true;
@@ -491,6 +491,27 @@
}
/**
+ * Set UiccSlot object for a specific physical slot index on the device.
+ *
+ * This is only supposed to be used internally and by unit tests.
+ *
+ * @param slotId Slot index
+ * @param slot Slot object
+ */
+ @VisibleForTesting
+ public void setUiccSlot(int slotId, @NonNull UiccSlot slot) {
+ synchronized (mLock) {
+ if (!isValidSlotIndex(slotId)) {
+ throw new ArrayIndexOutOfBoundsException("Invalid slot index: " + slotId);
+ }
+ if (mUiccSlots[slotId] != null) {
+ mUiccSlots[slotId].dispose();
+ }
+ mUiccSlots[slotId] = Objects.requireNonNull(slot);
+ }
+ }
+
+ /**
* API to get UiccSlot object for a given phone id
* @return UiccSlot object for the given phone id
*/
@@ -1076,7 +1097,7 @@
log("Creating mUiccSlots[" + slotId + "]; mUiccSlots.length = "
+ mUiccSlots.length);
}
- mUiccSlots[slotId] = new UiccSlot(mContext, true);
+ setUiccSlot(slotId, new UiccSlot(mContext, true));
}
mUiccSlots[slotId].update(mCis[index], status, index, slotId);
@@ -1353,7 +1374,7 @@
if (VDBG) {
log("Creating mUiccSlot[" + i + "]; mUiccSlots.length = " + mUiccSlots.length);
}
- mUiccSlots[i] = new UiccSlot(mContext, isActive);
+ setUiccSlot(i, new UiccSlot(mContext, isActive));
}
if (isActive) { // check isActive flag so that we don't have to iterate through all
@@ -1803,6 +1824,17 @@
return mCardStrings;
}
+ /**
+ * Release resources. Must be called each time this class is used.
+ */
+ @VisibleForTesting
+ public void dispose() {
+ for (var slot : mUiccSlots) {
+ slot.dispose();
+ }
+ mUiccSlots = null;
+ }
+
public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
pw.println("mIsCdmaSupported=" + isCdmaSupported(mContext));
diff --git a/src/java/com/android/internal/telephony/uicc/UiccPort.java b/src/java/com/android/internal/telephony/uicc/UiccPort.java
index 905db70..e1228e9 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccPort.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccPort.java
@@ -440,7 +440,13 @@
* removal or modem reset. The obsoleted records may trigger a redundant release of logical
* channel that may have been assigned to other client.
*/
+ @SuppressWarnings("GuardedBy")
private void cleanupOpenLogicalChannelRecordsIfNeeded() {
+ // This check may raise GuardedBy warning, but we need it as long as this method is called
+ // from finalize(). We can remove it from there once UiccPort is fully protected against
+ // resource leak (e.g. with CloseGuard) and all (direct and indirect) users are fixed.
+ if (mOpenChannelRecords == null) return;
+
synchronized (mOpenChannelRecords) {
for (OpenLogicalChannelRecord record : mOpenChannelRecords) {
if (DBG) log("Clean up " + record);
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index db10271..d986c93 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -391,6 +391,13 @@
}
}
+ /**
+ * Release resources. Must be called each time this class is used.
+ */
+ public void dispose() {
+ nullifyUiccCard(false);
+ }
+
public boolean isStateUnknown() {
// CardState is not specific to any port index, use default port.
CardState cardState = mCardState.get(TelephonyManager.DEFAULT_PORT_INDEX);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java
index 3b637c9..1e1e43f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java
@@ -26,6 +26,8 @@
import android.os.Looper;
+import com.android.internal.telephony.flags.FeatureFlagsImpl;
+
import org.junit.Ignore;
/**
@@ -465,7 +467,8 @@
if (Looper.myLooper() == null) {
Looper.prepare();
}
- SmsUsageMonitor monitor = new SmsUsageMonitor(TestApplication.getAppContext());
+ SmsUsageMonitor monitor = new SmsUsageMonitor(TestApplication.getAppContext(),
+ new FeatureFlagsImpl());
for (ShortCodeTest test : sShortCodeTests) {
assertEquals("country: " + test.countryIso + " number: " + test.address,
test.category, monitor.checkDestination(test.address, test.countryIso));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index d80c9a2..88eea32 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -747,6 +747,8 @@
doReturn(mDataRetryManager).when(mDataNetworkController).getDataRetryManager();
doReturn(mCarrierPrivilegesTracker).when(mPhone).getCarrierPrivilegesTracker();
doReturn(0).when(mPhone).getPhoneId();
+ doReturn(true).when(mPhone).hasCalling();
+ doReturn(true).when(mPhone2).hasCalling();
//mUiccController
doReturn(mUiccCardApplication3gpp).when(mUiccController).getUiccCardApplication(anyInt(),
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
index 33b195c..bfdca0f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
@@ -69,6 +69,7 @@
@After
public void tearDown() throws Exception {
+ mUiccCard.dispose();
mUiccCard = null;
mIccIoResult = null;
super.tearDown();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
index 58a8153..3343570 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
@@ -15,8 +15,6 @@
*/
package com.android.internal.telephony.uicc;
-import static junit.framework.Assert.fail;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -131,6 +129,7 @@
@After
public void tearDown() throws Exception {
+ if (mUiccControllerUT != null) mUiccControllerUT.dispose();
mUiccControllerUT = null;
super.tearDown();
}
@@ -145,6 +144,7 @@
com.android.internal.R.array.non_removable_euicc_slots,
nonRemovableEuiccSlots);
replaceInstance(UiccController.class, "mInstance", null, null);
+ mUiccControllerUT.dispose();
mUiccControllerUT = UiccController.make(mContext, mFeatureFlags);
processAllMessages();
}
@@ -250,7 +250,7 @@
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots
- mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockSlot);
doReturn(mMockCard).when(mMockSlot).getUiccCard();
doReturn(mMockPort).when(mMockCard).getUiccPort(0);
doReturn("A1B2C3D4").when(mMockPort).getIccId();
@@ -296,7 +296,7 @@
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots
- mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockSlot);
doReturn(true).when(mMockSlot).isEuicc();
// simulate slot status loaded so that the UiccController sets the card ID
@@ -323,7 +323,7 @@
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots
- mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockSlot);
doReturn(true).when(mMockSlot).isEuicc();
// simulate slot status loaded so that the UiccController sets the card ID
@@ -351,7 +351,7 @@
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots
- mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockSlot);
doReturn(false).when(mMockSlot).isEuicc();
doReturn(mMockCard).when(mMockSlot).getUiccCard();
doReturn("ASDF1234").when(mMockCard).getCardId();
@@ -402,7 +402,7 @@
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots
- mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockSlot);
doReturn(false).when(mMockSlot).isEuicc();
doReturn(mMockCard).when(mMockSlot).getUiccCard();
doReturn("ASDF1234").when(mMockCard).getCardId();
@@ -453,7 +453,7 @@
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots
- mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockSlot);
doReturn(true).when(mMockSlot).isEuicc();
doReturn(null).when(mMockSlot).getUiccCard();
doReturn(false).when(mMockSlot).isRemovable();
@@ -499,21 +499,17 @@
* The default eUICC should not be the removable slot if there is a built-in eUICC.
*/
@Test
- public void testDefaultEuiccIsNotRemovable() {
- try {
- reconfigureSlots(2, new int[]{ 1 } /* non-removable slot */);
- } catch (Exception e) {
- fail("Unable to reconfigure slots.");
- }
+ public void testDefaultEuiccIsNotRemovable() throws Exception {
+ reconfigureSlots(2, new int[]{ 1 } /* non-removable slot */);
// Give UiccController a real context so it can use shared preferences
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots so that [0] is a removable eUICC and [1] is built-in
- mUiccControllerUT.mUiccSlots[0] = mMockRemovableEuiccSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockRemovableEuiccSlot);
doReturn(true).when(mMockRemovableEuiccSlot).isEuicc();
doReturn(true).when(mMockRemovableEuiccSlot).isRemovable();
- mUiccControllerUT.mUiccSlots[1] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(1, mMockSlot);
doReturn(true).when(mMockSlot).isEuicc();
doReturn(false).when(mMockSlot).isRemovable();
@@ -550,21 +546,17 @@
* not depend on the order of the slots.
*/
@Test
- public void testDefaultEuiccIsNotRemovable_swapSlotOrder() {
- try {
- reconfigureSlots(2, new int[]{ 0 } /* non-removable slot */);
- } catch (Exception e) {
- fail("Unable to reconfigure slots.");
- }
+ public void testDefaultEuiccIsNotRemovable_swapSlotOrder() throws Exception {
+ reconfigureSlots(2, new int[]{ 0 } /* non-removable slot */);
// Give UiccController a real context so it can use shared preferences
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots so that [0] is a built-in eUICC and [1] is removable
- mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockSlot);
doReturn(true).when(mMockSlot).isEuicc();
doReturn(false).when(mMockSlot).isRemovable();
- mUiccControllerUT.mUiccSlots[1] = mMockRemovableEuiccSlot;
+ mUiccControllerUT.setUiccSlot(1, mMockRemovableEuiccSlot);
doReturn(true).when(mMockRemovableEuiccSlot).isEuicc();
doReturn(true).when(mMockRemovableEuiccSlot).isRemovable();
@@ -603,21 +595,17 @@
* the removable eUICC.
*/
@Test
- public void testDefaultEuiccIsNotRemovable_EuiccIsInactive() {
- try {
- reconfigureSlots(2, new int[]{ 1 } /* non-removable slot */);
- } catch (Exception e) {
- fail();
- }
+ public void testDefaultEuiccIsNotRemovable_EuiccIsInactive() throws Exception {
+ reconfigureSlots(2, new int[]{ 1 } /* non-removable slot */);
// Give UiccController a real context so it can use shared preferences
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots. Slot 0 is inactive here.
- mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockSlot);
doReturn(true).when(mMockSlot).isEuicc();
doReturn(false).when(mMockSlot).isRemovable();
- mUiccControllerUT.mUiccSlots[1] = mMockRemovableEuiccSlot;
+ mUiccControllerUT.setUiccSlot(1, mMockRemovableEuiccSlot);
doReturn(true).when(mMockRemovableEuiccSlot).isEuicc();
doReturn(true).when(mMockRemovableEuiccSlot).isRemovable();
@@ -669,7 +657,7 @@
mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
// Mock out UiccSlots
- mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ mUiccControllerUT.setUiccSlot(0, mMockSlot);
doReturn(true).when(mMockSlot).isEuicc();
doReturn(null).when(mMockSlot).getUiccCard();
//doReturn("123451234567890").when(mMockSlot).getIccId();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
index a2b42af..47b7c53 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
@@ -82,6 +82,7 @@
@After
public void tearDown() throws Exception {
+ mUiccPort.dispose();
mUiccPort = null;
mIccIoResult = null;
super.tearDown();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
index 671f273..8449ecc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
@@ -103,6 +103,7 @@
mTestHandlerThread = null;
mTestHandler.removeCallbacksAndMessages(null);
mTestHandler = null;
+ mUiccSlot.dispose();
mUiccSlot = null;
super.tearDown();
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
index f88bc1e..c9b159c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
@@ -51,6 +51,8 @@
private static final int CARD_COUNT = 1;
private static final String PROVISIONING_PACKAGE_NAME = "test.provisioning.package";
+ private UiccCard mUiccCardToDispose;
+
// Mocked classes
private Resources mResources;
@@ -77,6 +79,9 @@
@After
public void tearDown() throws Exception {
super.tearDown();
+
+ if (mUiccCardToDispose != null) mUiccCardToDispose.dispose();
+ mUiccCardToDispose = null;
}
@Test @SmallTest
@@ -99,7 +104,7 @@
msg.what = integerArgumentCaptor.getValue();
// The first broadcast should be sent after initialization.
- UiccCard card = new UiccCard(mContext, mSimulatedCommands,
+ UiccCard card = mUiccCardToDispose = new UiccCard(mContext, mSimulatedCommands,
makeCardStatus(CardState.CARDSTATE_PRESENT), 0 /* phoneId */, new Object(),
IccSlotStatus.MultipleEnabledProfilesMode.NONE);
when(UiccController.getInstance().getUiccCardForPhone(0)).thenReturn(card);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
index bcb5c4c..560c9aa 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
@@ -109,7 +109,10 @@
mHandler.removeCallbacksAndMessages(null);
mHandler = null;
}
- mEuiccCard = null;
+ if (mEuiccCard != null) {
+ mEuiccCard.dispose();
+ mEuiccCard = null;
+ }
super.tearDown();
}
@@ -132,6 +135,7 @@
@Test
public void testPassEidInConstructor() {
mMockIccCardStatus.eid = "1A2B3C4D";
+ mEuiccCard.dispose();
mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
mMockIccCardStatus, 0 /* phoneId */, new Object(),
IccSlotStatus.MultipleEnabledProfilesMode.NONE);
@@ -154,6 +158,7 @@
public void testLoadEidAndNotifyRegistrants() {
int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000");
mHandler.post(() -> {
+ mEuiccCard.dispose();
mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
mMockIccCardStatus, 0 /* phoneId */, new Object(),
IccSlotStatus.MultipleEnabledProfilesMode.NONE);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccPortTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccPortTest.java
index 2fef021..f0f1af3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccPortTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccPortTest.java
@@ -141,6 +141,7 @@
public void tearDown() throws Exception {
mHandler.removeCallbacksAndMessages(null);
mHandler = null;
+ mEuiccPort.dispose();
mEuiccPort = null;
super.tearDown();
}