[NTN][Geofence] CTS for geofence enhancement

Added an enhanced sats2dat test file, which contains entry values
Added an test purpose satellite configuration file
Added logics for loading / parsing / triggering satellite configuration

Bug: 379944543
Flag: com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn
Test: Generte new sats2 dat file and verify with tool
Test: atest cts/SatelliteManagerTestOnMockService to verify whether
it works as intended

Change-Id: I83c8f84884cf2e3b58e2a9d246577cf68bb62089
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 6e7306a..cf83585 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -14363,12 +14363,13 @@
      */
     public boolean setSatelliteAccessControlOverlayConfigs(boolean reset, boolean isAllowed,
             String s2CellFile, long locationFreshDurationNanos,
-            List<String> satelliteCountryCodes) {
+            List<String> satelliteCountryCodes, String satelliteAccessConfigurationFile) {
         Log.d(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: reset=" + reset
                 + ", isAllowed" + isAllowed + ", s2CellFile=" + s2CellFile
                 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
                 + ", satelliteCountryCodes=" + ((satelliteCountryCodes != null)
-                ? String.join(", ", satelliteCountryCodes) : null));
+                ? String.join(", ", satelliteCountryCodes) : null)
+                + ", satelliteAccessConfigurationFile=" + satelliteAccessConfigurationFile);
         TelephonyPermissions.enforceShellOnly(
                 Binder.getCallingUid(), "setSatelliteAccessControlOverlayConfigs");
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
@@ -14377,7 +14378,8 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             return mSatelliteAccessController.setSatelliteAccessControlOverlayConfigs(reset,
-                    isAllowed, s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
+                    isAllowed, s2CellFile, locationFreshDurationNanos, satelliteCountryCodes,
+                    satelliteAccessConfigurationFile);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 93ac55e..cd6a369 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -3593,9 +3593,11 @@
         String s2CellFile = null;
         long locationFreshDurationNanos = 0;
         List<String> satelliteCountryCodes = null;
+        String satelliteAccessConfigurationFile = null;
 
         String opt;
         while ((opt = getNextOption()) != null) {
+            Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: opt=" + opt);
             switch (opt) {
                 case "-r": {
                     reset = true;
@@ -3618,16 +3620,22 @@
                     satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
                     break;
                 }
+                case "-g": {
+                    satelliteAccessConfigurationFile = getNextArgRequired();
+                    break;
+                }
             }
         }
         Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
                 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
                 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
-                + ", satelliteCountryCodes=" + satelliteCountryCodes);
+                + ", satelliteCountryCodes=" + satelliteCountryCodes
+                + ", satelliteAccessConfigurationFile=" + satelliteAccessConfigurationFile);
 
         try {
             boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
-                    s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
+                    s2CellFile, locationFreshDurationNanos, satelliteCountryCodes,
+                    satelliteAccessConfigurationFile);
             if (VDBG) {
                 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
             }
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index f17377c..c837772 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -285,6 +285,8 @@
     private boolean mOverriddenIsSatelliteAllowAccessControl;
     @Nullable
     private File mOverriddenSatelliteS2CellFile;
+    @Nullable
+    private String mOverriddenSatelliteConfigurationFileName;
     private long mOverriddenLocationFreshDurationNanos;
 
     @GuardedBy("mLock")
@@ -331,7 +333,12 @@
 
     /** These are used for CTS test */
     private Path mCtsSatS2FilePath = null;
+    private Path mCtsSatelliteAccessConfigurationFilePath = null;
     protected static final String GOOGLE_US_SAN_SAT_S2_FILE_NAME = "google_us_san_sat_s2.dat";
+    protected static final String GOOGLE_US_SAN_SAT_MTV_S2_FILE_NAME =
+            "google_us_san_mtv_sat_s2.dat";
+    protected static final String SATELLITE_ACCESS_CONFIG_FILE_NAME =
+            "satellite_access_config.json";
 
     /** These are for config updater config data */
     private static final String SATELLITE_ACCESS_CONTROL_DATA_DIR = "satellite_access_control";
@@ -614,8 +621,8 @@
                         mNewRegionalConfigId = null;
                     }
                 }
-                updateRegionalConfigId();
             }
+            updateRegionalConfigId();
         }
     }
 
@@ -759,7 +766,8 @@
      */
     public boolean setSatelliteAccessControlOverlayConfigs(boolean reset, boolean isAllowed,
             @Nullable String s2CellFile, long locationFreshDurationNanos,
-            @Nullable List<String> satelliteCountryCodes) {
+            @Nullable List<String> satelliteCountryCodes,
+            @Nullable String satelliteConfigurationFile) {
         if (!isMockModemAllowed()) {
             plogd("setSatelliteAccessControllerOverlayConfigs: mock modem is not allowed");
             return false;
@@ -768,7 +776,8 @@
                 + ", isAllowed" + isAllowed + ", s2CellFile=" + s2CellFile
                 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
                 + ", satelliteCountryCodes=" + ((satelliteCountryCodes != null)
-                ? String.join(", ", satelliteCountryCodes) : null));
+                ? String.join(", ", satelliteCountryCodes) : null)
+                + ", satelliteConfigurationFile=" + satelliteConfigurationFile);
         synchronized (mLock) {
             if (reset) {
                 mIsOverlayConfigOverridden = false;
@@ -784,9 +793,25 @@
                                 + " does not exist");
                         mOverriddenSatelliteS2CellFile = null;
                     }
+                    mCachedAccessRestrictionMap.clear();
                 } else {
                     mOverriddenSatelliteS2CellFile = null;
                 }
+                if (!TextUtils.isEmpty(satelliteConfigurationFile)) {
+                    File overriddenSatelliteConfigurationFile = getTestSatelliteConfiguration(
+                            satelliteConfigurationFile);
+                    if (overriddenSatelliteConfigurationFile.exists()) {
+                        mOverriddenSatelliteConfigurationFileName =
+                                overriddenSatelliteConfigurationFile.getAbsolutePath();
+                    } else {
+                        plogd("The overriding file "
+                                + overriddenSatelliteConfigurationFile.getAbsolutePath()
+                                + " does not exist");
+                        mOverriddenSatelliteConfigurationFileName = null;
+                    }
+                } else {
+                    mOverriddenSatelliteConfigurationFileName = null;
+                }
                 mOverriddenLocationFreshDurationNanos = locationFreshDurationNanos;
                 if (satelliteCountryCodes != null) {
                     mOverriddenSatelliteCountryCodes = satelliteCountryCodes;
@@ -824,8 +849,9 @@
 
     protected File getTestSatelliteS2File(String fileName) {
         plogd("getTestSatelliteS2File: fileName=" + fileName);
-        if (TextUtils.equals(fileName, GOOGLE_US_SAN_SAT_S2_FILE_NAME)) {
-            mCtsSatS2FilePath = copyTestSatS2FileToPhoneDirectory(GOOGLE_US_SAN_SAT_S2_FILE_NAME);
+        if (TextUtils.equals(fileName, GOOGLE_US_SAN_SAT_S2_FILE_NAME)
+                || TextUtils.equals(fileName, GOOGLE_US_SAN_SAT_MTV_S2_FILE_NAME)) {
+            mCtsSatS2FilePath = copyTestAssetFileToPhoneDirectory(fileName);
             if (mCtsSatS2FilePath != null) {
                 return mCtsSatS2FilePath.toFile();
             } else {
@@ -835,8 +861,21 @@
         return new File(fileName);
     }
 
+    protected File getTestSatelliteConfiguration(String fileName) {
+        plogd("getTestSatelliteConfiguration: fileName=" + fileName);
+        if (TextUtils.equals(fileName, SATELLITE_ACCESS_CONFIG_FILE_NAME)) {
+            mCtsSatelliteAccessConfigurationFilePath = copyTestAssetFileToPhoneDirectory(fileName);
+            if (mCtsSatelliteAccessConfigurationFilePath != null) {
+                return mCtsSatelliteAccessConfigurationFilePath.toFile();
+            } else {
+                ploge("getTestSatelliteConfiguration: mCtsSatelliteConfigurationFilePath is null");
+            }
+        }
+        return new File(fileName);
+    }
+
     @Nullable
-    private static Path copyTestSatS2FileToPhoneDirectory(String sourceFileName) {
+    private static Path copyTestAssetFileToPhoneDirectory(String sourceFileName) {
         PhoneGlobals phoneGlobals = PhoneGlobals.getInstance();
         File ctsFile = phoneGlobals.getDir("cts", Context.MODE_PRIVATE);
         if (!ctsFile.exists()) {
@@ -844,26 +883,26 @@
         }
 
         Path targetDir = ctsFile.toPath();
-        Path targetSatS2FilePath = targetDir.resolve(sourceFileName);
+        Path targetFilePath = targetDir.resolve(sourceFileName);
         try {
             var assetManager = phoneGlobals.getAssets();
             if (assetManager == null) {
-                loge("copyTestSatS2FileToPhoneDirectory: no assets");
+                loge("copyTestAssetFileToPhoneDirectory: no assets");
                 return null;
             }
             InputStream inputStream = assetManager.open(sourceFileName);
             if (inputStream == null) {
-                loge("copyTestSatS2FileToPhoneDirectory: Resource=" + sourceFileName
+                loge("copyTestAssetFileToPhoneDirectory: Resource=" + sourceFileName
                         + " not found");
                 return null;
             } else {
-                Files.copy(inputStream, targetSatS2FilePath, StandardCopyOption.REPLACE_EXISTING);
+                Files.copy(inputStream, targetFilePath, StandardCopyOption.REPLACE_EXISTING);
             }
         } catch (IOException ex) {
-            loge("copyTestSatS2FileToPhoneDirectory: ex=" + ex);
+            loge("copyTestAssetFileToPhoneDirectory: ex=" + ex);
             return null;
         }
-        return targetSatS2FilePath;
+        return targetFilePath;
     }
 
     @Nullable
@@ -1128,8 +1167,16 @@
     }
 
     protected void loadSatelliteAccessConfigurationFromDeviceConfig() {
-        String satelliteConfigurationFileName =
-                getSatelliteConfigurationFileNameFromOverlayConfig(mContext);
+        logd("loadSatelliteAccessConfigurationFromDeviceConfig:");
+        String satelliteConfigurationFileName;
+        synchronized (mLock) {
+            if (mIsOverlayConfigOverridden && mOverriddenSatelliteConfigurationFileName != null) {
+                satelliteConfigurationFileName = mOverriddenSatelliteConfigurationFileName;
+            } else {
+                satelliteConfigurationFileName = getSatelliteConfigurationFileNameFromOverlayConfig(
+                        mContext);
+            }
+        }
         loadSatelliteAccessConfigurationFromFile(satelliteConfigurationFileName);
     }