Protect data call blocking using satellite feature flags.
Bug: 291811962
Bug: 296437388
Test: Flashed build on raven-userdebug and performed basic funtionality
tests,
atest DataNetworkControllerTest
Change-Id: I8fff723b6175fc6c25dfb6b0bad010161a7fd12b
diff --git a/flags/Android.bp b/flags/Android.bp
index 184f716..02ea821 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -28,6 +28,7 @@
"misc.aconfig",
"subscription.aconfig",
"uicc.aconfig",
+ "satellite.aconfig",
],
}
@@ -35,3 +36,10 @@
name: "telephony_flags-lib",
aconfig_declarations: "telephony_flags"
}
+
+// Create test version of java flag library to access flags using static approach
+java_aconfig_library {
+ name: "telephony_flags-lib-test",
+ aconfig_declarations: "telephony_flags",
+ test: true
+}
diff --git a/flags/satellite.aconfig b/flags/satellite.aconfig
new file mode 100644
index 0000000..e640e6e
--- /dev/null
+++ b/flags/satellite.aconfig
@@ -0,0 +1,15 @@
+package: "com.android.internal.telephony.flags"
+
+flag {
+ name: "oem_enabled_satellite_flag"
+ namespace: "telephony"
+ description: "This flag controls satellite communication supported by OEMs."
+ bug:"291811962"
+}
+
+flag {
+ name: "carrier_enabled_satellite_flag"
+ namespace: "telephony"
+ description: "This flag controls satellite communication supported by carriers."
+ bug:"296437388"
+}
\ No newline at end of file
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 7d04e60..3bc0849 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -107,6 +107,7 @@
import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.emergency.EmergencyStateTracker;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.gsm.GsmMmiCode;
import com.android.internal.telephony.gsm.SsData;
import com.android.internal.telephony.gsm.SuppServiceNotification;
@@ -299,23 +300,26 @@
// Constructors
public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, int phoneId,
- int precisePhoneType, TelephonyComponentFactory telephonyComponentFactory) {
- this(context, ci, notifier, false, phoneId, precisePhoneType, telephonyComponentFactory);
+ int precisePhoneType, TelephonyComponentFactory telephonyComponentFactory,
+ @NonNull FeatureFlags featureFlags) {
+ this(context, ci, notifier, false, phoneId, precisePhoneType, telephonyComponentFactory,
+ featureFlags);
}
public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
boolean unitTestMode, int phoneId, int precisePhoneType,
- TelephonyComponentFactory telephonyComponentFactory) {
+ TelephonyComponentFactory telephonyComponentFactory,
+ @NonNull FeatureFlags featureFlags) {
this(context, ci, notifier,
unitTestMode, phoneId, precisePhoneType,
telephonyComponentFactory,
- ImsManager::getInstance);
+ ImsManager::getInstance, featureFlags);
}
public GsmCdmaPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
boolean unitTestMode, int phoneId, int precisePhoneType,
TelephonyComponentFactory telephonyComponentFactory,
- ImsManagerFactory imsManagerFactory) {
+ ImsManagerFactory imsManagerFactory, @NonNull FeatureFlags featureFlags) {
super(precisePhoneType == PhoneConstants.PHONE_TYPE_GSM ? "GSM" : "CDMA",
notifier, context, ci, unitTestMode, phoneId, telephonyComponentFactory);
@@ -352,7 +356,7 @@
mDataNetworkController = mTelephonyComponentFactory.inject(
DataNetworkController.class.getName())
- .makeDataNetworkController(this, getLooper());
+ .makeDataNetworkController(this, getLooper(), featureFlags);
mCarrierResolver = mTelephonyComponentFactory.inject(CarrierResolver.class.getName())
.makeCarrierResolver(this);
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index 1b05ffd..e49804f 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -49,6 +49,7 @@
import com.android.internal.telephony.euicc.EuiccCardController;
import com.android.internal.telephony.euicc.EuiccController;
import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.flags.FeatureFlagsImpl;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneFactory;
import com.android.internal.telephony.metrics.MetricsCollector;
@@ -104,6 +105,7 @@
static private final HashMap<String, LocalLog>sLocalLogs = new HashMap<String, LocalLog>();
private static MetricsCollector sMetricsCollector;
private static RadioInterfaceCapabilityController sRadioHalCapabilities;
+ private static @NonNull FeatureFlags sFeatureFlags = new FeatureFlagsImpl();
//***** Class Methods
@@ -112,6 +114,7 @@
* @param featureFlags The feature flag.
*/
public static void makeDefaultPhones(Context context, @NonNull FeatureFlags featureFlags) {
+ sFeatureFlags = featureFlags;
makeDefaultPhone(context, featureFlags);
}
@@ -324,7 +327,7 @@
return injectedComponentFactory.makePhone(context,
sCommandsInterfaces[phoneId], sPhoneNotifier, phoneId, phoneType,
- TelephonyComponentFactory.getInstance());
+ TelephonyComponentFactory.getInstance(), sFeatureFlags);
}
@UnsupportedAppUsage
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index f7f24a2..17a4a54 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -40,6 +40,7 @@
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.data.PhoneSwitcher;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
import com.android.internal.telephony.imsphone.ImsNrSaModeHandler;
import com.android.internal.telephony.imsphone.ImsPhone;
@@ -429,9 +430,10 @@
public Phone makePhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
int phoneId, int precisePhoneType,
- TelephonyComponentFactory telephonyComponentFactory) {
+ TelephonyComponentFactory telephonyComponentFactory,
+ @NonNull FeatureFlags featureFlags) {
return new GsmCdmaPhone(context, ci, notifier, phoneId, precisePhoneType,
- telephonyComponentFactory);
+ telephonyComponentFactory, featureFlags);
}
public PhoneSwitcher makePhoneSwitcher(int maxDataAttachModemCount, Context context,
@@ -476,10 +478,12 @@
*
* @param phone The phone object
* @param looper The looper for event handling
+ * @param featureFlags The feature flag.
* @return The data network controller instance
*/
- public DataNetworkController makeDataNetworkController(Phone phone, Looper looper) {
- return new DataNetworkController(phone, looper);
+ public DataNetworkController makeDataNetworkController(Phone phone, Looper looper,
+ @NonNull FeatureFlags featureFlags) {
+ return new DataNetworkController(phone, looper, featureFlags);
}
/**
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index bd99a0c..d13aaf2 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -99,6 +99,7 @@
import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
import com.android.internal.telephony.data.DataStallRecoveryManager.DataStallRecoveryManagerCallback;
import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.ims.ImsResolver;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.telephony.Rlog;
@@ -383,6 +384,8 @@
/** True after try to release an IMS network; False after try to request an IMS network. */
private boolean mLastImsOperationIsRelease;
+ private final @NonNull FeatureFlags mFeatureFlags;
+
/** The broadcast receiver. */
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
@@ -795,10 +798,13 @@
* @param phone The phone instance.
* @param looper The looper to be used by the handler. Currently the handler thread is the
* phone process's main thread.
+ * @param featureFlags The feature flag.
*/
- public DataNetworkController(@NonNull Phone phone, @NonNull Looper looper) {
+ public DataNetworkController(@NonNull Phone phone, @NonNull Looper looper,
+ @NonNull FeatureFlags featureFlags) {
super(looper);
mPhone = phone;
+ mFeatureFlags = featureFlags;
mLogTag = "DNC-" + mPhone.getPhoneId();
log("DataNetworkController created.");
@@ -3814,6 +3820,10 @@
* while using satellite else {@code false}
*/
private boolean isDataDisallowedDueToSatellite(@NetCapability int[] capabilities) {
+ if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ return false;
+ }
+
if (!mServiceState.isUsingNonTerrestrialNetwork()) {
// Device is not connected to satellite
return false;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellBroadcastConfigTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellBroadcastConfigTrackerTest.java
index 40be490..21a14b2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellBroadcastConfigTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellBroadcastConfigTrackerTest.java
@@ -42,6 +42,7 @@
import android.testing.TestableLooper;
import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import org.junit.After;
@@ -49,6 +50,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
import java.util.ArrayList;
import java.util.Arrays;
@@ -60,13 +62,15 @@
private CommandsInterface mSpyCi;
private CellBroadcastConfigTracker mTracker;
+ @Mock private FeatureFlags mFeatureFlags;
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
mSpyCi = spy(mSimulatedCommands);
mPhone = new GsmCdmaPhone(mContext, mSpyCi, mNotifier, true, 0,
- PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager);
+ PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager,
+ mFeatureFlags);
mTracker = CellBroadcastConfigTracker.make(mPhone, mPhone, true);
mPhone.mCellBroadcastConfigTracker = mTracker;
processAllMessages();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 721c0cc..1143190 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -89,6 +89,7 @@
import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import com.android.internal.telephony.emergency.EmergencyStateTracker;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
@@ -113,6 +114,7 @@
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
+import org.mockito.Mock;
import org.mockito.Mockito;
import java.util.ArrayList;
@@ -138,6 +140,7 @@
// app is not currently debuggable. For now, we use the real device config and ensure that
// we reset the cellular_security namespace property to its pre-test value after every test.
private DeviceConfig.Properties mPreTestProperties;
+ @Mock private FeatureFlags mFeatureFlags;
private static final int EVENT_EMERGENCY_CALLBACK_MODE_EXIT = 1;
private static final int EVENT_EMERGENCY_CALL_TOGGLE = 2;
@@ -176,7 +179,8 @@
DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
mPhoneUT = new GsmCdmaPhone(mContext, mSimulatedCommands, mNotifier, true, 0,
- PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager);
+ PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager,
+ mFeatureFlags);
mPhoneUT.setVoiceCallSessionStats(mVoiceCallSessionStats);
ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mUiccController).registerForIccChanged(eq(mPhoneUT), integerArgumentCaptor.capture(),
@@ -1035,7 +1039,8 @@
};
Phone phone = new GsmCdmaPhone(mContext, sc, mNotifier, true, 0,
- PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager);
+ PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager,
+ mFeatureFlags);
phone.setVoiceCallSessionStats(mVoiceCallSessionStats);
ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mUiccController).registerForIccChanged(eq(phone), integerArgumentCaptor.capture(),
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
index a6ccf28..d25a504 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -115,6 +115,7 @@
import com.android.internal.telephony.data.DataNetworkController.HandoverRule;
import com.android.internal.telephony.data.DataRetryManager.DataRetryManagerCallback;
import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.ims.ImsResolver;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
@@ -181,6 +182,7 @@
private boolean mIsNonTerrestrialNetwork = false;
private ArrayList<Integer> mCarrierSupportedSatelliteServices = new ArrayList<>();
+ private FeatureFlags mFeatureFlags;
private final DataProfile mGeneralPurposeDataProfile = new DataProfile.Builder()
.setApnSetting(new ApnSetting.Builder()
@@ -775,6 +777,7 @@
mMockedDataNetworkControllerCallback = Mockito.mock(DataNetworkControllerCallback.class);
mMockedDataRetryManagerCallback = Mockito.mock(DataRetryManagerCallback.class);
mMockSubInfo = Mockito.mock(SubscriptionInfo.class);
+ mFeatureFlags = Mockito.mock(FeatureFlags.class);
when(mTelephonyComponentFactory.makeDataSettingsManager(any(Phone.class),
any(DataNetworkController.class), any(Looper.class),
any(DataSettingsManager.DataSettingsManagerCallback.class))).thenCallRealMethod();
@@ -856,7 +859,8 @@
// to test, in this case, DataNetworkController. But since there are too many interactions
// between DataNetworkController and its sub-modules, we intend to make those modules "real"
// as well, except some modules below we replaced with mocks.
- mDataNetworkControllerUT = new DataNetworkController(mPhone, Looper.myLooper());
+ mDataNetworkControllerUT = new DataNetworkController(mPhone, Looper.myLooper(),
+ mFeatureFlags);
// First two come from DataServiceManager and the third comes from DataConfigManager which
// is what we want to capture and assign to mCarrierConfigChangeListener
verify(mCarrierConfigManager, times(3)).registerCarrierConfigChangeListener(any(),
@@ -1585,6 +1589,7 @@
@Test
public void testNonTerrestrialNetworkChangedWithoutDataSupport() throws Exception {
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
mIsNonTerrestrialNetwork = true;
// Data is not supported while using satellite
mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
@@ -1610,6 +1615,7 @@
@Test
public void testNonTerrestrialNetworkWithDataSupport() throws Exception {
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
mIsNonTerrestrialNetwork = true;
// Data is supported while using satellite
mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_DATA);
@@ -1628,6 +1634,28 @@
}
@Test
+ public void testNonTerrestrialNetworkWithFlagDisabled() throws Exception {
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false);
+
+ mIsNonTerrestrialNetwork = true;
+ // Data is not supported while using satellite
+ mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+ processAllMessages();
+
+ // As feature is disabled, data is connected.
+ verifyInternetConnected();
+
+ mIsNonTerrestrialNetwork = false;
+ mCarrierSupportedSatelliteServices.clear();
+ }
+
+
+ @Test
public void testRoamingDataChanged() throws Exception {
doReturn(true).when(mServiceState).getDataRoaming();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
index 1c1ca0f..1f2cb15 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
@@ -36,11 +36,13 @@
import com.android.internal.telephony.GsmCdmaPhone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.flags.FeatureFlags;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import java.util.ArrayList;
import java.util.concurrent.Executor;
@@ -56,6 +58,7 @@
private static final String TEST_DIAL_STRING_NON_EMERGENCY_NUMBER = "11976";
private GsmMmiCode mGsmMmiCode;
private GsmCdmaPhone mGsmCdmaPhoneUT;
+ @Mock private FeatureFlags mFeatureFlags;
private final Executor mExecutor = Runnable::run;
@@ -64,7 +67,8 @@
super.setUp(getClass().getSimpleName());
doReturn(mExecutor).when(mContext).getMainExecutor();
mGsmCdmaPhoneUT = new GsmCdmaPhone(mContext, mSimulatedCommands, mNotifier, true, 0,
- PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager);
+ PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory, (c, p) -> mImsManager,
+ mFeatureFlags);
setCarrierSupportsCallerIdVerticalServiceCodesCarrierConfig();
}