Add callback/listener for satellite communication allowed state changed
Bug: 335760795
Test: atest android.telephony.satellite.cts.SatelliteManagerTestOnMockService
Test: Manually verified if the callback is invoked well when the allowed state is changed in skylo demo mode.
Change-Id: Ia36c8bd1452b2a95dabd5dbba9f364eec057b972
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 4c8c836..f410fad 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -156,6 +156,7 @@
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.satellite.INtnSignalStrengthCallback;
import android.telephony.satellite.ISatelliteCapabilitiesCallback;
+import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.ISatelliteModemStateCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
@@ -14082,4 +14083,42 @@
methodName + " is unsupported without " + telephonyFeature);
}
}
+
+ /**
+ * Registers for the satellite communication allowed state changed.
+ *
+ * @param subId The subId of the subscription to register for the satellite communication
+ * allowed state changed.
+ * @param callback The callback to handle the satellite communication allowed
+ * state changed event.
+ *
+ * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ @SatelliteManager.SatelliteResult public int registerForCommunicationAllowedStateChanged(
+ int subId, @NonNull ISatelliteCommunicationAllowedStateCallback callback) {
+ enforceSatelliteCommunicationPermission("registerForCommunicationAllowedStateChanged");
+ return mSatelliteAccessController.registerForCommunicationAllowedStateChanged(
+ subId, callback);
+ }
+
+ /**
+ * Unregisters for the satellite communication allowed state changed.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param subId The subId of the subscription to unregister for the satellite communication
+ * allowed state changed.
+ * @param callback The callback that was passed to
+ * {@link #registerForCommunicationAllowedStateChanged(int,
+ * ISatelliteCommunicationAllowedStateCallback)}. *
+ * @throws SecurityException if the caller doesn't have the required permission.
+ */
+ @Override
+ public void unregisterForCommunicationAllowedStateChanged(
+ int subId, @NonNull ISatelliteCommunicationAllowedStateCallback callback) {
+ enforceSatelliteCommunicationPermission("unregisterForCommunicationAllowedStateChanged");
+ mSatelliteAccessController.unregisterForCommunicationAllowedStateChanged(subId, callback);
+ }
}
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index 105dbd5..ea72acd 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -38,8 +38,10 @@
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -47,6 +49,7 @@
import android.telecom.TelecomManager;
import android.telephony.AnomalyReporter;
import android.telephony.Rlog;
+import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
import android.telephony.satellite.SatelliteManager;
import android.text.TextUtils;
import android.util.Pair;
@@ -79,6 +82,7 @@
import java.util.Map;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -158,12 +162,12 @@
@NonNull
private final Map<SatelliteOnDeviceAccessController.LocationToken, Boolean>
mCachedAccessRestrictionMap = new LinkedHashMap<>() {
- @Override
- protected boolean removeEldestEntry(
- Entry<SatelliteOnDeviceAccessController.LocationToken, Boolean> eldest) {
- return size() > MAX_CACHE_SIZE;
- }
- };
+ @Override
+ protected boolean removeEldestEntry(
+ Entry<SatelliteOnDeviceAccessController.LocationToken, Boolean> eldest) {
+ return size() > MAX_CACHE_SIZE;
+ }
+ };
@GuardedBy("mLock")
@Nullable
CancellationSignal mLocationRequestCancellationSignal = null;
@@ -188,6 +192,16 @@
private SharedPreferences mSharedPreferences;
/**
+ * Map key: binder of the callback, value: callback to receive the satellite communication
+ * allowed state changed events.
+ */
+ private final ConcurrentHashMap<IBinder, ISatelliteCommunicationAllowedStateCallback>
+ mSatelliteCommunicationAllowedStateChangedListeners = new ConcurrentHashMap<>();
+ private final Object mSatelliteCommunicationAllowStateLock = new Object();
+ @GuardedBy("mSatelliteCommunicationAllowStateLock")
+ private boolean mCurrentSatelliteAllowedState = false;
+
+ /**
* Create a SatelliteAccessController instance.
*
* @param context The context associated with the
@@ -231,6 +245,18 @@
initSatelliteOnDeviceAccessController();
}
+ private void updateCurrentSatelliteAllowedState(boolean isAllowed) {
+ logd("updateCurrentSatelliteAllowedState");
+ synchronized (mSatelliteCommunicationAllowStateLock) {
+ if (isAllowed != mCurrentSatelliteAllowedState) {
+ logd("updatedValue = " + isAllowed + " | mCurrentSatelliteAllowedState = "
+ + mCurrentSatelliteAllowedState);
+ mCurrentSatelliteAllowedState = isAllowed;
+ notifySatelliteCommunicationAllowedStateChanged(isAllowed);
+ }
+ }
+ }
+
/** @return the singleton instance of {@link SatelliteAccessController} */
public static synchronized SatelliteAccessController getOrCreateInstance(
@NonNull Context context, @NonNull FeatureFlags featureFlags) {
@@ -695,21 +721,23 @@
Bundle bundle = new Bundle();
bundle.putBoolean(SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED,
false);
- sendSatelliteAllowResultToReceivers(resultCode, bundle);
+ sendSatelliteAllowResultToReceivers(resultCode, bundle, false);
} else {
checkSatelliteAccessRestrictionForCurrentLocation();
}
} else {
loge("KEY_SATELLITE_SUPPORTED does not exist.");
- sendSatelliteAllowResultToReceivers(resultCode, resultData);
+ sendSatelliteAllowResultToReceivers(resultCode, resultData, false);
}
} else {
- sendSatelliteAllowResultToReceivers(resultCode, resultData);
+ sendSatelliteAllowResultToReceivers(resultCode, resultData, false);
}
}
}
- private void sendSatelliteAllowResultToReceivers(int resultCode, Bundle resultData) {
+ private void sendSatelliteAllowResultToReceivers(int resultCode, Bundle resultData,
+ boolean allowed) {
+ updateCurrentSatelliteAllowedState(allowed);
synchronized (mLock) {
for (ResultReceiver resultReceiver : mSatelliteAllowResultReceivers) {
resultReceiver.send(resultCode, resultData);
@@ -728,10 +756,10 @@
logd("Use current network country codes=" + String.join(", ",
networkCountryIsoList));
+ boolean allowed = isSatelliteAccessAllowedForLocation(networkCountryIsoList);
Bundle bundle = new Bundle();
- bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED,
- isSatelliteAccessAllowedForLocation(networkCountryIsoList));
- sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle);
+ bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, allowed);
+ sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle, allowed);
} else {
if (shouldUseOnDeviceAccessController()) {
// This will be an asynchronous check when it needs to wait for the current
@@ -768,10 +796,10 @@
}
logd("Use cached country codes=" + String.join(", ", countryCodeList));
+ boolean allowed = isSatelliteAccessAllowedForLocation(countryCodeList);
Bundle bundle = new Bundle();
- bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED,
- isSatelliteAccessAllowedForLocation(countryCodeList));
- sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle);
+ bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, allowed);
+ sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle, allowed);
}
/**
@@ -849,7 +877,8 @@
}
Bundle bundle = new Bundle();
bundle.putBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED, satelliteAllowed);
- sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle);
+ sendSatelliteAllowResultToReceivers(SATELLITE_RESULT_SUCCESS, bundle,
+ satelliteAllowed);
} catch (Exception ex) {
loge("checkSatelliteAccessRestrictionForLocation: ex=" + ex);
reportAnomaly(UUID_ON_DEVICE_LOOKUP_EXCEPTION,
@@ -1187,6 +1216,66 @@
msg.sendToTarget();
}
+ /**
+ * Registers for the satellite communication allowed state changed.
+ *
+ * @param subId The subId of the subscription to register for the satellite communication
+ * allowed state changed.
+ * @param callback The callback to handle the satellite communication allowed state changed
+ * event.
+ * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
+ */
+ @SatelliteManager.SatelliteResult
+ public int registerForCommunicationAllowedStateChanged(int subId,
+ @NonNull ISatelliteCommunicationAllowedStateCallback callback) {
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ logd("registerForCommunicationAllowedStateChanged: oemEnabledSatelliteFlag is "
+ + "disabled");
+ return SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+ }
+
+ mSatelliteCommunicationAllowedStateChangedListeners.put(callback.asBinder(), callback);
+ return SATELLITE_RESULT_SUCCESS;
+ }
+
+ /**
+ * Unregisters for the satellite communication allowed state changed.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param subId The subId of the subscription to unregister for the satellite communication
+ * allowed state changed.
+ * @param callback The callback that was passed to
+ * {@link #registerForCommunicationAllowedStateChanged(int,
+ * ISatelliteCommunicationAllowedStateCallback)}.
+ */
+ public void unregisterForCommunicationAllowedStateChanged(
+ int subId, @NonNull ISatelliteCommunicationAllowedStateCallback callback) {
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ logd("unregisterForCommunicationAllowedStateChanged: "
+ + "oemEnabledSatelliteFlag is disabled");
+ return;
+ }
+
+ mSatelliteCommunicationAllowedStateChangedListeners.remove(callback.asBinder());
+ }
+
+ private void notifySatelliteCommunicationAllowedStateChanged(boolean allowState) {
+ logd("notifySatelliteCommunicationAllowedStateChanged: allowState=" + allowState);
+
+ List<ISatelliteCommunicationAllowedStateCallback> deadCallersList = new ArrayList<>();
+ mSatelliteCommunicationAllowedStateChangedListeners.values().forEach(listener -> {
+ try {
+ listener.onSatelliteCommunicationAllowedStateChanged(allowState);
+ } catch (RemoteException e) {
+ logd("handleEventNtnSignalStrengthChanged RemoteException: " + e);
+ deadCallersList.add(listener);
+ }
+ });
+ deadCallersList.forEach(listener -> {
+ mSatelliteCommunicationAllowedStateChangedListeners.remove(listener.asBinder());
+ });
+ }
+
private static void logd(@NonNull String log) {
Rlog.d(TAG, log);
}