Merge "Fix disableGroup" into main
diff --git a/flags/Android.bp b/flags/Android.bp
index 3c0deee..8f363b6 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -22,16 +22,17 @@
name: "telephony_flags",
package: "com.android.internal.telephony.flags",
srcs: [
- "data.aconfig",
- "domainselection.aconfig",
- "ims.aconfig",
- "messaging.aconfig",
- "misc.aconfig",
- "network.aconfig",
- "subscription.aconfig",
- "uicc.aconfig",
- "satellite.aconfig",
- "iwlan.aconfig",
- "telephony.aconfig",
+ "calling.aconfig",
+ "data.aconfig",
+ "domainselection.aconfig",
+ "ims.aconfig",
+ "messaging.aconfig",
+ "misc.aconfig",
+ "network.aconfig",
+ "subscription.aconfig",
+ "uicc.aconfig",
+ "satellite.aconfig",
+ "iwlan.aconfig",
+ "telephony.aconfig",
],
}
diff --git a/flags/calling.aconfig b/flags/calling.aconfig
new file mode 100644
index 0000000..82f932b
--- /dev/null
+++ b/flags/calling.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.internal.telephony.flags"
+
+flag {
+ name: "simultaneous_calling_indications"
+ namespace: "telephony"
+ description: "APIs that are used to notify simultaneous calling changes to other applications."
+ bug: "297446980"
+}
\ No newline at end of file
diff --git a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index c035329..e81d0f1 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -45,6 +45,7 @@
import com.android.telephony.Rlog;
import java.util.List;
+import java.util.Set;
/**
* broadcast intents
@@ -301,6 +302,11 @@
}
@Override
+ public void notifySimultaneousCellularCallingSubscriptionsChanged(Set<Integer> subIds) {
+ mTelephonyRegistryMgr.notifySimultaneousCellularCallingSubscriptionsChanged(subIds);
+ }
+
+ @Override
public void notifyCallbackModeStarted(Phone sender, @EmergencyCallbackModeType int type) {
mTelephonyRegistryMgr.notifyCallBackModeStarted(sender.getPhoneId(),
sender.getSubId(), type);
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 654faaa..28e8ff1 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -5373,7 +5373,11 @@
}
boolean prefEnabled = getNullCipherNotificationsPreferenceEnabled();
- // TODO(b/316592273): Enable / disable in NullCipherNotifier once the class is available.
+ if (prefEnabled) {
+ mNullCipherNotifier.enable();
+ } else {
+ mNullCipherNotifier.disable();
+ }
mCi.setSecurityAlgorithmsUpdatedEnabled(prefEnabled,
obtainMessage(EVENT_SET_SECURITY_ALGORITHMS_UPDATED_ENABLED_DONE));
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index 26aeaca..1e0aa3a 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -87,6 +87,7 @@
/** Feature flags */
@NonNull
private final FeatureFlags mFeatureFlags;
+ private final DefaultPhoneNotifier mNotifier;
/**
* True if 'Virtual DSDA' i.e., in-call IMS connectivity on both subs with only single logical
* modem, is enabled.
@@ -128,6 +129,7 @@
mPhoneStatusMap = new HashMap<>();
mVirtualDsdaEnabled = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_TELEPHONY, KEY_ENABLE_VIRTUAL_DSDA, false);
+ mNotifier = new DefaultPhoneNotifier(mContext, mFeatureFlags);
DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_TELEPHONY, Runnable::run,
properties -> {
@@ -294,6 +296,11 @@
} else {
log(msg.what + " failure. Not getting logical slots that support "
+ "simultaneous calling." + ar.exception);
+ mSlotsSupportingSimultaneousCellularCalls.clear();
+ }
+ if (mFeatureFlags.simultaneousCallingIndications()) {
+ mNotifier.notifySimultaneousCellularCallingSubscriptionsChanged(
+ mSlotsSupportingSimultaneousCellularCalls);
}
break;
default:
@@ -449,9 +456,7 @@
}
private void notifyCapabilityChanged() {
- PhoneNotifier notifier = new DefaultPhoneNotifier(mContext, mFeatureFlags);
-
- notifier.notifyPhoneCapabilityChanged(mStaticCapability);
+ mNotifier.notifyPhoneCapabilityChanged(mStaticCapability);
}
/**
diff --git a/src/java/com/android/internal/telephony/PhoneNotifier.java b/src/java/com/android/internal/telephony/PhoneNotifier.java
index 20d6702..cb6b199 100644
--- a/src/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/PhoneNotifier.java
@@ -39,6 +39,7 @@
import android.telephony.ims.MediaQualityStatus;
import java.util.List;
+import java.util.Set;
/**
* {@hide}
@@ -149,4 +150,7 @@
/** Notify callback mode stopped. */
void notifyCallbackModeStopped(Phone sender, @EmergencyCallbackModeType int type,
@EmergencyCallbackModeStopReason int reason);
+
+ /** Notify that simultaneous cellular calling subscriptions have changed */
+ void notifySimultaneousCellularCallingSubscriptionsChanged(Set<Integer> subIds);
}
diff --git a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
index fb9d32f..893509c 100644
--- a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
@@ -372,6 +372,7 @@
0) != 0) {
mIsAirPlaneModeEnableDuringDataStall = true;
}
+ setRecoveryAction(mLastAction);
}
break;
case EVENT_CONTENT_DSRM_ENABLED_ACTIONS_CHANGED:
@@ -527,6 +528,7 @@
// during data stalled.
if (mDataStalled && enabled) {
mMobileDataChangedToEnabledDuringDataStall = true;
+ setRecoveryAction(mLastAction);
}
}
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index 2c84f5e..8dc8098 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -1521,18 +1521,22 @@
*/
private void validate(int subId, boolean needValidation, int switchReason,
@Nullable ISetOpportunisticDataCallback callback) {
- logl("Validate subId " + subId + " due to " + switchReasonToString(switchReason)
- + " needValidation=" + needValidation);
int subIdToValidate = (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
? mPrimaryDataSubId : subId;
+ logl("Validate subId " + subId + " due to " + switchReasonToString(switchReason)
+ + " needValidation=" + needValidation + " subIdToValidate=" + subIdToValidate
+ + " mAutoSelectedDataSubId=" + mAutoSelectedDataSubId
+ + " mPreferredDataSubId=" + mPreferredDataSubId.get());
if (!isActiveSubId(subIdToValidate)) {
logl("Can't switch data to inactive subId " + subIdToValidate);
if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
// the default data sub is not selected yet, store the intent of switching to
// default subId once it becomes available.
mAutoSelectedDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+ sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
+ } else {
+ sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
}
- sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
return;
}
diff --git a/src/java/com/android/internal/telephony/satellite/NtnCapabilityResolver.java b/src/java/com/android/internal/telephony/satellite/NtnCapabilityResolver.java
index 26100a8..4d294f4 100644
--- a/src/java/com/android/internal/telephony/satellite/NtnCapabilityResolver.java
+++ b/src/java/com/android/internal/telephony/satellite/NtnCapabilityResolver.java
@@ -40,7 +40,7 @@
public static void resolveNtnCapability(
@NonNull NetworkRegistrationInfo networkRegistrationInfo, int subId) {
SatelliteController satelliteController = SatelliteController.getInstance();
- List<String> satellitePlmnList = satelliteController.getSatellitePlmnList(subId);
+ List<String> satellitePlmnList = satelliteController.getAllSatellitePlmnsForCarrier(subId);
String registeredPlmn = networkRegistrationInfo.getRegisteredPlmn();
for (String satellitePlmn : satellitePlmnList) {
if (TextUtils.equals(satellitePlmn, registeredPlmn)) {
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index c691737..a5a1f82 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -2297,9 +2297,9 @@
* @return The list of satellite PLMNs used for connecting to satellite networks.
*/
@NonNull
- public List<String> getSatellitePlmnList(int subId) {
+ public List<String> getAllSatellitePlmnsForCarrier(int subId) {
if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
- logd("getSatellitePlmnList: carrierEnabledSatelliteFlag is disabled");
+ logd("getAllSatellitePlmnsForCarrier: carrierEnabledSatelliteFlag is disabled");
return new ArrayList<>();
}
synchronized (mSupportedSatelliteServicesLock) {
diff --git a/src/java/com/android/internal/telephony/security/NullCipherNotifier.java b/src/java/com/android/internal/telephony/security/NullCipherNotifier.java
index cef2bb9..0ab8299 100644
--- a/src/java/com/android/internal/telephony/security/NullCipherNotifier.java
+++ b/src/java/com/android/internal/telephony/security/NullCipherNotifier.java
@@ -34,6 +34,8 @@
private static final String TAG = "NullCipherNotifier";
private static NullCipherNotifier sInstance;
+ private boolean mEnabled = false;
+
/**
* Gets a singleton NullCipherNotifier.
*/
@@ -55,4 +57,28 @@
// from here.
Rlog.d(TAG, "Security algorithm update: phoneId = " + phoneId + " " + update);
}
+
+ /**
+ * Enables null cipher notification; {@code onSecurityAlgorithmUpdate} will start handling
+ * security algorithm updates and send notifications to the user when required.
+ */
+ public void enable() {
+ Rlog.d(TAG, "enabled");
+ mEnabled = true;
+ }
+
+ /**
+ * Clear all internal state and prevent further notifications until re-enabled. This can be
+ * used in response to a user disabling the feature for null cipher notifications. If
+ * {@code onSecurityAlgorithmUpdate} is called while in a disabled state, security algorithm
+ * updates will be dropped.
+ */
+ public void disable() {
+ Rlog.d(TAG, "disabled");
+ mEnabled = false;
+ }
+
+ public boolean isEnabled() {
+ return mEnabled;
+ }
}
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java b/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
index 0756650..bbe88a8 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
@@ -2062,7 +2062,7 @@
*/
public void setGroupDisabled(int subId, boolean isGroupDisabled) {
// group disabled does not have a corresponding SimInfo column. So we only update the cache.
-
+ boolean isChanged = false;
// Grab the write lock so no other threads can read or write the cache.
mReadWriteLock.writeLock().lock();
try {
@@ -2071,12 +2071,18 @@
throw new IllegalArgumentException("setGroupDisabled: Subscription doesn't exist. "
+ "subId=" + subId);
}
+ isChanged = subInfoCache.isGroupDisabled() != isGroupDisabled;
mAllSubscriptionInfoInternalCache.put(subId,
new SubscriptionInfoInternal.Builder(subInfoCache)
.setGroupDisabled(isGroupDisabled).build());
} finally {
mReadWriteLock.writeLock().unlock();
}
+
+ if (isChanged) {
+ log("setGroupDisabled value changed, firing the callback");
+ mCallback.invokeFromExecutor(() -> mCallback.onSubscriptionChanged(subId));
+ }
}
/**
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index dbbd6b0..02d48b1 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -2139,6 +2139,8 @@
*/
@Override
public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
+ enforcePermissions("requestEmbeddedSubscriptionInfoListRefresh",
+ Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS);
updateEmbeddedSubscriptions(List.of(cardId), null);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
index 5c0cd05..d27ab98 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
@@ -33,6 +33,7 @@
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsCallProfile;
+import android.util.ArraySet;
import androidx.test.filters.SmallTest;
@@ -380,4 +381,15 @@
assertEquals(3, cellLocationCapture.getValue().asCellLocation().getCid());
assertEquals(-1, cellLocationCapture.getValue().asCellLocation().getPsc());
}
+
+ @Test
+ @SmallTest
+ public void testSimultaneousCellularCallingSubscriptionsChanged() {
+ ArraySet<Integer> subs = new ArraySet<>(2);
+ subs.add(0);
+ subs.add(1);
+ mDefaultPhoneNotifierUT.notifySimultaneousCellularCallingSubscriptionsChanged(subs);
+ verify(mTelephonyRegistryManager).notifySimultaneousCellularCallingSubscriptionsChanged(
+ eq(subs));
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 3962565..a4f4a9c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -3019,6 +3019,31 @@
assertTrue(phoneUT.isNullCipherNotificationSupported());
}
+ @Test
+ public void testNullCipherNotification_preferenceEnabled() {
+ when(mFeatureFlags.enableModemCipherTransparency()).thenReturn(true);
+ GsmCdmaPhone phoneUT = makeNewPhoneUT();
+
+ setNullCipherNotificationPreferenceEnabled(true);
+ phoneUT.handleNullCipherNotificationPreferenceChanged();
+
+ verify(mNullCipherNotifier, times(1)).enable();
+ verify(mMockCi, times(1)).setSecurityAlgorithmsUpdatedEnabled(eq(true),
+ any(Message.class));
+ }
+
+ @Test
+ public void testNullCipherNotification_preferenceDisabled() {
+ when(mFeatureFlags.enableModemCipherTransparency()).thenReturn(true);
+ GsmCdmaPhone phoneUT = makeNewPhoneUT();
+
+ setNullCipherNotificationPreferenceEnabled(false);
+ phoneUT.handleNullCipherNotificationPreferenceChanged();
+
+ verify(mNullCipherNotifier, times(1)).disable();
+ verify(mMockCi, times(1)).setSecurityAlgorithmsUpdatedEnabled(eq(false),
+ any(Message.class));
+ }
private void sendRadioAvailableToPhone(GsmCdmaPhone phone) {
phone.sendMessage(phone.obtainMessage(EVENT_RADIO_AVAILABLE,
@@ -3037,6 +3062,14 @@
processAllMessages();
}
+ private void setNullCipherNotificationPreferenceEnabled(boolean enabled) {
+ SharedPreferences sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(mContext);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putBoolean(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED, enabled);
+ editor.apply();
+ }
+
private GsmCdmaPhone makeNewPhoneUT() {
return new GsmCdmaPhone(
mContext,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
index c516542..90105e3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
@@ -40,6 +40,7 @@
import android.os.Message;
import android.telephony.PhoneCapability;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyRegistryManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -54,6 +55,7 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
+import java.util.Collections;
import java.util.HashSet;
@RunWith(AndroidTestingRunner.class)
@@ -69,6 +71,7 @@
private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 1;
PhoneConfigurationManager mPcm;
private FeatureFlags mFeatureFlags;
+ private TelephonyRegistryManager mMockRegistryManager;
@Before
public void setUp() throws Exception {
@@ -83,6 +86,7 @@
mCT.mCi = mMockCi0;
mPhone1.mCi = mMockCi1;
doReturn(RIL.RADIO_HAL_VERSION_2_1).when(mMockRadioConfigProxy).getVersion();
+ mMockRegistryManager = mContext.getSystemService(TelephonyRegistryManager.class);
}
@After
@@ -169,6 +173,7 @@
@Test
@SmallTest
public void testUpdateSimultaneousCallingSupport() throws Exception {
+ doReturn(false).when(mFeatureFlags).simultaneousCallingIndications();
init(2);
mPcm.updateSimultaneousCallingSupport();
@@ -188,6 +193,7 @@
@Test
@SmallTest
public void testUpdateSimultaneousCallingSupport_invalidResponse_shouldFail() throws Exception {
+ doReturn(false).when(mFeatureFlags).simultaneousCallingIndications();
init(2);
mPcm.updateSimultaneousCallingSupport();
@@ -207,6 +213,46 @@
@Test
@SmallTest
+ public void testUpdateSimultaneousCallingSupportNotifications() throws Exception {
+ // retry simultaneous calling tests, but with notifications enabled this time
+ doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
+ init(2);
+
+ // Simultaneous calling enabled
+ mPcm.updateSimultaneousCallingSupport();
+ int[] enabledLogicalSlots = {0, 1};
+ ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
+ verify(mMockRadioConfig).updateSimultaneousCallingSupport(captor.capture());
+ Message msg = captor.getValue();
+ AsyncResult.forMessage(msg, enabledLogicalSlots, null);
+ msg.sendToTarget();
+ processAllMessages();
+
+ HashSet<Integer> expectedSlots = new HashSet<>();
+ for (int i : enabledLogicalSlots) {
+ expectedSlots.add(i);
+ }
+ assertEquals(expectedSlots, mPcm.getSlotsSupportingSimultaneousCellularCalls());
+ verify(mMockRegistryManager).notifySimultaneousCellularCallingSubscriptionsChanged(
+ eq(expectedSlots));
+
+ // Simultaneous Calling Disabled
+ mPcm.updateSimultaneousCallingSupport();
+ int[] disabled = {};
+ captor = ArgumentCaptor.forClass(Message.class);
+ verify(mMockRadioConfig, times(2)).updateSimultaneousCallingSupport(captor.capture());
+ msg = captor.getAllValues().get(1);
+ AsyncResult.forMessage(msg, disabled, null);
+ msg.sendToTarget();
+ processAllMessages();
+
+ assertEquals(Collections.emptySet(), mPcm.getSlotsSupportingSimultaneousCellularCalls());
+ verify(mMockRegistryManager, times(2))
+ .notifySimultaneousCellularCallingSubscriptionsChanged(eq(Collections.emptySet()));
+ }
+
+ @Test
+ @SmallTest
public void testSwitchMultiSimConfig_notDsdsCapable_shouldFail() throws Exception {
init(1);
assertEquals(PhoneCapability.DEFAULT_SSSS_CAPABILITY, mPcm.getStaticPhoneCapability());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index d920521..4fa42c9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -260,7 +260,8 @@
mSatelliteController = Mockito.mock(SatelliteController.class);
replaceInstance(SatelliteController.class, "sInstance", null,
mSatelliteController);
- doReturn(new ArrayList<>()).when(mSatelliteController).getSatellitePlmnList(anyInt());
+ doReturn(new ArrayList<>()).when(mSatelliteController).getAllSatellitePlmnsForCarrier(
+ anyInt());
mContextFixture.putResource(R.string.kg_text_message_separator, " \u2014 ");
@@ -3386,7 +3387,8 @@
CellIdentityGsm cellIdentity =
new CellIdentityGsm(0, 1, 900, 5, "101", "23", "test", "tst",
Collections.emptyList());
- doReturn(Arrays.asList("10123")).when(mSatelliteController).getSatellitePlmnList(anyInt());
+ doReturn(Arrays.asList("10123")).when(mSatelliteController).getAllSatellitePlmnsForCarrier(
+ anyInt());
doReturn(satelliteSupportedServiceList).when(mSatelliteController)
.getSupportedSatelliteServices(sst.mSubId, "10123");
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 777e851..6050b18 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.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.SparseArray;
import androidx.annotation.NonNull;
@@ -115,6 +116,7 @@
private BarringInfo mBarringInfo = null;
private CellIdentity mCellIdentityForRegiFail;
private int mRegistrationFailReason;
+ private Set<Integer> mSimultaneousCallingSubscriptions;
// All events contribute to TelephonyRegistry#isPhoneStatePermissionRequired
private static final Set<Integer> READ_PHONE_STATE_EVENTS;
@@ -160,6 +162,8 @@
TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED);
READ_PRIVILEGED_PHONE_STATE_EVENTS.add(
TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED);
+ READ_PRIVILEGED_PHONE_STATE_EVENTS.add(
+ TelephonyCallback.EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED);
}
// All events contribute to TelephonyRegistry#isActiveEmergencySessionPermissionRequired
@@ -187,7 +191,8 @@
TelephonyCallback.CellInfoListener,
TelephonyCallback.BarringInfoListener,
TelephonyCallback.RegistrationFailedListener,
- TelephonyCallback.DataActivityListener {
+ TelephonyCallback.DataActivityListener,
+ TelephonyCallback.SimultaneousCellularCallingSupportListener {
// This class isn't mockable to get invocation counts because the IBinder is null and
// crashes the TelephonyRegistry. Make a cheesy verify(times()) alternative.
public AtomicInteger invocationCount = new AtomicInteger(0);
@@ -275,6 +280,13 @@
invocationCount.incrementAndGet();
mDataActivity = direction;
}
+
+ @Override
+ public void onSimultaneousCellularCallingSubscriptionsChanged(
+ @NonNull Set<Integer> simultaneousCallingSubscriptionIds) {
+ invocationCount.incrementAndGet();
+ mSimultaneousCallingSubscriptions = simultaneousCallingSubscriptionIds;
+ }
}
private void addTelephonyRegistryService() {
@@ -1531,4 +1543,23 @@
processAllMessages();
assertEquals(TelephonyManager.DATA_ACTIVITY_OUT, mDataActivity);
}
+
+ @Test
+ public void testSimultaneousCellularCallingSubscriptionsChanged() {
+ final int subId = INVALID_SUBSCRIPTION_ID;
+ int[] events = {TelephonyCallback
+ .EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED};
+
+ int[] subIds = {0, 1, 2};
+ Set<Integer> subIdSet = new ArraySet<>(3);
+ for (Integer s : subIds) {
+ subIdSet.add(s);
+ }
+ mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+ mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+
+ mTelephonyRegistry.notifySimultaneousCellularCallingSubscriptionsChanged(subIds);
+ processAllMessages();
+ assertEquals(subIdSet, mSimultaneousCallingSubscriptions);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java
index 28c6cd6..e508e5b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java
@@ -43,6 +43,7 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
+import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
import com.android.internal.telephony.data.DataStallRecoveryManager.DataStallRecoveryManagerCallback;
import org.junit.After;
@@ -145,6 +146,17 @@
dataNetworkControllerCallback.onInternetDataNetworkValidationStatusChanged(status);
}
+ private void sendDataEabledCallback(boolean isEnabled) {
+ ArgumentCaptor<DataSettingsManagerCallback> dataSettingsManagerCallbackCaptor =
+ ArgumentCaptor.forClass(DataSettingsManagerCallback.class);
+ verify(mDataSettingsManager).registerCallback(dataSettingsManagerCallbackCaptor.capture());
+
+ // Data enabled
+ doReturn(isEnabled).when(mDataSettingsManager).isDataEnabled();
+ dataSettingsManagerCallbackCaptor.getValue().onDataEnabledChanged(isEnabled,
+ TelephonyManager.DATA_ENABLED_REASON_USER, "");
+ }
+
private void sendOnInternetDataNetworkCallback(boolean isConnected) {
ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
@@ -257,7 +269,8 @@
moveTimeForward(15000);
processAllMessages();
- assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);
+ // should not change the recovery action due to there is an active call.
+ assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1);
}
@Test
@@ -510,4 +523,59 @@
// Check if predict waiting millis is 0
assertThat(field.get(mDataStallRecoveryManager)).isEqualTo(0L);
}
+
+ @Test
+ public void testRecoveryActionAfterDataEnabled() throws Exception {
+ sendDataEabledCallback(true);
+ sendOnInternetDataNetworkCallback(true);
+ sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
+ mDataStallRecoveryManager.setRecoveryAction(0);
+ doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
+ doReturn(3).when(mSignalStrength).getLevel();
+ doReturn(mSignalStrength).when(mPhone).getSignalStrength();
+ logd("Sending validation failed callback");
+
+ assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
+ sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+ processAllMessages();
+ moveTimeForward(101);
+ assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1);
+
+ // test mobile data off/on
+ sendDataEabledCallback(false);
+ sendDataEabledCallback(true);
+
+ // recovery action will jump to next action if user doing the mobile data off/on.
+ assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);
+ }
+
+ @Test
+ public void testJumpToRecoveryActionRadioRestart() throws Exception {
+ sendDataEabledCallback(true);
+ sendOnInternetDataNetworkCallback(true);
+ sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
+ mDataStallRecoveryManager.setRecoveryAction(0);
+
+ doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
+ doReturn(3).when(mSignalStrength).getLevel();
+ doReturn(mSignalStrength).when(mPhone).getSignalStrength();
+ doReturn(TelephonyManager.RADIO_POWER_ON).when(mPhone).getRadioPowerState();
+ assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
+
+ sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+ moveTimeForward(200);
+ processAllMessages();
+ moveTimeForward(200);
+ mDataStallRecoveryManager.sendMessageDelayed(
+ mDataStallRecoveryManager.obtainMessage(3), 1000);
+ processAllMessages();
+ sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+ moveTimeForward(200);
+ sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+ processAllMessages();
+ moveTimeForward(200);
+
+ // recovery action will jump to modem reset action if user doing the radio restart.
+ assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(4);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
index 60aac0d..5d5ef64 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -1408,13 +1408,22 @@
// Switch to primary before a primary is selected/inactive.
setDefaultDataSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mPhoneSwitcherUT.trySetOpportunisticDataSubscription(
- SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, mSetOpptDataCallback1);
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID, false, mSetOpptDataCallback1);
processAllMessages();
assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
mPhoneSwitcherUT.getAutoSelectedDataSubId());
verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
+ // Verify that the switch to default sub is successful
+ mPhoneSwitcherUT.trySetOpportunisticDataSubscription(
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, mSetOpptDataCallback1);
+ processAllMessages();
+
+ assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ mPhoneSwitcherUT.getAutoSelectedDataSubId());
+ verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS);
+
// once the primary is selected, it becomes the active sub.
setDefaultDataSubId(2);
assertEquals(2, mPhoneSwitcherUT.getActiveDataSubId());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/NtnCapabilityResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/NtnCapabilityResolverTest.java
index 0944c6c..5ee7e8f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/NtnCapabilityResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/NtnCapabilityResolverTest.java
@@ -76,7 +76,7 @@
replaceInstance(SatelliteController.class, "sInstance", null,
mMockSatelliteController);
doReturn(Arrays.asList(SATELLITE_PLMN_ARRAY))
- .when(mMockSatelliteController).getSatellitePlmnList(anyInt());
+ .when(mMockSatelliteController).getAllSatellitePlmnsForCarrier(anyInt());
doReturn(mSatelliteSupportedServiceList).when(mMockSatelliteController)
.getSupportedSatelliteServices(SUB_ID, SATELLITE_PLMN);
}
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 685578c..dedc906 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -1587,7 +1587,8 @@
@Test
public void testSupportedSatelliteServices() {
when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false);
- List<String> satellitePlmnList = mSatelliteControllerUT.getSatellitePlmnList(SUB_ID);
+ List<String> satellitePlmnList = mSatelliteControllerUT.getAllSatellitePlmnsForCarrier(
+ SUB_ID);
assertEquals(EMPTY_STRING_ARRAY.length, satellitePlmnList.size());
List<Integer> supportedSatelliteServices =
mSatelliteControllerUT.getSupportedSatelliteServices(SUB_ID, "00101");
@@ -1610,7 +1611,7 @@
TestSatelliteController testSatelliteController =
new TestSatelliteController(mContext, Looper.myLooper(), mFeatureFlags);
- satellitePlmnList = testSatelliteController.getSatellitePlmnList(SUB_ID);
+ satellitePlmnList = testSatelliteController.getAllSatellitePlmnsForCarrier(SUB_ID);
assertTrue(satellitePlmnList.isEmpty());
supportedSatelliteServices =
testSatelliteController.getSupportedSatelliteServices(SUB_ID, "00101");
@@ -1642,7 +1643,7 @@
}
processAllMessages();
- satellitePlmnList = testSatelliteController.getSatellitePlmnList(SUB_ID);
+ satellitePlmnList = testSatelliteController.getAllSatellitePlmnsForCarrier(SUB_ID);
assertTrue(Arrays.equals(
expectedSupportedSatellitePlmns, satellitePlmnList.stream().toArray()));
supportedSatelliteServices =
@@ -1669,7 +1670,7 @@
}
processAllMessages();
- satellitePlmnList = testSatelliteController.getSatellitePlmnList(SUB_ID);
+ satellitePlmnList = testSatelliteController.getAllSatellitePlmnsForCarrier(SUB_ID);
assertTrue(satellitePlmnList.isEmpty());
supportedSatelliteServices =
testSatelliteController.getSupportedSatelliteServices(SUB_ID, "00102");
@@ -1714,7 +1715,8 @@
TestSatelliteController testSatelliteController =
new TestSatelliteController(mContext, Looper.myLooper(), mFeatureFlags);
processAllMessages();
- List<String> carrierPlmnList = testSatelliteController.getSatellitePlmnList(SUB_ID);
+ List<String> carrierPlmnList = testSatelliteController.getAllSatellitePlmnsForCarrier(
+ SUB_ID);
verify(mMockSatelliteModemInterface, never()).setSatellitePlmn(
anyInt(), anyList(), anyList(), any(Message.class));
assertTrue(carrierPlmnList.isEmpty());
@@ -1741,7 +1743,7 @@
);
}
processAllMessages();
- carrierPlmnList = testSatelliteController.getSatellitePlmnList(SUB_ID);
+ carrierPlmnList = testSatelliteController.getAllSatellitePlmnsForCarrier(SUB_ID);
verify(mMockSatelliteModemInterface, never()).setSatellitePlmn(
anyInt(), anyList(), anyList(), any(Message.class));
assertTrue(carrierPlmnList.isEmpty());
@@ -1767,7 +1769,7 @@
}
processAllMessages();
- carrierPlmnList = testSatelliteController.getSatellitePlmnList(SUB_ID);
+ carrierPlmnList = testSatelliteController.getAllSatellitePlmnsForCarrier(SUB_ID);
assertTrue(carrierPlmnList.isEmpty());
List<String> allSatellitePlmnList = SatelliteServiceUtils.mergeStrLists(
carrierPlmnList, satellitePlmnListFromOverlayConfig);
@@ -1787,7 +1789,7 @@
);
}
processAllMessages();
- carrierPlmnList = testSatelliteController.getSatellitePlmnList(SUB_ID);
+ carrierPlmnList = testSatelliteController.getAllSatellitePlmnsForCarrier(SUB_ID);
allSatellitePlmnList = SatelliteServiceUtils.mergeStrLists(
carrierPlmnList, satellitePlmnListFromOverlayConfig);
assertEquals(expectedCarrierPlmnList, carrierPlmnList);
@@ -1826,7 +1828,7 @@
);
}
processAllMessages();
- carrierPlmnList = testSatelliteController.getSatellitePlmnList(SUB_ID);
+ carrierPlmnList = testSatelliteController.getAllSatellitePlmnsForCarrier(SUB_ID);
assertTrue(carrierPlmnList.isEmpty());
verify(mMockSatelliteModemInterface, times(1)).setSatellitePlmn(anyInt(),
eq(EMPTY_STRING_LIST), eq(EMPTY_STRING_LIST), any(Message.class));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
index d75b32a..1a89c15 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
@@ -2018,6 +2018,36 @@
}
@Test
+ public void testSetGroupDisabled() throws Exception {
+ assertThrows(IllegalArgumentException.class,
+ () -> mDatabaseManagerUT.setGroupDisabled(
+ FAKE_SUBSCRIPTION_INFO1.getSubscriptionId(), true));
+
+ insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+ mDatabaseManagerUT.setGroupDisabled(FAKE_SUBSCRIPTION_INFO1.getSubscriptionId(), true);
+ processAllMessages();
+
+ assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(
+ FAKE_SUBSCRIPTION_INFO1.getSubscriptionId()).isGroupDisabled()).isTrue();
+
+ verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+ Mockito.clearInvocations(mSubscriptionDatabaseManagerCallback);
+
+ mDatabaseManagerUT.setGroupDisabled(FAKE_SUBSCRIPTION_INFO1.getSubscriptionId(), true);
+ processAllMessages();
+ verify(mSubscriptionDatabaseManagerCallback, never()).onSubscriptionChanged(eq(1));
+
+ assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(
+ FAKE_SUBSCRIPTION_INFO1.getSubscriptionId()).isGroupDisabled()).isTrue();
+
+ mDatabaseManagerUT.setGroupDisabled(FAKE_SUBSCRIPTION_INFO1.getSubscriptionId(), false);
+ processAllMessages();
+ verify(mSubscriptionDatabaseManagerCallback, times(1)).onSubscriptionChanged(eq(1));
+ assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(
+ FAKE_SUBSCRIPTION_INFO1.getSubscriptionId()).isGroupDisabled()).isFalse();
+ }
+
+ @Test
public void testUpdateSatelliteNtnWithFeatureDisabled() throws Exception {
assertThrows(IllegalArgumentException.class,
() -> mDatabaseManagerUT.setSatelliteAttachEnabledForCarrier(