Merge "Return false if radio is off in isCarrierRoamingNtnEligible" into main
diff --git a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index 1aaa1d3..732582f 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -41,6 +41,7 @@
import android.telephony.ims.ImsCallSession;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.MediaQualityStatus;
+import android.telephony.satellite.NtnSignalStrength;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.telephony.Rlog;
@@ -348,6 +349,13 @@
sender.getSubId(), availableServices);
}
+ @Override
+ public void notifyCarrierRoamingNtnSignalStrengthChanged(Phone sender,
+ @NonNull NtnSignalStrength ntnSignalStrength) {
+ mTelephonyRegistryMgr.notifyCarrierRoamingNtnSignalStrengthChanged(
+ sender.getSubId(), ntnSignalStrength);
+ }
+
/**
* Convert the {@link Call.State} enum into the PreciseCallState.PRECISE_CALL_STATE_* constants
* for the public API.
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 ca82d31..ab9be76 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -74,6 +74,7 @@
import android.telephony.ims.RegistrationManager;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.telephony.satellite.NtnSignalStrength;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
@@ -660,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
@@ -1966,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() {
@@ -5380,6 +5388,18 @@
mNotifier.notifyCarrierRoamingNtnAvailableServicesChanged(this, availableServices);
}
+ /**
+ * Notify external listeners that carrier roaming non-terrestrial network
+ * signal strength changed.
+ * @param ntnSignalStrength non-terrestrial network signal strength.
+ */
+ public void notifyCarrierRoamingNtnSignalStrengthChanged(
+ @NonNull NtnSignalStrength ntnSignalStrength) {
+ logd("notifyCarrierRoamingNtnSignalStrengthChanged: ntnSignalStrength="
+ + ntnSignalStrength.getLevel());
+ mNotifier.notifyCarrierRoamingNtnSignalStrengthChanged(this, ntnSignalStrength);
+ }
+
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Phone: subId=" + getSubId());
pw.println(" mPhoneId=" + mPhoneId);
diff --git a/src/java/com/android/internal/telephony/PhoneNotifier.java b/src/java/com/android/internal/telephony/PhoneNotifier.java
index f652370..faf4fd1 100644
--- a/src/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/PhoneNotifier.java
@@ -38,6 +38,7 @@
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.MediaQualityStatus;
+import android.telephony.satellite.NtnSignalStrength;
import java.util.List;
import java.util.Set;
@@ -169,4 +170,8 @@
/** Notify carrier roaming non-terrestrial available services changed. */
void notifyCarrierRoamingNtnAvailableServicesChanged(
Phone sender, @NetworkRegistrationInfo.ServiceType int[] availableServices);
+
+ /** Notify carrier roaming non-terrestrial network signal strength changed. */
+ void notifyCarrierRoamingNtnSignalStrengthChanged(Phone sender,
+ @NonNull NtnSignalStrength ntnSignalStrength);
}
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 02c410d..21d3f7a 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -291,6 +291,7 @@
protected static final int EVENT_SATELLITE_REGISTRATION_FAILURE = 54;
private static final int EVENT_TERRESTRIAL_NETWORK_AVAILABLE_CHANGED = 55;
private static final int EVENT_SET_NETWORK_SELECTION_AUTO_DONE = 56;
+ private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 57;
@NonNull private static SatelliteController sInstance;
@NonNull private final Context mContext;
@@ -516,6 +517,10 @@
@NonNull private final Map<Integer, List<Integer>>
mSatModeCapabilitiesForCarrierRoaming = new HashMap<>();
+ @GuardedBy("mSatelliteConnectedLock")
+ private SparseArray<NtnSignalStrength> mLastNotifiedCarrierRoamingNtnSignalStrength =
+ new SparseArray<>();
+
/**
* This is used for testing only. When mEnforcedEmergencyCallToSatelliteHandoverType is valid,
* Telephony will ignore the IMS registration status and cellular availability, and always send
@@ -815,6 +820,7 @@
registerForPendingDatagramCount();
registerForSatelliteModemStateChanged();
registerForServiceStateChanged();
+ registerForSignalStrengthChanged();
mContentResolver = mContext.getContentResolver();
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
@@ -1701,6 +1707,7 @@
ploge("EVENT_SATELLITE_MODEM_STATE_CHANGED: result is null");
} else {
handleEventSatelliteModemStateChanged((int) ar.result);
+ updateLastNotifiedCarrierRoamingNtnSignalStrengthAndNotify(getSatellitePhone());
}
break;
@@ -1790,6 +1797,7 @@
ploge("EVENT_NTN_SIGNAL_STRENGTH_CHANGED: result is null");
} else {
handleEventNtnSignalStrengthChanged((NtnSignalStrength) ar.result);
+ updateLastNotifiedCarrierRoamingNtnSignalStrengthAndNotify(getSatellitePhone());
}
break;
}
@@ -2003,6 +2011,13 @@
break;
}
+ case EVENT_SIGNAL_STRENGTH_CHANGED: {
+ ar = (AsyncResult) msg.obj;
+ int phoneId = (int) ar.userObj;
+ updateLastNotifiedCarrierRoamingNtnSignalStrengthAndNotify(
+ PhoneFactory.getPhone(phoneId));
+ }
+
default:
Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " +
msg.what);
@@ -3896,24 +3911,7 @@
* else {@return false}
*/
public boolean isInCarrierRoamingNbIotNtn() {
- if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
- plogd("isInCarrierRoamingNbIotNtn: carrier roaming nb iot ntn "
- + "feature flag is disabled");
- return false;
- }
-
- if (!isSatelliteEnabled()) {
- plogd("iisInCarrierRoamingNbIotNtn: satellite is disabled");
- return false;
- }
-
- Phone satellitePhone = getSatellitePhone();
- if (!isCarrierRoamingNtnEligible(satellitePhone)) {
- plogd("isInCarrierRoamingNbIotNtn: not carrier roaming ntn eligible.");
- return false;
- }
- plogd("isInCarrierRoamingNbIotNtn: carrier roaming ntn eligible.");
- return true;
+ return isInCarrierRoamingNbIotNtn(getSatellitePhone());
}
/**
@@ -5693,6 +5691,13 @@
}
}
+ private void registerForSignalStrengthChanged() {
+ for (Phone phone : PhoneFactory.getPhones()) {
+ phone.getSignalStrengthController().registerForSignalStrengthChanged(this,
+ EVENT_SIGNAL_STRENGTH_CHANGED, phone.getPhoneId());
+ }
+ }
+
private void handleEventServiceStateChanged() {
handleStateChangedForCarrierRoamingNtnEligibility();
handleServiceStateForSatelliteConnectionViaCarrier();
@@ -5758,6 +5763,7 @@
mWasSatelliteConnectedViaCarrier.put(subId, false);
}
updateLastNotifiedNtnModeAndNotify(phone);
+ updateLastNotifiedCarrierRoamingNtnSignalStrengthAndNotify(phone);
}
}
determineAutoConnectSystemNotification();
@@ -5778,6 +5784,7 @@
if (!initialized) mInitialized.put(subId, true);
mLastNotifiedNtnMode.put(subId, currNtnMode);
phone.notifyCarrierRoamingNtnModeChanged(currNtnMode);
+ updateLastNotifiedCarrierRoamingNtnSignalStrengthAndNotify(phone);
logCarrierRoamingSatelliteSessionStats(phone, lastNotifiedNtnMode, currNtnMode);
if(mIsNotificationShowing && !currNtnMode) {
dismissSatelliteNotification();
@@ -7699,6 +7706,50 @@
logd("notifyEnabledStateChanged to " + isEnabled);
}
+ private NtnSignalStrength getCarrierRoamingNtnSignalStrength(@NonNull Phone phone) {
+ NtnSignalStrength carrierRoamingNtnSignalStrength = new NtnSignalStrength(
+ NTN_SIGNAL_STRENGTH_NONE);
+
+ if (isInCarrierRoamingNbIotNtn(phone)) {
+ if (mSatelliteSessionController.isInConnectedState()) {
+ synchronized (mNtnSignalsStrengthLock) {
+ carrierRoamingNtnSignalStrength = mNtnSignalStrength;
+ }
+ plogd("getCarrierRoamingNtnSignalStrength[phoneId=" + phone.getPhoneId()
+ + "]: in carrier roaming nb iot ntn mode.");
+ }
+ } else if (isInSatelliteModeForCarrierRoaming(phone)) {
+ ServiceState serviceState = phone.getServiceState();
+ if (serviceState.getState() != ServiceState.STATE_OUT_OF_SERVICE) {
+ carrierRoamingNtnSignalStrength = new NtnSignalStrength(
+ phone.getSignalStrength().getLevel());
+ plogd("getCarrierRoamingNtnSignalStrength[phoneId=" + phone.getPhoneId()
+ + "]: is in satellite mode for carrier roaming.");
+ }
+ }
+
+ return carrierRoamingNtnSignalStrength;
+ }
+
+ private void updateLastNotifiedCarrierRoamingNtnSignalStrengthAndNotify(@Nullable Phone phone) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) return;
+ if (phone == null) {
+ return;
+ }
+
+ NtnSignalStrength currSignalStrength = getCarrierRoamingNtnSignalStrength(phone);
+ int subId = phone.getSubId();
+ synchronized (mSatelliteConnectedLock) {
+ NtnSignalStrength lastNotifiedSignalStrength =
+ mLastNotifiedCarrierRoamingNtnSignalStrength.get(subId);
+ if (lastNotifiedSignalStrength == null
+ || lastNotifiedSignalStrength.getLevel() != currSignalStrength.getLevel()) {
+ mLastNotifiedCarrierRoamingNtnSignalStrength.put(subId, currSignalStrength);
+ phone.notifyCarrierRoamingNtnSignalStrengthChanged(currSignalStrength);
+ }
+ }
+ }
+
/** Returns whether to send SMS to DatagramDispatcher or not. */
public boolean shouldSendSmsToDatagramDispatcher(@NonNull Phone phone) {
if (!isInCarrierRoamingNbIotNtn(phone)) {
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
index 8f299f8..19c3f65 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
@@ -593,6 +593,17 @@
}
/**
+ * Get whether state machine is in connected state.
+ *
+ * @return {@code true} if state machine is in connected state and {@code false} otherwise.
+ */
+ public boolean isInConnectedState() {
+ if (DBG) plogd("isInConnectedState: getCurrentState=" + getCurrentState());
+ return getCurrentState() == mConnectedState;
+ }
+
+
+ /**
* Release all resource.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
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/android/telephony/ims/RcsConfigTest.java b/tests/telephonytests/src/android/telephony/ims/RcsConfigTest.java
index 25cdc82..c690ab4 100644
--- a/tests/telephonytests/src/android/telephony/ims/RcsConfigTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/RcsConfigTest.java
@@ -36,6 +36,7 @@
import com.android.internal.telephony.FakeTelephonyProvider;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -176,6 +177,11 @@
createFakeSimInfo();
}
+ @After
+ public void tearDown() {
+ mFakeTelephonyProvider.close();
+ }
+
@Test
@SmallTest
public void testLoadAndUpdateConfigForSub() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
index c923f69..101c668 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
@@ -196,4 +196,11 @@
selectionArgs);
return count;
}
+
+ /**
+ * Release resources. Must be called each time this class is used.
+ */
+ public void close() {
+ mDbHelper.close();
+ }
}
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/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 0b7ac22..2ff38b2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -69,6 +69,7 @@
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
+import android.telephony.satellite.NtnSignalStrength;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.text.TextUtils;
@@ -131,6 +132,7 @@
private boolean mCarrierRoamingNtnMode;
private boolean mCarrierRoamingNtnEligible;
private List<Integer> mCarrierRoamingNtnAvailableServices;
+ private NtnSignalStrength mCarrierRoamingNtnSignalStrength;
private boolean mIsSatelliteEnabled;
// All events contribute to TelephonyRegistry#isPhoneStatePermissionRequired
@@ -343,6 +345,12 @@
invocationCount.incrementAndGet();
mCarrierRoamingNtnAvailableServices = services;
}
+
+ @Override
+ public void onCarrierRoamingNtnSignalStrengthChanged(NtnSignalStrength ntnSignalStrength) {
+ invocationCount.incrementAndGet();
+ mCarrierRoamingNtnSignalStrength = ntnSignalStrength;
+ }
}
public class MySatelliteStateChangeListener implements ISatelliteStateChangeListener {
@@ -1743,6 +1751,24 @@
}
@Test
+ @EnableFlags(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public void testNotifyCarrierRoamingNtnSignalStrengthChanged() {
+ int subId = INVALID_SUBSCRIPTION_ID;
+ doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+ doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
+ int[] events = {TelephonyCallback.EVENT_CARRIER_ROAMING_NTN_SIGNAL_STRENGTH_CHANGED};
+
+ mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+ mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+
+ mTelephonyRegistry.notifyCarrierRoamingNtnSignalStrengthChanged(subId,
+ new NtnSignalStrength(NtnSignalStrength.NTN_SIGNAL_STRENGTH_GOOD));
+ processAllMessages();
+ assertEquals(mCarrierRoamingNtnSignalStrength.getLevel(),
+ NtnSignalStrength.NTN_SIGNAL_STRENGTH_GOOD);
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_SATELLITE_STATE_CHANGE_LISTENER)
public void testNotifySatelliteStateChanged_onRegistration_getNotified() {
MySatelliteStateChangeListener listener = new MySatelliteStateChangeListener();
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/satellite/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
index 5dfaa52..7d30ca8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -146,6 +146,7 @@
import android.telephony.NetworkRegistrationInfo;
import android.telephony.Rlog;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.satellite.INtnSignalStrengthCallback;
@@ -576,9 +577,11 @@
when(mPhone.getServiceState()).thenReturn(mServiceState);
when(mPhone.getSubId()).thenReturn(SUB_ID);
when(mPhone.getPhoneId()).thenReturn(0);
+ when(mPhone.getSignalStrengthController()).thenReturn(mSignalStrengthController);
when(mPhone2.getServiceState()).thenReturn(mServiceState2);
when(mPhone2.getSubId()).thenReturn(SUB_ID1);
when(mPhone2.getPhoneId()).thenReturn(1);
+ when(mPhone2.getSignalStrengthController()).thenReturn(mSignalStrengthController);
mContextFixture.putStringArrayResource(
R.array.config_satellite_providers,
@@ -4228,6 +4231,43 @@
}
@Test
+ public void testNotifyCarrierRoamingNtnSignalStrengthChanged() {
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+
+ sendSignalStrengthChangedEvent(mPhone.getPhoneId());
+ processAllMessages();
+ ArgumentCaptor<NtnSignalStrength> captor = ArgumentCaptor.forClass(NtnSignalStrength.class);
+ verify(mPhone, times(1)).notifyCarrierRoamingNtnSignalStrengthChanged(
+ captor.capture());
+ NtnSignalStrength actualSignalStrength = captor.getValue();
+ assertEquals(NTN_SIGNAL_STRENGTH_NONE, actualSignalStrength.getLevel());
+ clearInvocations(mPhone);
+
+ when(mSignalStrength.getLevel()).thenReturn(SignalStrength.SIGNAL_STRENGTH_GOOD);
+ when(mPhone.getSignalStrength()).thenReturn(mSignalStrength);
+ mCarrierConfigBundle.putInt(KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT, 1 * 60);
+ mCarrierConfigBundle.putBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true);
+ for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair
+ : mCarrierConfigChangedListenerList) {
+ pair.first.execute(() -> pair.second.onCarrierConfigChanged(
+ /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0)
+ );
+ }
+ processAllMessages();
+ when(mServiceState.isUsingNonTerrestrialNetwork()).thenReturn(true);
+ when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+ sendServiceStateChangedEvent();
+ processAllMessages();
+ captor = ArgumentCaptor.forClass(NtnSignalStrength.class);
+ verify(mPhone, times(1)).notifyCarrierRoamingNtnSignalStrengthChanged(
+ captor.capture());
+ actualSignalStrength = captor.getValue();
+ assertEquals(NTN_SIGNAL_STRENGTH_GOOD, actualSignalStrength.getLevel());
+ clearInvocations(mPhone);
+ }
+
+ @Test
public void testGetWwanIsInService() {
when(mServiceState.getNetworkRegistrationInfoListForTransportType(
eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)))
@@ -5476,6 +5516,13 @@
msg.sendToTarget();
}
+ private void sendSignalStrengthChangedEvent(int phoneId) {
+ Message msg = mSatelliteControllerUT.obtainMessage(
+ 57 /* EVENT_SIGNAL_STRENGTH_CHANGED */);
+ msg.obj = new AsyncResult(phoneId, null, null);
+ msg.sendToTarget();
+ }
+
private void sendCmdStartSendingNtnSignalStrengthChangedEvent(boolean shouldReport) {
Message msg = mSatelliteControllerUT.obtainMessage(
35 /* CMD_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING */);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
index 2609ffc..56d5731 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
@@ -152,8 +152,10 @@
mServiceState2 = Mockito.mock(ServiceState.class);
when(mPhone.getServiceState()).thenReturn(mServiceState);
when(mPhone.getPhoneId()).thenReturn(PHONE_ID);
+ when(mPhone.getSignalStrengthController()).thenReturn(mSignalStrengthController);
when(mPhone2.getServiceState()).thenReturn(mServiceState2);
when(mPhone2.getPhoneId()).thenReturn(PHONE_ID2);
+ when(mPhone2.getSignalStrengthController()).thenReturn(mSignalStrengthController);
mTestSOSMessageRecommender = new TestSOSMessageRecommender(mContext, Looper.myLooper(),
mTestSatelliteController, mTestImsManager);
when(mServiceState.getState()).thenReturn(STATE_OUT_OF_SERVICE);
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();
}