Use the new HAL API updateSystemSelectionChannels to pass the bands/frequency to vendor service.
Bug: 371438496
Flag: com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn
Test: atest SatelliteAccessControllerTest SatelliteControllerTest
Test: manually run e2e system test for checking functionality and
regression
Change-Id: I99404ee6adb464979f0f1d701a952134f6c83363
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index a47691e..251ba65 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -25,6 +25,7 @@
import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED;
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;
@@ -80,11 +81,13 @@
import android.telephony.Rlog;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.satellite.EarfcnRange;
import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
import android.telephony.satellite.ISatelliteDisallowedReasonsCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteSupportedStateCallback;
import android.telephony.satellite.SatelliteAccessConfiguration;
+import android.telephony.satellite.SatelliteInfo;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.telephony.satellite.SystemSelectionSpecifier;
@@ -133,6 +136,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
+import java.util.stream.IntStream;
/**
* This module is responsible for making sure that satellite communication can be used by devices
@@ -321,7 +325,8 @@
/** Key: Config ID; Value: SatelliteAccessConfiguration */
@GuardedBy("mLock")
@Nullable
- private Map<Integer, SatelliteAccessConfiguration> mSatelliteAccessConfigMap;
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected Map<Integer, SatelliteAccessConfiguration> mSatelliteAccessConfigMap;
/** These are used for CTS test */
private Path mCtsSatS2FilePath = null;
@@ -358,6 +363,7 @@
protected static final int
DEFAULT_MAX_RETRY_COUNT_FOR_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION = 3;
protected static final int DEFAULT_THROTTLE_INTERVAL_FOR_LOCATION_QUERY_MINUTES = 10;
+ private static final int MAX_EARFCN_ARRAY_LENGTH = 32;
private long mRetryIntervalToEvaluateUserInSatelliteAllowedRegion = 0;
private int mMaxRetryCountForValidatingPossibleChangeInAllowedRegion = 0;
@@ -808,7 +814,7 @@
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);
+ result.send(SATELLITE_RESULT_ACCESS_BARRED, null);
return;
}
}
@@ -2224,41 +2230,66 @@
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);
+ final Integer[] regionalConfigId = new Integer[1];
+ regionalConfigId[0] = getSelectedRegionalConfigId();
+ if (regionalConfigId[0] != null
+ && regionalConfigId[0] == UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID) {
+ // The geofence file with old format return UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID
+ // for an S2 cell present in the file.
+ // For backward compatibility, we will use DEFAULT_REGIONAL_SATELLITE_CONFIG_ID
+ // for such cases.
+ regionalConfigId[0] = DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
}
+ if (!SatelliteAccessConfigurationParser.isRegionalConfigIdValid(regionalConfigId[0])) {
+ plogd("handleCmdUpdateSystemSelectionChannels: mRegionalConfigId is not valid, "
+ + "mRegionalConfig=" + getSelectedRegionalConfigId());
+ sendUpdateSystemSelectionChannelsResult(
+ SATELLITE_RESULT_ACCESS_BARRED, null);
+ return;
+ }
+
+ SatelliteAccessConfiguration satelliteAccessConfiguration;
+ synchronized (mLock) {
+ satelliteAccessConfiguration = Optional.ofNullable(mSatelliteAccessConfigMap)
+ .map(map -> map.get(regionalConfigId[0]))
+ .orElse(null);
+ }
+ if (satelliteAccessConfiguration == null) {
+ plogd("handleCmdUpdateSystemSelectionChannels: satelliteAccessConfiguration "
+ + "is not valid");
+ sendUpdateSystemSelectionChannelsResult(
+ SATELLITE_RESULT_ACCESS_BARRED, null);
+ return;
+ }
+
+ List<SatelliteInfo> satelliteInfos =
+ satelliteAccessConfiguration.getSatelliteInfos();
+ List<Integer> bandList = new ArrayList<>();
+ List<Integer> earfcnList = new ArrayList<>();
+ for (SatelliteInfo satelliteInfo : satelliteInfos) {
+ bandList.addAll(satelliteInfo.getBands());
+ List<EarfcnRange> earfcnRangeList = satelliteInfo.getEarfcnRanges();
+ earfcnRangeList.stream().flatMapToInt(
+ earfcnRange -> IntStream.of(earfcnRange.getStartEarfcn(),
+ earfcnRange.getEndEarfcn())).boxed().forEach(earfcnList::add);
+ }
+
+ IntArray bands = new IntArray(bandList.size());
+ bands.addAll(bandList.stream().mapToInt(Integer::intValue).toArray());
+ IntArray earfcns = new IntArray(
+ Math.min(earfcnList.size(), MAX_EARFCN_ARRAY_LENGTH));
+ for (int i = 0; i < Math.min(earfcnList.size(), MAX_EARFCN_ARRAY_LENGTH); i++) {
+ earfcns.add(earfcnList.get(i));
+ }
+ IntArray tagIds = new IntArray(satelliteAccessConfiguration.getTagIds().size());
+ tagIds.addAll(satelliteAccessConfiguration.getTagIds().stream().mapToInt(
+ Integer::intValue).toArray());
+
+ List<SystemSelectionSpecifier> selectionSpecifiers = new ArrayList<>();
+ selectionSpecifiers.add(new SystemSelectionSpecifier(mccmnc, bands, earfcns,
+ satelliteInfos.toArray(new SatelliteInfo[0]), tagIds));
+ mSatelliteController.updateSystemSelectionChannels(selectionSpecifiers,
+ mInternalUpdateSystemSelectionChannelsResultReceiver);
}
}
@@ -2909,6 +2940,13 @@
evaluatePossibleChangeInDefaultSmsApp(context);
}
+ @Nullable
+ private Integer getSelectedRegionalConfigId() {
+ synchronized (mLock) {
+ return mRegionalConfigId;
+ }
+ }
+
private void plogv(@NonNull String log) {
Rlog.v(TAG, log);
if (mPersistentLogger != null) {
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
index c8013d6..a47095d 100644
--- a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
+++ b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
@@ -22,6 +22,7 @@
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;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ERROR;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_DISABLED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_LOCATION_NOT_AVAILABLE;
@@ -44,6 +45,7 @@
import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.GOOGLE_US_SAN_SAT_S2_FILE_NAME;
import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -54,6 +56,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -98,10 +101,13 @@
import android.telecom.TelecomManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.satellite.EarfcnRange;
import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
import android.telephony.satellite.SatelliteAccessConfiguration;
import android.telephony.satellite.SatelliteInfo;
import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.SatellitePosition;
+import android.telephony.satellite.SystemSelectionSpecifier;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Log;
@@ -136,11 +142,14 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
/** Unit test for {@link SatelliteAccessController} */
@RunWith(AndroidTestingRunner.class)
@@ -288,6 +297,22 @@
}
};
+ private int mQueriedSystemSelectionChannelUpdatedResultCode = SATELLITE_RESULT_SUCCESS;
+ private Semaphore mSystemSelectionChannelUpdatedSemaphore = new Semaphore(0);
+ private ResultReceiver mSystemSelectionChannelUpdatedReceiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ mQueriedSystemSelectionChannelUpdatedResultCode = resultCode;
+ try {
+ mSystemSelectionChannelUpdatedSemaphore.release();
+ } catch (Exception ex) {
+ fail("mSystemSelectionChannelUpdatedReceiver: Got exception in releasing "
+ + "semaphore, ex="
+ + ex);
+ }
+ }
+ };
+
@Before
public void setUp() throws Exception {
super.setUp();
@@ -1530,7 +1555,7 @@
// Captor and Verify if the mockReceiver and mocContext is registered well
verify(mMockContext, times(2))
.registerReceiver(mLocationBroadcastReceiverCaptor.capture(),
- mIntentFilterCaptor.capture());
+ mIntentFilterCaptor.capture());
// When the intent action is not MODE_CHANGED_ACTION,
// verify if the location manager never invoke isLocationEnabled()
@@ -1710,6 +1735,311 @@
any(Consumer.class));
}
+ @Test
+ public void testUpdateSystemSelectionChannels() {
+ // Set non-emergency case
+ when(mMockFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+ when(mMockFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
+
+ // Invoke when regional config ID is not set.
+ mSatelliteAccessControllerUT.setRegionalConfigId(null);
+ mSatelliteAccessControllerUT.updateSystemSelectionChannels(
+ mSystemSelectionChannelUpdatedReceiver);
+ mTestableLooper.processAllMessages();
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
+ mSystemSelectionChannelUpdatedSemaphore, 1));
+ assertEquals(SATELLITE_RESULT_ACCESS_BARRED,
+ mQueriedSystemSelectionChannelUpdatedResultCode);
+
+ // Invoke when mSatelliteAccessConfigMap does not have data for given regional config ID
+ int satelliteRegionalConfigId = DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
+ mSatelliteAccessControllerUT.setRegionalConfigId(satelliteRegionalConfigId);
+ mSatelliteAccessControllerUT.resetSatelliteAccessConfigMap();
+ mSatelliteAccessControllerUT.updateSystemSelectionChannels(
+ mSystemSelectionChannelUpdatedReceiver);
+ mTestableLooper.processAllMessages();
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
+ mSystemSelectionChannelUpdatedSemaphore, 1));
+ assertEquals(SATELLITE_RESULT_ACCESS_BARRED,
+ mQueriedSystemSelectionChannelUpdatedResultCode);
+
+ // Invoke when mSatelliteAccessConfigMap does not have data and given data is old format.
+ satelliteRegionalConfigId = UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID;
+ mSatelliteAccessControllerUT.setRegionalConfigId(satelliteRegionalConfigId);
+ mSatelliteAccessControllerUT.resetSatelliteAccessConfigMap();
+ mSatelliteAccessControllerUT.updateSystemSelectionChannels(
+ mSystemSelectionChannelUpdatedReceiver);
+ mTestableLooper.processAllMessages();
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
+ mSystemSelectionChannelUpdatedSemaphore, 1));
+ assertEquals(SATELLITE_RESULT_ACCESS_BARRED,
+ mQueriedSystemSelectionChannelUpdatedResultCode);
+
+ satelliteRegionalConfigId = DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
+ // Return success when SatelliteController.updateSystemSelectionChannels was invoked
+ setupResponseForUpdateSystemSelectionChannels(SATELLITE_RESULT_SUCCESS);
+
+ // Invoke updateSystemSelectionChannels when there is corresponding satellite access config.
+ // Create satellite info 1
+ String seed1 = "test-seed-satellite1";
+ UUID uuid1 = UUID.nameUUIDFromBytes(seed1.getBytes());
+ SatellitePosition satellitePosition1 = new SatellitePosition(0, 35876);
+ int[] bands1 = {200, 201, 202};
+ EarfcnRange earfcnRange1 = new EarfcnRange(300, 301);
+ EarfcnRange earfcnRange2 = new EarfcnRange(310, 311);
+ List<EarfcnRange> earfcnRangeList1 = new ArrayList<>(
+ Arrays.asList(earfcnRange1, earfcnRange2));
+ SatelliteInfo satelliteInfo1 = new SatelliteInfo(uuid1, satellitePosition1, Arrays.stream(
+ bands1).boxed().collect(Collectors.toList()), earfcnRangeList1);
+ // Create satellite info 2
+ String seed2 = "test-seed-satellite2";
+ UUID uuid2 = UUID.nameUUIDFromBytes(seed2.getBytes());
+ SatellitePosition satellitePosition2 = new SatellitePosition(120, 35876);
+ int[] bands2 = {210, 211, 212};
+ EarfcnRange earfcnRange3 = new EarfcnRange(320, 321);
+ EarfcnRange earfcnRange4 = new EarfcnRange(330, 331);
+ List<EarfcnRange> earfcnRangeList2 = new ArrayList<>(
+ Arrays.asList(earfcnRange3, earfcnRange4));
+ SatelliteInfo satelliteInfo2 = new SatelliteInfo(uuid2, satellitePosition2, Arrays.stream(
+ bands2).boxed().collect(Collectors.toList()), earfcnRangeList2);
+ // Create satellite info 3
+ String seed3 = "test-seed-satellite3";
+ UUID uuid3 = UUID.nameUUIDFromBytes(seed3.getBytes());
+ SatellitePosition satellitePosition3 = new SatellitePosition(120, 35876);
+ int[] bands3 = {220, 221, 222};
+ EarfcnRange earfcnRange5 = new EarfcnRange(340, 341);
+ EarfcnRange earfcnRange6 = new EarfcnRange(350, 351);
+ List<EarfcnRange> earfcnRangeList3 = new ArrayList<>(
+ Arrays.asList(earfcnRange5, earfcnRange6));
+ SatelliteInfo satelliteInfo3 = new SatelliteInfo(uuid3, satellitePosition3, Arrays.stream(
+ bands3).boxed().collect(Collectors.toList()), earfcnRangeList3);
+
+ int[] tagIds = {1, 2, 3};
+ SatelliteAccessConfiguration satelliteAccessConfiguration =
+ new SatelliteAccessConfiguration(new ArrayList<>(
+ Arrays.asList(satelliteInfo1, satelliteInfo2, satelliteInfo3)),
+ Arrays.stream(tagIds).boxed().collect(Collectors.toList()));
+
+ // Add satellite access configuration to map
+ mSatelliteAccessControllerUT.setSatelliteAccessConfigMap(satelliteRegionalConfigId,
+ satelliteAccessConfiguration);
+
+ // Invoke updateSystemSelectionChannel
+ mSatelliteAccessControllerUT.updateSystemSelectionChannels(
+ mSystemSelectionChannelUpdatedReceiver);
+ mTestableLooper.processAllMessages();
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
+ mSystemSelectionChannelUpdatedSemaphore, 1));
+ assertEquals(SATELLITE_RESULT_SUCCESS,
+ mQueriedSystemSelectionChannelUpdatedResultCode);
+ ArgumentCaptor<List<SystemSelectionSpecifier>> systemSelectionSpecifierListCaptor =
+ ArgumentCaptor.forClass(List.class);
+ verify(mMockSatelliteController, times(1)).updateSystemSelectionChannels(
+ systemSelectionSpecifierListCaptor.capture(), any(ResultReceiver.class));
+ List<SystemSelectionSpecifier> capturedList = systemSelectionSpecifierListCaptor.getValue();
+ SystemSelectionSpecifier systemSelectionSpecifier = capturedList.getFirst();
+
+ // Verify the fields value of given systemSelectionSpecifier matched with expected.
+ int[] expectedBandsArray = IntStream.concat(
+ IntStream.concat(Arrays.stream(bands1), Arrays.stream(bands2)),
+ Arrays.stream(bands3)).toArray();
+ int[] actualBandsArray = IntStream.range(0, systemSelectionSpecifier.getBands().size()).map(
+ systemSelectionSpecifier.getBands()::get).toArray();
+ assertArrayEquals(expectedBandsArray, actualBandsArray);
+
+ int[] expectedEarfcnsArray = {300, 301, 310, 311, 320, 321, 330, 331, 340, 341, 350, 351};
+ int[] actualEarfcnsArray = IntStream.range(0,
+ systemSelectionSpecifier.getEarfcns().size()).map(
+ systemSelectionSpecifier.getEarfcns()::get).toArray();
+ assertArrayEquals(expectedEarfcnsArray, actualEarfcnsArray);
+
+ SatelliteInfo[] expectedSatelliteInfos = {satelliteInfo1, satelliteInfo2, satelliteInfo3};
+ assertArrayEquals(expectedSatelliteInfos, systemSelectionSpecifier.getSatelliteInfos());
+
+ int[] actualTagIdArray = IntStream.range(0,
+ systemSelectionSpecifier.getTagIds().size()).map(
+ systemSelectionSpecifier.getTagIds()::get).toArray();
+ assertArrayEquals(tagIds, actualTagIdArray);
+
+ // Verify backward compatibility when there is valid data for default regional config ID
+ satelliteRegionalConfigId = UNKNOWN_REGIONAL_SATELLITE_CONFIG_ID;
+ mSatelliteAccessControllerUT.setRegionalConfigId(satelliteRegionalConfigId);
+ mSatelliteAccessControllerUT.updateSystemSelectionChannels(
+ mSystemSelectionChannelUpdatedReceiver);
+ mTestableLooper.processAllMessages();
+
+ // updateSelectionChannelResult will be invoked with the data for default regional config ID
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
+ mSystemSelectionChannelUpdatedSemaphore, 1));
+ systemSelectionSpecifierListCaptor = ArgumentCaptor.forClass(List.class);
+ verify(mMockSatelliteController, times(2)).updateSystemSelectionChannels(
+ systemSelectionSpecifierListCaptor.capture(), any(ResultReceiver.class));
+ capturedList = systemSelectionSpecifierListCaptor.getValue();
+ systemSelectionSpecifier = capturedList.getFirst();
+
+ // Data will be same with default regional config ID
+
+ // Verify the fields value of given systemSelectionSpecifier matched with expected.
+ actualBandsArray = IntStream.range(0, systemSelectionSpecifier.getBands().size()).map(
+ systemSelectionSpecifier.getBands()::get).toArray();
+ assertArrayEquals(expectedBandsArray, actualBandsArray);
+
+ actualEarfcnsArray = IntStream.range(0,
+ systemSelectionSpecifier.getEarfcns().size()).map(
+ systemSelectionSpecifier.getEarfcns()::get).toArray();
+ assertArrayEquals(expectedEarfcnsArray, actualEarfcnsArray);
+
+ assertArrayEquals(expectedSatelliteInfos, systemSelectionSpecifier.getSatelliteInfos());
+
+ actualTagIdArray = IntStream.range(0,
+ systemSelectionSpecifier.getTagIds().size()).map(
+ systemSelectionSpecifier.getTagIds()::get).toArray();
+ assertArrayEquals(tagIds, actualTagIdArray);
+
+ mSatelliteAccessControllerUT.resetSatelliteAccessConfigMap();
+ }
+
+ @Test
+ public void testUpdateSystemSelectionChannels_HandleInvalidInput() {
+ // Set non-emergency case
+ when(mMockFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+ when(mMockFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ when(mMockCountryDetector.getCurrentNetworkCountryIso()).thenReturn(EMPTY_STRING_LIST);
+ int satelliteRegionalConfigId = DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
+ mSatelliteAccessControllerUT.setRegionalConfigId(satelliteRegionalConfigId);
+ // Set return success when SatelliteController.updateSystemSelectionChannels was invoked
+ setupResponseForUpdateSystemSelectionChannels(SATELLITE_RESULT_SUCCESS);
+
+ // Create satellite info in which satellite position is null.
+ String seed1 = "test-seed-satellite1";
+ UUID uuid1 = UUID.nameUUIDFromBytes(seed1.getBytes());
+ SatellitePosition satellitePosition1 = null;
+ List<Integer> bandList1 = new ArrayList<>(List.of(200, 201, 202));
+ EarfcnRange earfcnRange1 = new EarfcnRange(300, 301);
+ EarfcnRange earfcnRange2 = new EarfcnRange(310, 311);
+ List<EarfcnRange> earfcnRangeList1 = new ArrayList<>(
+ Arrays.asList(earfcnRange1, earfcnRange2));
+ SatelliteInfo satelliteInfo1 = new SatelliteInfo(uuid1, satellitePosition1, bandList1,
+ earfcnRangeList1);
+
+ // Create satellite info in which band list is empty
+ String seed2 = "test-seed-satellite2";
+ UUID uuid2 = UUID.nameUUIDFromBytes(seed2.getBytes());
+ SatellitePosition satellitePosition2 = new SatellitePosition(120, 35876);
+ List<Integer> bandList2 = new ArrayList<>();
+ EarfcnRange earfcnRange3 = new EarfcnRange(320, 321);
+ EarfcnRange earfcnRange4 = new EarfcnRange(330, 331);
+ List<EarfcnRange> earfcnRangeList2 = new ArrayList<>(
+ Arrays.asList(earfcnRange3, earfcnRange4));
+ SatelliteInfo satelliteInfo2 = new SatelliteInfo(uuid2, satellitePosition2, bandList2,
+ earfcnRangeList2);
+
+ // Create satellite info 3, every field is valid
+ String seed3 = "test-seed-satellite3";
+ UUID uuid3 = UUID.nameUUIDFromBytes(seed3.getBytes());
+ SatellitePosition satellitePosition3 = new SatellitePosition(120, 35876);
+ List<Integer> bandList3 = new ArrayList<>(List.of(220, 221, 222));
+ EarfcnRange earfcnRange5 = new EarfcnRange(340, 341);
+ EarfcnRange earfcnRange6 = new EarfcnRange(350, 351);
+ List<EarfcnRange> earfcnRangeList3 = new ArrayList<>(
+ Arrays.asList(earfcnRange5, earfcnRange6));
+ SatelliteInfo satelliteInfo3 = new SatelliteInfo(uuid3, satellitePosition3, bandList3,
+ earfcnRangeList3);
+ // Add empty tagId list
+ List<Integer> tagIdList = new ArrayList<>();
+
+ // Create satelliteAccessConfiguration with some of files of added Satellite info are empty.
+ SatelliteAccessConfiguration satelliteAccessConfiguration1 =
+ new SatelliteAccessConfiguration(new ArrayList<>(
+ Arrays.asList(satelliteInfo1, satelliteInfo2, satelliteInfo3)), tagIdList);
+
+ // Add satellite access configuration to map
+ mSatelliteAccessControllerUT.setSatelliteAccessConfigMap(satelliteRegionalConfigId,
+ satelliteAccessConfiguration1);
+
+ // Invoke updateSystemSelectionChannel
+ mSatelliteAccessControllerUT.updateSystemSelectionChannels(
+ mSystemSelectionChannelUpdatedReceiver);
+ mTestableLooper.processAllMessages();
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
+ mSystemSelectionChannelUpdatedSemaphore, 1));
+ assertEquals(SATELLITE_RESULT_SUCCESS,
+ mQueriedSystemSelectionChannelUpdatedResultCode);
+ ArgumentCaptor<List<SystemSelectionSpecifier>> systemSelectionSpecifierListCaptor =
+ ArgumentCaptor.forClass(List.class);
+ verify(mMockSatelliteController, times(1)).updateSystemSelectionChannels(
+ systemSelectionSpecifierListCaptor.capture(), any(ResultReceiver.class));
+ List<SystemSelectionSpecifier> capturedList = systemSelectionSpecifierListCaptor.getValue();
+ SystemSelectionSpecifier systemSelectionSpecifier = capturedList.getFirst();
+
+ // Verify the fields value of given systemSelectionSpecifier matched with expected.
+ List<Integer> expectedBandList = new ArrayList<>(bandList1);
+ expectedBandList.addAll(bandList2);
+ expectedBandList.addAll(bandList3);
+
+ List<Integer> actualBandList = IntStream.range(0,
+ systemSelectionSpecifier.getBands().size()).map(
+ systemSelectionSpecifier.getBands()::get).boxed().toList();
+ assertEquals(expectedBandList, actualBandList);
+
+ List<Integer> expectedEarfcnList = new ArrayList<>(
+ List.of(300, 301, 310, 311, 320, 321, 330, 331, 340, 341, 350, 351));
+ List<Integer> actualEarfcnList = IntStream.range(0,
+ systemSelectionSpecifier.getEarfcns().size()).map(
+ systemSelectionSpecifier.getEarfcns()::get).boxed().toList();
+ assertEquals(expectedEarfcnList, actualEarfcnList);
+
+ assertEquals(satelliteInfo1, systemSelectionSpecifier.getSatelliteInfos()[0]);
+ assertEquals(satelliteInfo2, systemSelectionSpecifier.getSatelliteInfos()[1]);
+ assertEquals(satelliteInfo3, systemSelectionSpecifier.getSatelliteInfos()[2]);
+
+ List<Integer> actualTagIdList = IntStream.range(0,
+ systemSelectionSpecifier.getTagIds().size()).map(
+ systemSelectionSpecifier.getTagIds()::get).boxed().toList();
+ assertEquals(tagIdList, actualTagIdList);
+
+ // Create satelliteAccessConfiguration with empty list of SatelliteInfo.
+ SatelliteAccessConfiguration satelliteAccessConfiguration2 =
+ new SatelliteAccessConfiguration(new ArrayList<>(), tagIdList);
+ mSatelliteAccessControllerUT.setSatelliteAccessConfigMap(
+ DEFAULT_REGIONAL_SATELLITE_CONFIG_ID, satelliteAccessConfiguration2);
+
+ // Invoke updateSystemSelectionChannel
+ mSatelliteAccessControllerUT.updateSystemSelectionChannels(
+ mSystemSelectionChannelUpdatedReceiver);
+ mTestableLooper.processAllMessages();
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(
+ mSystemSelectionChannelUpdatedSemaphore, 1));
+ assertEquals(SATELLITE_RESULT_SUCCESS,
+ mQueriedSystemSelectionChannelUpdatedResultCode);
+ systemSelectionSpecifierListCaptor = ArgumentCaptor.forClass(List.class);
+ verify(mMockSatelliteController, times(2)).updateSystemSelectionChannels(
+ systemSelectionSpecifierListCaptor.capture(), any(ResultReceiver.class));
+ capturedList = systemSelectionSpecifierListCaptor.getValue();
+ systemSelectionSpecifier = capturedList.getFirst();
+
+ // Verify the fields value of given systemSelectionSpecifier matched with expected.
+ assertEquals(0, systemSelectionSpecifier.getBands().size());
+ assertEquals(0, systemSelectionSpecifier.getEarfcns().size());
+
+ SatelliteInfo[] expectedSatelliteInfoArray = new SatelliteInfo[0];
+ assertArrayEquals(expectedSatelliteInfoArray, systemSelectionSpecifier.getSatelliteInfos());
+
+ actualTagIdList = IntStream.range(0,
+ systemSelectionSpecifier.getTagIds().size()).map(
+ systemSelectionSpecifier.getTagIds()::get).boxed().toList();
+ assertEquals(tagIdList, actualTagIdList);
+
+ mSatelliteAccessControllerUT.resetSatelliteAccessConfigMap();
+ }
+
private void sendSatelliteCommunicationAllowedEvent() {
Pair<Integer, ResultReceiver> requestPair =
new Pair<>(DEFAULT_SUBSCRIPTION_ID,
@@ -1721,7 +2051,6 @@
mTestableLooper.processAllMessages();
}
-
private void sendConfigUpdateChangedEvent(Context context) {
Message msg = mSatelliteAccessControllerUT.obtainMessage(EVENT_CONFIG_DATA_UPDATED);
msg.obj = new AsyncResult(context, SATELLITE_RESULT_SUCCESS, null);
@@ -1774,6 +2103,24 @@
return true;
}
+ private boolean waitForRequestUpdateSystemSelectionChannelResult(Semaphore semaphore,
+ int expectedNumberOfEvents) {
+ for (int i = 0; i < expectedNumberOfEvents; i++) {
+ try {
+ if (!semaphore.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ logd("Timeout to receive "
+ + "updateSystemSelectionChannel()"
+ + " callback");
+ return false;
+ }
+ } catch (Exception ex) {
+ logd("updateSystemSelectionChannel: Got exception=" + ex);
+ return false;
+ }
+ }
+ return true;
+ }
+
private void sendLocationRequestResult(Location location) {
mLocationRequestConsumerCaptor.getValue().accept(location);
mTestableLooper.processAllMessages();
@@ -1810,6 +2157,16 @@
}).when(mMockSatelliteController).requestIsSatelliteProvisioned(any(ResultReceiver.class));
}
+ private void setupResponseForUpdateSystemSelectionChannels(
+ @SatelliteManager.SatelliteResult int error) {
+ doAnswer(invocation -> {
+ ResultReceiver resultReceiver = invocation.getArgument(1);
+ resultReceiver.send(error, null);
+ return null;
+ }).when(mMockSatelliteController).updateSystemSelectionChannels(anyList(),
+ any(ResultReceiver.class));
+ }
+
@SafeVarargs
private static <E> List<E> listOf(E... values) {
return Arrays.asList(values);
@@ -1925,5 +2282,25 @@
mRegionalConfigId = regionalConfigId;
}
}
+
+ public void setSatelliteAccessConfigMap(int regionalConfigId,
+ SatelliteAccessConfiguration satelliteAccessConfiguration) {
+ synchronized (mLock) {
+ if (mSatelliteAccessConfigMap == null) {
+ mSatelliteAccessConfigMap = new HashMap<>();
+ }
+ mSatelliteAccessConfigMap.put(regionalConfigId, satelliteAccessConfiguration);
+ }
+ }
+
+ public void resetSatelliteAccessConfigMap() {
+ synchronized (mLock) {
+ if (mSatelliteAccessConfigMap == null) {
+ mSatelliteAccessConfigMap = new HashMap<>();
+ } else {
+ mSatelliteAccessConfigMap.clear();
+ }
+ }
+ }
}
}