Filter out satellite plmn when in SAT mode

[SAT-070] : PLMNs associated with SAT MODE, as specified in SAT-008, should not be displayed or selectable in Manual Selection/Network Operator Menu

Bug: 316264277
Test: Manual test with pixel in live network
Test: atest NetworkSelectSettingsTest

Change-Id: Ic100772c97fa1ab18d7e63b654e397d8a80eda8a
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 854d409..11362b8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -454,6 +454,7 @@
         <activity
             android:name="Settings$NetworkSelectActivity"
             android:label="@string/choose_network_title"
+            android:permission="android.permission.SATELLITE_COMMUNICATION"
             android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|smallestScreenSize">
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.network.telephony.NetworkSelectSettings" />
diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
index 5312506..9f0e605 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -34,6 +34,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.satellite.SatelliteManager;
 import android.util.Log;
 import android.view.View;
 
@@ -43,6 +44,7 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
 
+import com.android.internal.annotations.Initializer;
 import com.android.internal.telephony.OperatorInfo;
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
@@ -56,6 +58,8 @@
 import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
 
 /**
  * "Choose network" settings UI for the Settings app.
@@ -82,6 +86,8 @@
     List<CellInfo> mCellInfoList;
     private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     private TelephonyManager mTelephonyManager;
+    private SatelliteManager mSatelliteManager;
+    private CarrierConfigManager mCarrierConfigManager;
     private List<String> mForbiddenPlmns;
     private boolean mShow4GForLTE = false;
     private NetworkScanHelper mNetworkScanHelper;
@@ -93,6 +99,8 @@
     private long mWaitingForNumberOfScanResults;
     @VisibleForTesting
     boolean mIsAggregationEnabled = false;
+    private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
+    private AtomicBoolean mShouldFilterOutSatellitePlmn = new AtomicBoolean();
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -102,28 +110,41 @@
 
     @Keep
     @VisibleForTesting
+    @Initializer
     protected void onCreateInitialization() {
-        mUseNewApi = enableNewAutoSelectNetworkUI(getContext());
+        Context context = getContext();
+        mUseNewApi = enableNewAutoSelectNetworkUI(context);
         mSubId = getSubId();
 
         mPreferenceCategory = getPreferenceCategory(PREF_KEY_NETWORK_OPERATORS);
-        mStatusMessagePreference = new Preference(getContext());
+        mStatusMessagePreference = new Preference(context);
         mStatusMessagePreference.setSelectable(false);
         mSelectedPreference = null;
-        mTelephonyManager = getTelephonyManager(getContext(), mSubId);
+        mTelephonyManager = getTelephonyManager(context, mSubId);
+        mSatelliteManager = getSatelliteManager(context);
+        mCarrierConfigManager = getCarrierConfigManager(context);
         mNetworkScanHelper = new NetworkScanHelper(
                 mTelephonyManager, mCallback, mNetworkScanExecutor);
-        PersistableBundle bundle = getCarrierConfigManager(getContext())
-                .getConfigForSubId(mSubId);
-        if (bundle != null) {
-            mShow4GForLTE = bundle.getBoolean(
-                    CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
-        }
+        PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(mSubId,
+                CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL,
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL);
+        mShow4GForLTE = bundle.getBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL,
+                false);
+        mShouldFilterOutSatellitePlmn.set(bundle.getBoolean(
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL,
+                true));
 
-        mMetricsFeatureProvider = getMetricsFeatureProvider(getContext());
-        mIsAggregationEnabled = enableAggregation(getContext());
+        mMetricsFeatureProvider = getMetricsFeatureProvider(context);
+        mIsAggregationEnabled = enableAggregation(context);
         Log.d(TAG, "init: mUseNewApi:" + mUseNewApi
                 + " ,mIsAggregationEnabled:" + mIsAggregationEnabled + " ,mSubId:" + mSubId);
+
+        mCarrierConfigChangeListener =
+                (slotIndex, subId, carrierId, specificCarrierId) -> handleCarrierConfigChanged(
+                        subId);
+        mCarrierConfigManager.registerCarrierConfigChangeListener(mNetworkScanExecutor,
+                mCarrierConfigChangeListener);
+
     }
 
     @Keep
@@ -167,6 +188,12 @@
 
     @Keep
     @VisibleForTesting
+    protected SatelliteManager getSatelliteManager(Context context) {
+        return context.getSystemService(SatelliteManager.class);
+    }
+
+    @Keep
+    @VisibleForTesting
     protected boolean isPreferenceScreenEnabled() {
         return getPreferenceScreen().isEnabled();
     }
@@ -385,7 +412,43 @@
             }
             aggregatedList.add(cellInfo);
         }
-        return aggregatedList;
+
+        return filterOutSatellitePlmn(aggregatedList);
+    }
+
+    /* We do not want to expose carrier satellite plmns to the user when manually scan the
+       cellular network. Therefore, it is needed to filter out satellite plmns from current cell
+       info list  */
+    private List<CellInfo> filterOutSatellitePlmn(List<CellInfo> cellInfoList) {
+        List<String> aggregatedSatellitePlmn = getAllSatellitePlmnsForCarrierWrapper();
+        if (!mShouldFilterOutSatellitePlmn.get() || aggregatedSatellitePlmn.isEmpty()) {
+            return cellInfoList;
+        }
+        return cellInfoList.stream()
+                .filter(cellInfo -> !aggregatedSatellitePlmn.contains(
+                        CellInfoUtil.getOperatorNumeric(cellInfo.getCellIdentity())))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Serves as a wrapper method for {@link SatelliteManager#getAllSatellitePlmnsForCarrier(int)}.
+     * Since SatelliteManager is final, this wrapper enables mocking or spying of
+     * {@link SatelliteManager#getAllSatellitePlmnsForCarrier(int)} for unit testing purposes.
+     */
+    @VisibleForTesting
+    protected List<String> getAllSatellitePlmnsForCarrierWrapper() {
+        return mSatelliteManager.getAllSatellitePlmnsForCarrier(mSubId);
+    }
+
+    private void handleCarrierConfigChanged(int subId) {
+        PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId,
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL);
+        boolean shouldFilterSatellitePlmn = config.getBoolean(
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL,
+                true);
+        if (shouldFilterSatellitePlmn != mShouldFilterOutSatellitePlmn.get()) {
+            mShouldFilterOutSatellitePlmn.set(shouldFilterSatellitePlmn);
+        }
     }
 
     private final NetworkScanHelper.NetworkScanCallback mCallback =
diff --git a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
index 301ea11..6678603 100644
--- a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
@@ -17,6 +17,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -50,6 +51,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -277,6 +279,102 @@
         assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
     }
 
+    @Test
+    public void doAggregation_filterOutSatellitePlmn_whenKeyIsTrue() {
+        PersistableBundle config = new PersistableBundle();
+        config.putBoolean(
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true);
+        doReturn(config).when(mCarrierConfigManager).getConfigForSubId(eq(SUB_ID),
+                eq(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL),
+                eq(CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL));
+
+        List<String> testSatellitePlmn = new ArrayList<>(Arrays.asList("123232", "123235"));
+        doReturn(testSatellitePlmn).when(
+                mNetworkSelectSettings).getAllSatellitePlmnsForCarrierWrapper();
+
+        /* Expect filter out satellite plmns when
+           KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL is true, and there is available
+           satellite plmns. */
+        mNetworkSelectSettings.onCreateInitialization();
+        List<CellInfo> testList = Arrays.asList(
+                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
+                createGsmCellInfo(false, 123, "123", "233", "CarrierB"),
+                createLteCellInfo(false, 1234, "123", "234", "CarrierC"),
+                createGsmCellInfo(false, 1234, "123", "235", "CarrierD"));
+        List<CellInfo> expected = Arrays.asList(
+                createGsmCellInfo(false, 123, "123", "233", "CarrierB"),
+                createLteCellInfo(false, 1234, "123", "234", "CarrierC"));
+        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
+    }
+
+    @Test
+    public void doAggregation_filterOutSatellitePlmn_whenNoSatellitePlmnIsAvailable() {
+        PersistableBundle config = new PersistableBundle();
+        config.putBoolean(
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true);
+        doReturn(config).when(mCarrierConfigManager).getConfigForSubId(eq(SUB_ID),
+                eq(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL),
+                eq(CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL));
+
+        List<String> testSatellitePlmn = new ArrayList<>(Arrays.asList("123232", "123235"));
+        doReturn(testSatellitePlmn).when(
+                mNetworkSelectSettings).getAllSatellitePlmnsForCarrierWrapper();
+
+        // Expect no filter out when there is no available satellite plmns.
+        mNetworkSelectSettings.onCreateInitialization();
+        testSatellitePlmn = new ArrayList<>();
+        doReturn(testSatellitePlmn).when(
+                mNetworkSelectSettings).getAllSatellitePlmnsForCarrierWrapper();
+        mNetworkSelectSettings.onCreateInitialization();
+        List<CellInfo> testList = Arrays.asList(
+                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
+                createGsmCellInfo(false, 123, "123", "233", "CarrierB"),
+                createLteCellInfo(false, 1234, "123", "234", "CarrierC"),
+                createGsmCellInfo(false, 12345, "123", "235", "CarrierD"));
+        List<CellInfo> expected = Arrays.asList(
+                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
+                createGsmCellInfo(false, 123, "123", "233", "CarrierB"),
+                createLteCellInfo(false, 1234, "123", "234", "CarrierC"),
+                createGsmCellInfo(false, 12345, "123", "235", "CarrierD"));
+        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
+
+        // Expect no filter out when KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL is false.
+        config.putBoolean(
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, false);
+        mNetworkSelectSettings.onCreateInitialization();
+        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
+    }
+
+    @Test
+    public void doAggregation_filterOutSatellitePlmn_whenKeyIsFalse() {
+        PersistableBundle config = new PersistableBundle();
+        config.putBoolean(
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true);
+        doReturn(config).when(mCarrierConfigManager).getConfigForSubId(eq(SUB_ID),
+                eq(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL),
+                eq(CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL));
+
+        List<String> testSatellitePlmn = new ArrayList<>(Arrays.asList("123232", "123235"));
+        doReturn(testSatellitePlmn).when(
+                mNetworkSelectSettings).getAllSatellitePlmnsForCarrierWrapper();
+
+        // Expect no filter out when KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL is false.
+        config.putBoolean(
+                CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, false);
+        mNetworkSelectSettings.onCreateInitialization();
+        List<CellInfo> testList = Arrays.asList(
+                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
+                createGsmCellInfo(false, 123, "123", "233", "CarrierB"),
+                createLteCellInfo(false, 1234, "123", "234", "CarrierC"),
+                createGsmCellInfo(false, 12345, "123", "235", "CarrierD"));
+        List<CellInfo> expected = Arrays.asList(
+                createLteCellInfo(true, 123, "123", "232", "CarrierA"),
+                createGsmCellInfo(false, 123, "123", "233", "CarrierB"),
+                createLteCellInfo(false, 1234, "123", "234", "CarrierC"),
+                createGsmCellInfo(false, 12345, "123", "235", "CarrierD"));
+        assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected);
+    }
+
     private CellInfoLte createLteCellInfo(boolean registered, int cellId, String mcc, String mnc,
             String plmnName) {
         CellIdentityLte cil = new CellIdentityLte(