Add callback into vendor interface to receive modem state change event
Added a callback into vendor interface to receive the satellite supported state changed event.
Bug: 327652782
Test: SatelliteControllerTest, cts/SatelliteManagerTest, cts/SatelliteManagerTestOnMockService
manual basic call/sms/mms test includes regression test cases
Change-Id: Ibd9853f82e524fdeae53c6bd919476982607e3bc
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 370d769..d4dcb2d 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -88,6 +88,7 @@
import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.ISatelliteModemStateCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.telephony.satellite.ISatelliteSupportedStateCallback;
import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteCapabilities;
@@ -196,6 +197,7 @@
private static final int EVENT_SATELLITE_CAPABILITIES_CHANGED = 38;
private static final int EVENT_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMED_OUT = 39;
private static final int EVENT_SATELLITE_CONFIG_DATA_UPDATED = 40;
+ private static final int EVENT_SATELLITE_SUPPORTED_STATE_CHANGED = 41;
@NonNull private static SatelliteController sInstance;
@NonNull private final Context mContext;
@@ -251,6 +253,8 @@
new AtomicBoolean(false);
private final AtomicBoolean mIsModemEnabledReportingNtnSignalStrength =
new AtomicBoolean(false);
+ private final AtomicBoolean mRegisteredForSatelliteSupportedStateChanged =
+ new AtomicBoolean(false);
/**
* Map key: subId, value: callback to get error code of the provision request.
*/
@@ -274,6 +278,11 @@
*/
private final ConcurrentHashMap<IBinder, ISatelliteCapabilitiesCallback>
mSatelliteCapabilitiesChangedListeners = new ConcurrentHashMap<>();
+ /**
+ * Map key: binder of the callback, value: callback to receive supported state changed events.
+ */
+ private final ConcurrentHashMap<IBinder, ISatelliteSupportedStateCallback>
+ mSatelliteSupportedStateChangedListeners = new ConcurrentHashMap<>();
private final Object mIsSatelliteSupportedLock = new Object();
@GuardedBy("mIsSatelliteSupportedLock")
private Boolean mIsSatelliteSupported = null;
@@ -1312,6 +1321,16 @@
break;
}
+ case EVENT_SATELLITE_SUPPORTED_STATE_CHANGED: {
+ ar = (AsyncResult) msg.obj;
+ if (ar.result == null) {
+ loge("EVENT_SATELLITE_SUPPORTED_STATE_CHANGED: result is null");
+ } else {
+ handleEventSatelliteSupportedStateChanged((boolean) ar.result);
+ }
+ break;
+ }
+
case EVENT_SATELLITE_CONFIG_DATA_UPDATED: {
handleEventConfigDataUpdated();
mSatelliteConfigUpdateChangedRegistrants.notifyRegistrants();
@@ -2162,6 +2181,43 @@
}
/**
+ * Registers for the satellite supported state changed.
+ *
+ * @param subId The subId of the subscription to register for supported state changed.
+ * @param callback The callback to handle the satellite supported state changed event.
+ *
+ * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
+ */
+ @SatelliteManager.SatelliteResult public int registerForSatelliteSupportedStateChanged(
+ int subId, @NonNull ISatelliteSupportedStateCallback callback) {
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ logd("registerForSatelliteSupportedStateChanged: oemEnabledSatelliteFlag is disabled");
+ return SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+ }
+
+ mSatelliteSupportedStateChangedListeners.put(callback.asBinder(), callback);
+ return SATELLITE_RESULT_SUCCESS;
+ }
+
+ /**
+ * Unregisters for the satellite supported state changed.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param subId The subId of the subscription to unregister for supported state changed.
+ * @param callback The callback that was passed to
+ * {@link #registerForSatelliteSupportedStateChanged(int, ISatelliteSupportedStateCallback)}.
+ */
+ public void unregisterForSatelliteSupportedStateChanged(
+ int subId, @NonNull ISatelliteSupportedStateCallback callback) {
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ logd("unregisterForSatelliteSupportedStateChanged: "
+ + "oemEnabledSatelliteFlag is disabled");
+ return;
+ }
+ mSatelliteSupportedStateChangedListeners.remove(callback.asBinder());
+ }
+
+ /**
* This API can be used by only CTS to update satellite vendor service package name.
*
* @param servicePackageName The package name of the satellite vendor service.
@@ -2943,6 +2999,7 @@
registerForSatelliteModemStateChanged();
registerForNtnSignalStrengthChanged();
registerForCapabilitiesChanged();
+ registerForSatelliteSupportedStateChanged();
requestIsSatelliteProvisioned(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
new ResultReceiver(this) {
@@ -3046,6 +3103,16 @@
}
}
+ private void registerForSatelliteSupportedStateChanged() {
+ if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+ if (!mRegisteredForSatelliteSupportedStateChanged.get()) {
+ mSatelliteModemInterface.registerForSatelliteSupportedStateChanged(
+ this, EVENT_SATELLITE_SUPPORTED_STATE_CHANGED, null);
+ mRegisteredForSatelliteSupportedStateChanged.set(true);
+ }
+ }
+ }
+
private void handleEventSatelliteProvisionStateChanged(boolean provisioned) {
logd("handleSatelliteProvisionStateChangedEvent: provisioned=" + provisioned);
@@ -3154,6 +3221,53 @@
});
}
+ private void handleEventSatelliteSupportedStateChanged(boolean supported) {
+ logd("handleSatelliteSupportedStateChangedEvent: supported=" + supported);
+
+ synchronized (mIsSatelliteSupportedLock) {
+ if (mIsSatelliteSupported != null && mIsSatelliteSupported == supported) {
+ if (DBG) {
+ logd("current satellite support state and new supported state are matched,"
+ + " ignore update.");
+ }
+ return;
+ }
+ /* In case satellite has been reported as not support from modem, but satellite is
+ enabled, request disable satellite. */
+ synchronized (mIsSatelliteEnabledLock) {
+ if (!supported && mIsSatelliteEnabled != null && mIsSatelliteEnabled) {
+ logd("Invoke requestSatelliteEnabled(), supported=false, "
+ + "mIsSatelliteEnabled=true");
+ requestSatelliteEnabled(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ false /* enableSatellite */, false /* enableDemoMode */,
+ new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ logd("handleSatelliteSupportedStateChangedEvent: request "
+ + "satellite disable, result="
+ + result);
+ }
+ });
+
+ }
+ }
+ mIsSatelliteSupported = supported;
+ }
+
+ List<ISatelliteSupportedStateCallback> deadCallersList = new ArrayList<>();
+ mSatelliteSupportedStateChangedListeners.values().forEach(listener -> {
+ try {
+ listener.onSatelliteSupportedStateChanged(supported);
+ } catch (RemoteException e) {
+ logd("handleSatelliteSupportedStateChangedEvent RemoteException: " + e);
+ deadCallersList.add(listener);
+ }
+ });
+ deadCallersList.forEach(listener -> {
+ mSatelliteSupportedStateChangedListeners.remove(listener.asBinder());
+ });
+ }
+
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
protected void setSettingsKeyForSatelliteMode(int val) {
logd("setSettingsKeyForSatelliteMode val: " + val);
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
index e51042f..7432d91 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
@@ -93,6 +93,8 @@
new RegistrantList();
@NonNull private final RegistrantList mSatelliteCapabilitiesChangedRegistrants =
new RegistrantList();
+ @NonNull private final RegistrantList mSatelliteSupportedStateChangedRegistrants =
+ new RegistrantList();
@NonNull private final ISatelliteListener mListener = new ISatelliteListener.Stub() {
@Override
@@ -158,6 +160,11 @@
mSatelliteCapabilitiesChangedRegistrants.notifyResult(
SatelliteServiceUtils.fromSatelliteCapabilities(satelliteCapabilities));
}
+
+ @Override
+ public void onSatelliteSupportedStateChanged(boolean supported) {
+ mSatelliteSupportedStateChangedRegistrants.notifyResult(supported);
+ }
};
/**
@@ -505,6 +512,27 @@
}
/**
+ * Registers for the satellite supported state changed.
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ public void registerForSatelliteSupportedStateChanged(
+ @NonNull Handler h, int what, @Nullable Object obj) {
+ mSatelliteSupportedStateChangedRegistrants.add(h, what, obj);
+ }
+
+ /**
+ * Unregisters for the satellite supported state changed.
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ public void unregisterForSatelliteSupportedStateChanged(@NonNull Handler h) {
+ mSatelliteSupportedStateChangedRegistrants.remove(h);
+ }
+
+ /**
* Request to enable or disable the satellite service listening mode.
* Listening mode allows the satellite service to listen for incoming pages.
*
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
index c48095c..b6e4b6b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -106,6 +106,7 @@
import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.ISatelliteModemStateCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.telephony.satellite.ISatelliteSupportedStateCallback;
import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteCapabilities;
@@ -3285,6 +3286,123 @@
any(Message.class));
}
+ @Test
+ public void testRegisterForSatelliteSupportedStateChanged_WithFeatureFlagEnabled() {
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+
+ Semaphore semaphore = new Semaphore(0);
+ final boolean[] isSupported = new boolean[1];
+ ISatelliteSupportedStateCallback callback =
+ new ISatelliteSupportedStateCallback.Stub() {
+ @Override
+ public void onSatelliteSupportedStateChanged(boolean supported) {
+ logd("onSatelliteSupportedStateChanged: supported=" + supported);
+ isSupported[0] = supported;
+ try {
+ semaphore.release();
+ } catch (Exception ex) {
+ loge("onSatelliteSupportedStateChanged: Got exception in releasing "
+ + "semaphore, ex=" + ex);
+ }
+ }
+ };
+
+ resetSatelliteControllerUT();
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ int errorCode = mSatelliteControllerUT.registerForSatelliteSupportedStateChanged(
+ SUB_ID, callback);
+ assertEquals(SATELLITE_RESULT_SUCCESS, errorCode);
+
+ sendSatelliteSupportedStateChangedEvent(true, null);
+ processAllMessages();
+ // Verify redundant report is ignored
+ assertFalse(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSupportedStateChanged"));
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+
+ // Verify updated state is reported
+ sendSatelliteSupportedStateChangedEvent(false, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSupportedStateChanged"));
+ assertEquals(false, isSupported[0]);
+ verifySatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
+
+ // Verify redundant report is ignored
+ sendSatelliteSupportedStateChangedEvent(false, null);
+ processAllMessages();
+ assertFalse(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSupportedStateChanged"));
+ verifySatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
+
+ // Verify updated state is reported
+ sendSatelliteSupportedStateChangedEvent(true, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSupportedStateChanged"));
+ assertEquals(true, isSupported[0]);
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+
+ // Successfully enable satellite
+ sendProvisionedStateChangedEvent(true, null);
+ processAllMessages();
+ verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ mIIntegerConsumerResults.clear();
+ setUpResponseForRequestSatelliteEnabled(true, false, SATELLITE_RESULT_SUCCESS);
+ mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, mIIntegerConsumer);
+ processAllMessages();
+ assertTrue(waitForIIntegerConsumerResult(1));
+ assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
+ verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS);
+
+ // Send satellite is not supported state from modem to disable satellite
+ setUpResponseForRequestSatelliteEnabled(false, false, SATELLITE_RESULT_SUCCESS);
+ sendSatelliteSupportedStateChangedEvent(false, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSupportedStateChanged"));
+ assertEquals(false, isSupported[0]);
+
+ // It is needed to set satellite as support to check whether satellite is enabled or not
+ sendSatelliteSupportedStateChangedEvent(true, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSupportedStateChanged"));
+ assertEquals(true, isSupported[0]);
+ // Verify satellite was disabled
+ verifySatelliteEnabled(false, SATELLITE_RESULT_SUCCESS);
+
+ mSatelliteControllerUT.unregisterForSatelliteSupportedStateChanged(SUB_ID, callback);
+ sendSatelliteSupportedStateChangedEvent(true, null);
+ processAllMessages();
+ assertFalse(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSupportedStateChanged"));
+ }
+
+ @Test
+ public void testRegisterForSatelliteSupportedStateChanged_WithFeatureFlagDisabled() {
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(false);
+
+ Semaphore semaphore = new Semaphore(0);
+ ISatelliteSupportedStateCallback callback =
+ new ISatelliteSupportedStateCallback.Stub() {
+ @Override
+ public void onSatelliteSupportedStateChanged(boolean supported) {
+ logd("onSatelliteSupportedStateChanged: supported=" + supported);
+ try {
+ semaphore.release();
+ } catch (Exception ex) {
+ loge("onSatelliteSupportedStateChanged: Got exception in releasing "
+ + "semaphore, ex=" + ex);
+ }
+ }
+ };
+ int errorCode = mSatelliteControllerUT.registerForSatelliteSupportedStateChanged(
+ SUB_ID, callback);
+ assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, errorCode);
+ }
+
private void resetSatelliteControllerUTEnabledState() {
logd("resetSatelliteControllerUTEnabledState");
setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
@@ -3802,6 +3920,13 @@
msg.sendToTarget();
}
+ private void sendSatelliteSupportedStateChangedEvent(boolean supported, Throwable exception) {
+ Message msg = mSatelliteControllerUT.obtainMessage(
+ 41 /* EVENT_SATELLITE_SUPPORTED_STATE_CHANGED */);
+ msg.obj = new AsyncResult(null, supported, exception);
+ msg.sendToTarget();
+ }
+
private void setRadioPower(boolean on) {
mSimulatedCommands.setRadioPower(on, false, false, null);
}