Configure earfcns to modem
Change-Id: I2d7d2dedb5a5ee92ffff3c8c2e14246aa57704b9
Flag: com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn
Bug: 373872272
Test: SatelliteManagerTestOnMockService SatelliteAccessControllerTest
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index f3028cf..47c00af 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -13227,14 +13227,17 @@
return;
}
if (isAllowed) {
- if (mFeatureFlags.carrierRoamingNbIotNtn()
- && !mSatelliteAccessController.getSatelliteDisallowedReasons()
- .isEmpty()) {
- result.accept(SATELLITE_RESULT_ACCESS_BARRED);
- } else {
- mSatelliteController.requestSatelliteEnabled(
+ ResultReceiver resultReceiver = new ResultReceiver(mMainThreadHandler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ Log.d(LOG_TAG, "updateSystemSelectionChannels resultCode="
+ + resultCode);
+ mSatelliteController.requestSatelliteEnabled(
enableSatellite, enableDemoMode, isEmergency, callback);
- }
+ }
+ };
+ mSatelliteAccessController.updateSystemSelectionChannels(
+ resultReceiver);
} else {
result.accept(SATELLITE_RESULT_ACCESS_BARRED);
}
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index c1cc74e..d0d0e8f 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -59,6 +59,7 @@
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
@@ -71,10 +72,12 @@
import android.provider.DeviceConfig;
import android.telecom.TelecomManager;
import android.telephony.AnomalyReporter;
+import android.telephony.CarrierConfigManager;
import android.telephony.DropBoxManagerLoggerBackend;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PersistentLogger;
import android.telephony.Rlog;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
import android.telephony.satellite.ISatelliteDisallowedReasonsCallback;
@@ -83,7 +86,9 @@
import android.telephony.satellite.SatelliteAccessConfiguration;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
+import android.telephony.satellite.SystemSelectionSpecifier;
import android.text.TextUtils;
+import android.util.IntArray;
import android.util.Pair;
import com.android.internal.R;
@@ -100,6 +105,7 @@
import com.android.internal.telephony.satellite.metrics.AccessControllerMetricsStats;
import com.android.internal.telephony.satellite.metrics.ConfigUpdaterMetricsStats;
import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.phone.PhoneGlobals;
@@ -162,6 +168,7 @@
protected static final int EVENT_CONFIG_DATA_UPDATED = 4;
protected static final int EVENT_COUNTRY_CODE_CHANGED = 5;
protected static final int EVENT_LOCATION_SETTINGS_ENABLED = 6;
+ protected static final int CMD_UPDATE_SYSTEM_SELECTION_CHANNELS = 7;
public static final int DEFAULT_REGIONAL_SATELLITE_CONFIG_ID = 0;
public static final int UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID = -1;
@@ -246,11 +253,16 @@
@NonNull
private final ISatelliteProvisionStateCallback mInternalSatelliteProvisionStateCallback;
@NonNull
+ private final ResultReceiver mInternalUpdateSystemSelectionChannelsResultReceiver;
+ @NonNull
protected final Object mLock = new Object();
@GuardedBy("mLock")
@NonNull
private final Set<ResultReceiver> mSatelliteAllowResultReceivers = new HashSet<>();
@NonNull
+ private final Set<ResultReceiver>
+ mUpdateSystemSelectionChannelsResultReceivers = new HashSet<>();
+ @NonNull
private List<String> mSatelliteCountryCodes;
private boolean mIsSatelliteAllowAccessControl;
@Nullable
@@ -292,6 +304,17 @@
@NonNull
private HashMap<Integer, SatelliteAccessConfiguration> mSatelliteAccessConfigMap =
new HashMap<>();
+ @NonNull private final CarrierConfigManager mCarrierConfigManager;
+ @NonNull private final CarrierConfigManager.CarrierConfigChangeListener
+ mCarrierConfigChangeListener;
+ /**
+ * Key: Sub Id, Value: (key: Regional satellite config Id, value: SatelliteRegionalConfig
+ * contains satellite config IDs and set of earfcns in the corresponding regions).
+ */
+ @GuardedBy("mRegionalSatelliteEarfcnsLock")
+ private Map<Integer, Map<Integer, SatelliteRegionalConfig>>
+ mSatelliteRegionalConfigPerSubMap = new HashMap();
+ @NonNull private final Object mRegionalSatelliteEarfcnsLock = new Object();
/** These are used for CTS test */
private Path mCtsSatS2FilePath = null;
@@ -531,11 +554,29 @@
mInternalSatelliteProvisionStateCallback);
plogd("registerForSatelliteProvisionStateChanged result: " + result);
+ mInternalUpdateSystemSelectionChannelsResultReceiver = new ResultReceiver(this) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ plogd("UpdateSystemSelectionChannels.onReceiveResult: resultCode=" + resultCode
+ + ", resultData=" + resultData);
+ sendUpdateSystemSelectionChannelsResult(resultCode, resultData);
+ }
+ };
+
// Init the SatelliteOnDeviceAccessController so that the S2 level can be cached
initSatelliteOnDeviceAccessController();
initializeSatelliteSystemNotification(context);
registerLocationModeChangedBroadcastReceiver(context);
registerDefaultSmsAppChangedBroadcastReceiver(context);
+
+ mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
+ mCarrierConfigChangeListener =
+ (slotIndex, subId, carrierId, specificCarrierId) ->
+ handleCarrierConfigChanged(slotIndex, subId, carrierId, specificCarrierId);
+ if (mCarrierConfigManager != null) {
+ mCarrierConfigManager.registerCarrierConfigChangeListener(
+ new HandlerExecutor(new Handler(looper)), mCarrierConfigChangeListener);
+ }
}
private void updateCurrentSatelliteAllowedState(boolean isAllowed) {
@@ -595,6 +636,9 @@
case EVENT_COUNTRY_CODE_CHANGED:
handleSatelliteAllowedRegionPossiblyChanged(msg.what);
break;
+ case CMD_UPDATE_SYSTEM_SELECTION_CHANNELS:
+ handleCmdUpdateSystemSelectionChannels((ResultReceiver) msg.obj);
+ break;
default:
plogw("SatelliteAccessControllerHandler: unexpected message code: " + msg.what);
break;
@@ -734,6 +778,28 @@
return true;
}
+ /**
+ * Report updated system selection to modem and report the update result.
+ */
+ public void updateSystemSelectionChannels(@NonNull ResultReceiver result) {
+ plogd("updateSystemSelectionChannels");
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("updateSystemSelectionChannels: "
+ + "carrierRoamingNbIotNtn flag is disabled");
+ result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
+ return;
+ }
+ synchronized (mLock) {
+ if (mRegionalConfigId == null) {
+ plogd("updateSystemSelectionChannels: Invalid Regional config ID."
+ + " System Selection channels can not be passed down to modem");
+ result.send(SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED, null);
+ return;
+ }
+ }
+ sendRequestAsync(CMD_UPDATE_SYSTEM_SELECTION_CHANNELS, result);
+ }
+
protected File getTestSatelliteS2File(String fileName) {
plogd("getTestSatelliteS2File: fileName=" + fileName);
if (TextUtils.equals(fileName, GOOGLE_US_SAN_SAT_S2_FILE_NAME)) {
@@ -2073,6 +2139,78 @@
}
}
+ private void handleCmdUpdateSystemSelectionChannels(
+ @NonNull ResultReceiver resultReceiver) {
+ synchronized (mLock) {
+ mUpdateSystemSelectionChannelsResultReceivers.add(resultReceiver);
+ if (mUpdateSystemSelectionChannelsResultReceivers.size() > 1) {
+ plogd("updateSystemSelectionChannels is already being processed");
+ return;
+ }
+ int subId = mSatelliteController.getSelectedSatelliteSubId();
+ plogd("handleCmdUpdateSystemSelectionChannels: SatellitePhone subId: " + subId);
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ sendUpdateSystemSelectionChannelsResult(
+ SATELLITE_RESULT_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+
+ String mccmnc = "";
+ final SubscriptionInfo subInfo = SubscriptionManagerService.getInstance()
+ .getSubscriptionInfo(subId);
+ if (subInfo != null) {
+ mccmnc = subInfo.getMccString() + subInfo.getMncString();
+ }
+
+ synchronized (mRegionalSatelliteEarfcnsLock) {
+ /* Key: Regional satellite config ID, Value: SatelliteRegionalConfig
+ * contains satellite config IDs and set of earfcns in the corresponding regions.
+ */
+ Map<Integer, SatelliteRegionalConfig> satelliteRegionalConfigMap =
+ mSatelliteRegionalConfigPerSubMap.get(subId);
+ if (satelliteRegionalConfigMap == null || satelliteRegionalConfigMap.isEmpty()) {
+ plogd("handleCmdUpdateSystemSelectionChannels: config IDs and Earfcns are not"
+ + " found for subId: "
+ + subId);
+ sendUpdateSystemSelectionChannelsResult(
+ SATELLITE_RESULT_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+
+ SatelliteRegionalConfig satelliteRegionalConfig = satelliteRegionalConfigMap.get(
+ mRegionalConfigId);
+ if (satelliteRegionalConfig == null) {
+ plogd("handleCmdUpdateSystemSelectionChannels: "
+ + "Earfcns for satellite config Id: " + mRegionalConfigId
+ + " not found");
+ sendUpdateSystemSelectionChannelsResult(
+ SATELLITE_RESULT_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+ IntArray bands = new IntArray();
+ IntArray earfcns = new IntArray();
+ for (Integer value : satelliteRegionalConfig.getEarfcns()) {
+ earfcns.add(value);
+ }
+
+ mSatelliteController.updateSystemSelectionChannels(
+ new SystemSelectionSpecifier(mccmnc, bands, earfcns),
+ mInternalUpdateSystemSelectionChannelsResultReceiver);
+ }
+ }
+ }
+
+ private void sendUpdateSystemSelectionChannelsResult(int resultCode, Bundle resultData) {
+ plogd("sendUpdateSystemSelectionChannelsResult: resultCode=" + resultCode);
+
+ synchronized (mLock) {
+ for (ResultReceiver resultReceiver : mUpdateSystemSelectionChannelsResultReceivers) {
+ resultReceiver.send(resultCode, resultData);
+ }
+ mUpdateSystemSelectionChannelsResultReceivers.clear();
+ }
+ }
+
private static boolean getSatelliteAccessAllowFromOverlayConfig(@NonNull Context context) {
Boolean accessAllowed = null;
try {
@@ -2618,6 +2756,69 @@
resetRequired);
}
+ private static final class SatelliteRegionalConfig {
+ /** Regional satellite config IDs */
+ private final int mConfigId;
+
+ /** Set of earfcns in the corresponding regions */
+ private final Set<Integer> mEarfcns;
+
+ SatelliteRegionalConfig(int configId, Set<Integer> earfcns) {
+ this.mConfigId = configId;
+ this.mEarfcns = earfcns;
+ }
+
+ public Set<Integer> getEarfcns() {
+ return mEarfcns;
+ }
+ }
+
+ private void updateSatelliteRegionalConfig(int subId) {
+ plogd("updateSatelliteRegionalConfig: subId: " + subId);
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ return;
+ }
+
+ mSatelliteController.updateRegionalSatelliteEarfcns(subId);
+ //key: regional satellite config Id,
+ //value: set of earfcns in the corresponding regions
+ Map<String, Set<Integer>> earfcnsMap = mSatelliteController
+ .getRegionalSatelliteEarfcns(subId);
+ if (earfcnsMap.isEmpty()) {
+ plogd("updateSatelliteRegionalConfig: Earfcns are not found for subId: "
+ + subId);
+ return;
+ }
+
+ synchronized (mRegionalSatelliteEarfcnsLock) {
+ SatelliteRegionalConfig satelliteRegionalConfig;
+ /* Key: Regional satellite config ID, Value: SatelliteRegionalConfig
+ * contains satellite config IDs and set of earfcns in the corresponding regions.
+ */
+ Map<Integer, SatelliteRegionalConfig> satelliteRegionalConfigMap = new HashMap<>();
+ for (String configId: earfcnsMap.keySet()) {
+ Set<Integer> earfcnsSet = new HashSet<>();
+ for (int earfcn : earfcnsMap.get(configId)) {
+ earfcnsSet.add(earfcn);
+ }
+ satelliteRegionalConfig = new SatelliteRegionalConfig(Integer.valueOf(configId),
+ earfcnsSet);
+ satelliteRegionalConfigMap.put(Integer.valueOf(configId), satelliteRegionalConfig);
+ }
+
+ mSatelliteRegionalConfigPerSubMap.put(subId, satelliteRegionalConfigMap);
+ }
+ }
+
+ private void handleCarrierConfigChanged(int slotIndex, int subId,
+ int carrierId, int specificCarrierId) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("handleCarrierConfigChanged: carrierRoamingNbIotNtn flag is disabled");
+ return;
+ }
+ updateSatelliteRegionalConfig(subId);
+ }
+
private void plogv(@NonNull String log) {
Rlog.v(TAG, log);
if (mPersistentLogger != null) {