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();
     }