Added default data subscription changed callback
Replaced the broadcast intent with the much efficient internal
callback.
Test: Basic telephony functionality tests
Test: atest PhoneSwitcherTest SubscriptionManagerServiceTest
Flag: com.android.internal.telephony.flags.dds_callback
Bug: 353723350
Change-Id: Ib066d0bfe321bd6cf41c9c9b8a6c1d40316a0ed9
diff --git a/flags/data.aconfig b/flags/data.aconfig
index d956104..80d6f61 100644
--- a/flags/data.aconfig
+++ b/flags/data.aconfig
@@ -172,3 +172,13 @@
description: "Write DataRatStateChanged atom"
bug:"318519337"
}
+
+# OWNER=jackyu TARGET=24Q4
+flag {
+ name: "dds_callback"
+ namespace: "telephony"
+ description: "Adding new callback when DDS changed"
+ bug:"353723350"
+}
+
+
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index e73556d..f1f7b49 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -89,6 +89,7 @@
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
+import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback;
import com.android.internal.telephony.subscription.SubscriptionManagerService.WatchedInt;
import com.android.internal.util.IndentingPrintWriter;
import com.android.telephony.Rlog;
@@ -587,9 +588,19 @@
};
mAutoDataSwitchController = new AutoDataSwitchController(context, looper, this,
mFlags, mAutoDataSwitchCallback);
-
- mContext.registerReceiver(mDefaultDataChangedReceiver,
- new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
+ if (!mFlags.ddsCallback()) {
+ mContext.registerReceiver(mDefaultDataChangedReceiver,
+ new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
+ } else {
+ mSubscriptionManagerService.registerCallback(new SubscriptionManagerServiceCallback(
+ this::post) {
+ @Override
+ public void onDefaultDataSubscriptionChanged(int subId) {
+ evaluateIfImmediateDataSwitchIsNeeded("default data sub changed to " + subId,
+ DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL);
+ }
+ });
+ }
PhoneConfigurationManager.registerForMultiSimConfigChange(
this, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 5f2272b..6ef7328 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -458,6 +458,13 @@
* @param subId The subscription id.
*/
public void onUiccApplicationsEnabledChanged(int subId) {}
+
+ /**
+ * Called when {@link #getDefaultDataSubId()} changed.
+ *
+ * @param subId The subscription id.
+ */
+ public void onDefaultDataSubscriptionChanged(int subId) {}
}
/**
@@ -593,6 +600,13 @@
// Broadcast sub Id on service initialized.
broadcastSubId(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED,
getDefaultDataSubId());
+ if (mFeatureFlags.ddsCallback()) {
+ mSubscriptionManagerServiceCallbacks.forEach(
+ callback -> callback.invokeFromExecutor(
+ () -> callback.onDefaultDataSubscriptionChanged(
+ getDefaultDataSubId())));
+ }
+
broadcastSubId(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED,
getDefaultVoiceSubId());
broadcastSubId(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED,
@@ -3177,6 +3191,11 @@
broadcastSubId(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED,
subId);
+ if (mFeatureFlags.ddsCallback()) {
+ mSubscriptionManagerServiceCallbacks.forEach(
+ callback -> callback.invokeFromExecutor(
+ () -> callback.onDefaultDataSubscriptionChanged(subId)));
+ }
updateDefaultSubId();
}
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 2a1fedb..a820ec7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -87,11 +87,11 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCall;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
+import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback;
import org.junit.After;
import org.junit.Before;
@@ -155,6 +155,7 @@
private TelephonyDisplayInfo mTelephonyDisplayInfo = new TelephonyDisplayInfo(
TelephonyManager.NETWORK_TYPE_NR,
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false);
+ private SubscriptionManagerServiceCallback mSubscriptionManagerServiceCallback;
@Before
public void setUp() throws Exception {
@@ -203,6 +204,7 @@
mServiceManagerMockedServices.put("isub", mIBinder);
doReturn(mTelephonyDisplayInfo).when(mDisplayInfoController).getTelephonyDisplayInfo();
+ doReturn(true).when(mFeatureFlags).ddsCallback();
}
@After
@@ -2032,12 +2034,6 @@
}
}
- private void sendDefaultDataSubChanged() {
- final Intent intent = new Intent(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
- mContext.sendBroadcast(intent);
- processAllMessages();
- }
-
private void initialize() throws Exception {
setNumPhones(mActiveModemCount, mSupportedModemCount);
@@ -2066,6 +2062,11 @@
processAllMessages();
verify(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(any(), any());
+
+ ArgumentCaptor<SubscriptionManagerServiceCallback> callbackCaptor =
+ ArgumentCaptor.forClass(SubscriptionManagerServiceCallback.class);
+ verify(mSubscriptionManagerService).registerCallback(callbackCaptor.capture());
+ mSubscriptionManagerServiceCallback = callbackCaptor.getValue();
}
/**
@@ -2231,7 +2232,8 @@
doAnswer(invocation -> phone.getSubId() == mDefaultDataSub)
.when(phone).isUserDataEnabled();
}
- sendDefaultDataSubChanged();
+ mSubscriptionManagerServiceCallback.onDefaultDataSubscriptionChanged(defaultDataSub);
+ processAllMessages();
}
private void setSlotIndexToSubId(int slotId, int subId) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
index 8172d97..65790f8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
@@ -109,8 +109,6 @@
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.euicc.EuiccController;
-import com.android.internal.telephony.flags.FeatureFlags;
-import com.android.internal.telephony.subscription.SubscriptionDatabaseManager.SubscriptionDatabaseManagerCallback;
import com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.SubscriptionProvider;
import com.android.internal.telephony.subscription.SubscriptionManagerService.BinderWrapper;
import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback;
@@ -164,7 +162,6 @@
// mocked
private SubscriptionManagerServiceCallback mMockedSubscriptionManagerServiceCallback;
private EuiccController mEuiccController;
- private FeatureFlags mFlags;
private BinderWrapper mBinder;
private Set<Integer> mActiveSubs = new ArraySet<>();
@@ -215,9 +212,13 @@
((MockContentResolver) mContext.getContentResolver()).addProvider(
Telephony.Carriers.CONTENT_URI.getAuthority(), mSubscriptionProvider);
- mFlags = Mockito.mock(FeatureFlags.class);
+ doReturn(true).when(mFeatureFlags).saferGetPhoneNumber();
+ doReturn(true).when(mFeatureFlags).uiccPhoneNumberFix();
+ doReturn(true).when(mFeatureFlags).ddsCallback();
+ doReturn(true).when(mFeatureFlags).oemEnabledSatelliteFlag();
+
mSubscriptionManagerServiceUT = new SubscriptionManagerService(mContext, Looper.myLooper(),
- mFlags);
+ mFeatureFlags);
monitorTestableLooper(new TestableLooper(getBackgroundHandler().getLooper()));
monitorTestableLooper(new TestableLooper(getSubscriptionDatabaseManager().getLooper()));
@@ -240,12 +241,6 @@
doReturn(true).when(mUserManager)
.isManagedProfile(eq(FAKE_MANAGED_PROFILE_USER_HANDLE.getIdentifier()));
- // Due to affect exist implementation, bypass feature flag.
- doReturn(false).when(mFlags).enforceTelephonyFeatureMappingForPublicApis();
-
- doReturn(true).when(mFlags).saferGetPhoneNumber();
- doReturn(true).when(mFlags).uiccPhoneNumberFix();
-
doReturn(true).when(mPackageManager).hasSystemFeature(
eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
logd("SubscriptionManagerServiceTest -Setup!");
@@ -279,12 +274,6 @@
return (SubscriptionDatabaseManager) field.get(mSubscriptionManagerServiceUT);
}
- private SubscriptionDatabaseManagerCallback getSubscriptionDatabaseCallback() throws Exception {
- Field field = SubscriptionDatabaseManager.class.getDeclaredField("mCallback");
- field.setAccessible(true);
- return (SubscriptionDatabaseManagerCallback) field.get(getSubscriptionDatabaseManager());
- }
-
/**
* Insert the subscription info to the database. This is an instant insertion method. For real
* insertion sequence please use {@link #testInsertNewSim()}.
@@ -461,7 +450,7 @@
@Test
@DisableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
public void testSetPhoneNumber() {
- doReturn(false).when(mFlags).enforceTelephonyFeatureMapping();
+ doReturn(false).when(mFeatureFlags).enforceTelephonyFeatureMapping();
doReturn(true).when(mPackageManager).hasSystemFeature(
eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
@@ -521,7 +510,7 @@
mSubscriptionManagerServiceUT, vendorApiLevel);
// Enabled FeatureFlags and ENABLE_FEATURE_MAPPING, telephony features are defined
- doReturn(true).when(mFlags).enforceTelephonyFeatureMappingForPublicApis();
+ doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis();
doReturn(true).when(mPackageManager).hasSystemFeature(
eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
try {
@@ -790,6 +779,8 @@
assertThat(b.containsKey(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX)).isTrue();
assertThat(b.getInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX)).isEqualTo(1);
+
+ verify(mMockedSubscriptionManagerServiceCallback).onDefaultDataSubscriptionChanged(eq(1));
}
@Test
@@ -1285,8 +1276,8 @@
@EnableCompatChanges({SubscriptionManagerService.REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID,
SubscriptionManagerService.FILTER_ACCESSIBLE_SUBS_BY_USER})
public void testIsSubscriptionAssociatedWithUserMultiSubs() {
- doReturn(true).when(mFlags).workProfileApiSplit();
- doReturn(true).when(mFlags).enforceSubscriptionUserFilter();
+ doReturn(true).when(mFeatureFlags).workProfileApiSplit();
+ doReturn(true).when(mFeatureFlags).enforceSubscriptionUserFilter();
mContextFixture.addCallingOrSelfPermission(
Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION);
insertSubscription(FAKE_SUBSCRIPTION_INFO1);
@@ -1348,8 +1339,8 @@
public void testSubscriptionAssociationWorkProfileCallerVisibility() {
// Split mode is defined as when a profile owns a dedicated sub, it loses the visibility to
// the unassociated sub.
- doReturn(true).when(mFlags).enforceSubscriptionUserFilter();
- doReturn(true).when(mFlags).workProfileApiSplit();
+ doReturn(true).when(mFeatureFlags).enforceSubscriptionUserFilter();
+ doReturn(true).when(mFeatureFlags).workProfileApiSplit();
mContextFixture.addCallingOrSelfPermission(
Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION);
// Sub 1 is associated with work profile; Sub 2 is unassociated.
@@ -1484,8 +1475,8 @@
public void testSubscriptionAssociationPersonalCallerVisibility() {
// Split mode is defined as when a profile owns a dedicated sub, it loses the visibility to
// the unassociated sub.
- doReturn(true).when(mFlags).enforceSubscriptionUserFilter();
- doReturn(true).when(mFlags).workProfileApiSplit();
+ doReturn(true).when(mFeatureFlags).enforceSubscriptionUserFilter();
+ doReturn(true).when(mFeatureFlags).workProfileApiSplit();
mContextFixture.addCallingOrSelfPermission(
Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION);
// Sub 1 is unassociated; Sub 2 is associated with work profile.
@@ -2564,8 +2555,6 @@
@Test
public void testGetPhoneNumberFromDefaultSubscription() {
- doReturn(true).when(mFlags).saferGetPhoneNumber();
-
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
int subId = insertSubscription(FAKE_SUBSCRIPTION_INFO1);
@@ -3213,7 +3202,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "true");
- doReturn(true).when(mFlags).oemEnabledSatelliteFlag();
EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
.setIccid(FAKE_ICCID1)
@@ -3243,14 +3231,12 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "false");
- doReturn(false).when(mFlags).oemEnabledSatelliteFlag();
}
@Test
public void testIsSatelliteSpnWithEmptySpn() {
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier, ""); // Empty
System.setProperty("persist.radio.allow_mock_modem", "true");
- doReturn(true).when(mFlags).oemEnabledSatelliteFlag();
EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
.setIccid(FAKE_ICCID1)
@@ -3306,7 +3292,6 @@
.isEqualTo(FAKE_SATELLITE_IS_ONLY_NTN_DISABLED);
System.setProperty("persist.radio.allow_mock_modem", "false");
- doReturn(false).when(mFlags).oemEnabledSatelliteFlag();
}
@Test
@@ -3314,7 +3299,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "true");
- doReturn(true).when(mFlags).oemEnabledSatelliteFlag();
EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
.setIccid(FAKE_ICCID1)
@@ -3343,7 +3327,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "false");
- doReturn(false).when(mFlags).oemEnabledSatelliteFlag();
}
@Test
@@ -3351,7 +3334,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "true");
- doReturn(true).when(mFlags).oemEnabledSatelliteFlag();
EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
.setIccid(FAKE_ICCID1)
@@ -3381,7 +3363,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "false");
- doReturn(false).when(mFlags).oemEnabledSatelliteFlag();
}
@Test