Add requestRegionalSatelliteConfigurationForCurrentLocation and onRegionalSatelliteConfigurationChanged
Bug: 371438277
Flag: com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn
Test: atest
SatelliteAccessControllerTest(http://ab/I58000010332908616-pass)
Test: Manually verified satellite is working well in both demo and real(b/371438277#comment4)
Change-Id: Ic8363191ff9f5750916bbe33481c33b1ad914af2
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index bd90a9d..6c52af2 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -13723,6 +13723,29 @@
}
/**
+ * Request to get satellite access configuration for the current location.
+ *
+ * @param result The result receiver that returns the satellite access configuration
+ * for the current location if the request is successful or an error code
+ * if the request failed.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void requestSatelliteAccessConfigurationForCurrentLocation(
+ @NonNull ResultReceiver result) {
+ enforceSatelliteCommunicationPermission(
+ "requestSatelliteAccessConfigurationForCurrentLocation");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteAccessController
+ .requestSatelliteAccessConfigurationForCurrentLocation(result);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
* Request to get the time after which the satellite will be visible.
*
* @param result The result receiver that returns the time after which the satellite will
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index 49edf6a..2571bbc 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -16,6 +16,7 @@
package com.android.phone.satellite.accesscontrol;
+import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_ACCESS_CONFIGURATION;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_PROVISIONED;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_SUPPORTED;
@@ -24,6 +25,7 @@
import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_NOT_IN_ALLOWED_REGION;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_LOCATION_DISABLED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_DISABLED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_NOT_AVAILABLE;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
@@ -78,6 +80,7 @@
import android.telephony.satellite.ISatelliteDisallowedReasonsCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteSupportedStateCallback;
+import android.telephony.satellite.SatelliteAccessConfiguration;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.text.TextUtils;
@@ -116,6 +119,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@@ -160,6 +164,8 @@
protected static final int EVENT_LOCATION_SETTINGS_ENABLED = 6;
public static final int DEFAULT_REGIONAL_SATELLITE_CONFIG_ID = 0;
+ public static final int UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID = -1;
+
private static final String KEY_AVAILABLE_NOTIFICATION_SHOWN = "available_notification_shown";
private static final String KEY_UNAVAILABLE_NOTIFICATION_SHOWN =
@@ -260,11 +266,11 @@
private long mOverriddenLocationFreshDurationNanos;
@GuardedBy("mLock")
@NonNull
- private final Map<SatelliteOnDeviceAccessController.LocationToken, Boolean>
+ private final Map<SatelliteOnDeviceAccessController.LocationToken, Integer>
mCachedAccessRestrictionMap = new LinkedHashMap<>() {
@Override
protected boolean removeEldestEntry(
- Entry<SatelliteOnDeviceAccessController.LocationToken, Boolean> eldest) {
+ Entry<SatelliteOnDeviceAccessController.LocationToken, Integer> eldest) {
return size() > MAX_CACHE_SIZE;
}
};
@@ -277,7 +283,15 @@
private Location mFreshLastKnownLocation = null;
@GuardedBy("mLock")
@Nullable
- private Integer mRegionalConfigId = null;
+ protected Integer mRegionalConfigId = null;
+ @GuardedBy("mLock")
+ @Nullable
+ protected Integer mNewRegionalConfigId = null;
+
+ /** Key: Config ID; Value: SatelliteAccessConfiguration */
+ @NonNull
+ private HashMap<Integer, SatelliteAccessConfiguration> mSatelliteAccessConfigMap =
+ new HashMap<>();
/** These are used for CTS test */
private Path mCtsSatS2FilePath = null;
@@ -522,6 +536,13 @@
mCurrentSatelliteAllowedState = isAllowed;
notifySatelliteCommunicationAllowedStateChanged(isAllowed);
mControllerMetricsStats.reportAllowedStateChanged();
+ if (!isAllowed) {
+ synchronized (mLock) {
+ plogd("updateCurrentSatelliteAllowedState : set mNewRegionalConfigId null");
+ mNewRegionalConfigId = null;
+ }
+ }
+ updateRegionalConfigId();
}
}
}
@@ -594,6 +615,66 @@
}
/**
+ * Request to get satellite access configuration for the current location.
+ *
+ * @param result The result receiver that returns satellite access configuration
+ * for the current location if the request is successful or an error code
+ * if the request failed.
+ */
+ public void requestSatelliteAccessConfigurationForCurrentLocation(
+ @NonNull ResultReceiver result) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("carrierRoamingNbIotNtnFlag is disabled");
+ result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
+ return;
+ }
+ plogd("requestSatelliteAccessConfigurationForCurrentLocation");
+ ResultReceiver internalResultReceiver = new ResultReceiver(this) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ plogd("requestSatelliteAccessConfigurationForCurrentLocation: resultCode="
+ + resultCode + ", resultData=" + resultData);
+ boolean isSatelliteCommunicationAllowed = false;
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
+ isSatelliteCommunicationAllowed =
+ resultData.getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED);
+ } else {
+ loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
+ result.send(SATELLITE_RESULT_INVALID_TELEPHONY_STATE, null);
+ return;
+ }
+ } else {
+ loge("resultCode is not SATELLITE_RESULT_SUCCESS.");
+ result.send(resultCode, null);
+ return;
+ }
+
+ SatelliteAccessConfiguration satelliteAccessConfig = null;
+ synchronized (mLock) {
+ if (isSatelliteCommunicationAllowed && isRegionalConfigIdValid(
+ mRegionalConfigId)) {
+ plogd("requestSatelliteAccessConfigurationForCurrentLocation : "
+ + "mRegionalConfigId is " + mRegionalConfigId);
+ satelliteAccessConfig =
+ mSatelliteAccessConfigMap.get(mRegionalConfigId);
+ }
+ }
+ plogd("requestSatelliteAccessConfigurationForCurrentLocation : "
+ + "satelliteAccessConfig is " + satelliteAccessConfig);
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(KEY_SATELLITE_ACCESS_CONFIGURATION, satelliteAccessConfig);
+ result.send(resultCode, bundle);
+ }
+ };
+ requestIsCommunicationAllowedForCurrentLocation(internalResultReceiver, false);
+ }
+
+ private boolean isRegionalConfigIdValid(@Nullable Integer configId) {
+ return (configId != null && configId >= 0);
+ }
+
+ /**
* This API should be used by only CTS tests to override the overlay configs of satellite
* access controller.
*/
@@ -1125,8 +1206,8 @@
if (isRegionDisallowed(networkCountryIsoList)) {
Bundle bundle = new Bundle();
bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, false);
- mAccessControllerMetricsStats.setAccessControlType(
- SatelliteConstants.ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE)
+ mAccessControllerMetricsStats.setAccessControlType(SatelliteConstants
+ .ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE)
.setCountryCodes(networkCountryIsoList);
sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle,
false);
@@ -1704,8 +1785,11 @@
location.getLatitude(),
location.getLongitude(), mS2Level);
boolean satelliteAllowed;
+
if (mCachedAccessRestrictionMap.containsKey(locationToken)) {
- satelliteAllowed = mCachedAccessRestrictionMap.get(locationToken);
+ mNewRegionalConfigId = mCachedAccessRestrictionMap.get(locationToken);
+ satelliteAllowed = (mNewRegionalConfigId != null);
+ plogd("mNewRegionalConfigId is " + mNewRegionalConfigId);
} else {
if (!initSatelliteOnDeviceAccessController()) {
ploge("Failed to init SatelliteOnDeviceAccessController");
@@ -1718,16 +1802,20 @@
if (mFeatureFlags.carrierRoamingNbIotNtn()) {
synchronized (mLock) {
- mRegionalConfigId = mSatelliteOnDeviceAccessController
+ mNewRegionalConfigId = mSatelliteOnDeviceAccessController
.getRegionalConfigIdForLocation(locationToken);
- plogd("mRegionalConfigId is " + mRegionalConfigId);
- satelliteAllowed = (mRegionalConfigId != null);
+ plogd("mNewRegionalConfigId is " + mNewRegionalConfigId);
+ satelliteAllowed = (mNewRegionalConfigId != null);
}
} else {
+ plogd("checkSatelliteAccessRestrictionForLocation: "
+ + "carrierRoamingNbIotNtn is disabled");
satelliteAllowed = mSatelliteOnDeviceAccessController
.isSatCommunicationAllowedAtLocation(locationToken);
+ mNewRegionalConfigId =
+ satelliteAllowed ? UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID : null;
}
- updateCachedAccessRestrictionMap(locationToken, satelliteAllowed);
+ updateCachedAccessRestrictionMap(locationToken, mNewRegionalConfigId);
}
mAccessControllerMetricsStats.setOnDeviceLookupTime(mOnDeviceLookupStartTimeMillis);
Bundle bundle = new Bundle();
@@ -1756,11 +1844,23 @@
}
}
+ private void updateRegionalConfigId() {
+ synchronized (mLock) {
+ plogd("mNewRegionalConfigId: updatedValue = " + mNewRegionalConfigId
+ + " | mRegionalConfigId: beforeValue = " + mRegionalConfigId);
+ if (!Objects.equals(mRegionalConfigId, mNewRegionalConfigId)) {
+ mRegionalConfigId = mNewRegionalConfigId;
+ notifyRegionalSatelliteConfigurationChanged(
+ mSatelliteAccessConfigMap.get(mRegionalConfigId));
+ }
+ }
+ }
+
private void updateCachedAccessRestrictionMap(
@NonNull SatelliteOnDeviceAccessController.LocationToken locationToken,
- boolean satelliteAllowed) {
+ Integer regionalConfigId) {
synchronized (mLock) {
- mCachedAccessRestrictionMap.put(locationToken, satelliteAllowed);
+ mCachedAccessRestrictionMap.put(locationToken, regionalConfigId);
}
}
@@ -2199,6 +2299,14 @@
logd("registerForCommunicationAllowedStateChanged: "
+ "mCurrentSatelliteAllowedState " + mCurrentSatelliteAllowedState);
}
+ synchronized (mLock) {
+ SatelliteAccessConfiguration satelliteAccessConfig =
+ mSatelliteAccessConfigMap.get(mRegionalConfigId);
+ callback.onSatelliteAccessConfigurationChanged(satelliteAccessConfig);
+ logd("registerForCommunicationAllowedStateChanged: satelliteAccessConfig: "
+ + satelliteAccessConfig + " of mRegionalConfigId: "
+ + mRegionalConfigId);
+ }
} catch (RemoteException ex) {
ploge("registerForCommunicationAllowedStateChanged: RemoteException ex=" + ex);
}
@@ -2382,6 +2490,25 @@
});
}
+ protected void notifyRegionalSatelliteConfigurationChanged(
+ @Nullable SatelliteAccessConfiguration satelliteAccessConfig) {
+ plogd("notifyRegionalSatelliteConfigurationChanged : satelliteAccessConfig is "
+ + satelliteAccessConfig);
+
+ List<ISatelliteCommunicationAllowedStateCallback> deadCallersList = new ArrayList<>();
+ mSatelliteCommunicationAllowedStateChangedListeners.values().forEach(listener -> {
+ try {
+ listener.onSatelliteAccessConfigurationChanged(satelliteAccessConfig);
+ } catch (RemoteException e) {
+ plogd("handleEventNtnSignalStrengthChanged RemoteException: " + e);
+ deadCallersList.add(listener);
+ }
+ });
+ deadCallersList.forEach(listener -> {
+ mSatelliteCommunicationAllowedStateChangedListeners.remove(listener.asBinder());
+ });
+ }
+
private void reportMetrics(int resultCode, boolean allowed) {
if (resultCode == SATELLITE_RESULT_SUCCESS) {
mControllerMetricsStats.reportAllowedSatelliteAccessCount(allowed);