1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <android/binder_manager.h>
18 
19 #include "radio_config_utils.h"
20 
21 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
22 
SetUp()23 void RadioConfigTest::SetUp() {
24     RadioServiceTest::SetUp();
25     std::string serviceName = GetParam();
26 
27     radio_config = IRadioConfig::fromBinder(
28             ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
29     ASSERT_NE(nullptr, radio_config.get());
30 
31     radioRsp_config = ndk::SharedRefBase::make<RadioConfigResponse>(*this);
32     ASSERT_NE(nullptr, radioRsp_config.get());
33 
34     radioInd_config = ndk::SharedRefBase::make<RadioConfigIndication>(*this);
35     ASSERT_NE(nullptr, radioInd_config.get());
36 
37     radio_config->setResponseFunctions(radioRsp_config, radioInd_config);
38 }
39 
updateSimSlotStatus()40 void RadioConfigTest::updateSimSlotStatus() {
41     serial = GetRandomSerialNumber();
42     radio_config->getSimSlotsStatus(serial);
43     EXPECT_EQ(std::cv_status::no_timeout, wait());
44     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
45     EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
46     EXPECT_EQ(RadioError::NONE, radioRsp_config->rspInfo.error);
47     // assuming only 1 slot
48     for (const SimSlotStatus& slotStatusResponse : radioRsp_config->simSlotStatus) {
49         slotStatus = slotStatusResponse;
50     }
51 }
52 
53 /*
54  * Test IRadioConfig.getHalDeviceCapabilities() for the response returned.
55  */
TEST_P(RadioConfigTest,getHalDeviceCapabilities)56 TEST_P(RadioConfigTest, getHalDeviceCapabilities) {
57     if (telephony_flags::enforce_telephony_feature_mapping()) {
58         if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
59             GTEST_SKIP() << "Skipping getHalDeviceCapabilities "
60                             "due to undefined FEATURE_TELEPHONY";
61         }
62     }
63 
64     serial = GetRandomSerialNumber();
65     ndk::ScopedAStatus res = radio_config->getHalDeviceCapabilities(serial);
66     ASSERT_OK(res);
67     EXPECT_EQ(std::cv_status::no_timeout, wait());
68     ALOGI("getHalDeviceCapabilities, rspInfo.error = %s\n",
69           toString(radioRsp_config->rspInfo.error).c_str());
70 }
71 
72 /*
73  * Test IRadioConfig.getSimSlotsStatus() for the response returned.
74  */
TEST_P(RadioConfigTest,getSimSlotsStatus)75 TEST_P(RadioConfigTest, getSimSlotsStatus) {
76     if (telephony_flags::enforce_telephony_feature_mapping()) {
77         if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
78             GTEST_SKIP() << "Skipping getSimSlotsStatus "
79                             "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
80         }
81     }
82 
83     serial = GetRandomSerialNumber();
84     ndk::ScopedAStatus res = radio_config->getSimSlotsStatus(serial);
85     ASSERT_OK(res);
86     EXPECT_EQ(std::cv_status::no_timeout, wait());
87     ALOGI("getSimSlotsStatus, rspInfo.error = %s\n",
88           toString(radioRsp_config->rspInfo.error).c_str());
89 }
90 
91 /*
92  * Test IRadioConfig.getPhoneCapability() for the response returned.
93  */
TEST_P(RadioConfigTest,getPhoneCapability)94 TEST_P(RadioConfigTest, getPhoneCapability) {
95     if (telephony_flags::enforce_telephony_feature_mapping()) {
96         if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
97             GTEST_SKIP() << "Skipping getPhoneCapability "
98                             "due to undefined FEATURE_TELEPHONY";
99         }
100     }
101 
102     serial = GetRandomSerialNumber();
103     ndk::ScopedAStatus res = radio_config->getPhoneCapability(serial);
104     ASSERT_OK(res);
105     EXPECT_EQ(std::cv_status::no_timeout, wait());
106     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
107     EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
108     ALOGI("getPhoneCapability, rspInfo.error = %s\n",
109           toString(radioRsp_config->rspInfo.error).c_str());
110 
111     ASSERT_TRUE(CheckAnyOfErrors(
112             radioRsp_config->rspInfo.error,
113             {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
114 
115     if (radioRsp_config->rspInfo.error == RadioError ::NONE) {
116         // maxActiveData should be greater than or equal to maxActiveInternetData.
117         EXPECT_GE(radioRsp_config->phoneCap.maxActiveData,
118                   radioRsp_config->phoneCap.maxActiveInternetData);
119         // maxActiveData and maxActiveInternetData should be 0 or positive numbers.
120         EXPECT_GE(radioRsp_config->phoneCap.maxActiveInternetData, 0);
121     }
122 }
123 
124 /*
125  * Test IRadioConfig.getSimultaneousCallingSupport() for the response returned.
126  */
TEST_P(RadioConfigTest,getSimultaneousCallingSupport)127 TEST_P(RadioConfigTest, getSimultaneousCallingSupport) {
128     if (telephony_flags::enforce_telephony_feature_mapping()) {
129         if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
130             GTEST_SKIP() << "Skipping getSimultaneousCallingSupport "
131                             "due to undefined FEATURE_TELEPHONY";
132         }
133     }
134 
135     int32_t aidl_version;
136     ndk::ScopedAStatus aidl_status = radio_config->getInterfaceVersion(&aidl_version);
137     ASSERT_OK(aidl_status);
138     if (aidl_version < 3) {
139         ALOGI("Skipped the test since"
140                 " getSimultaneousCallingSupport is not supported on version < 3.");
141         GTEST_SKIP();
142     }
143 
144     serial = GetRandomSerialNumber();
145     ndk::ScopedAStatus res = radio_config->getSimultaneousCallingSupport(serial);
146     ASSERT_OK(res);
147     EXPECT_EQ(std::cv_status::no_timeout, wait());
148     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
149     EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
150     ALOGI("getSimultaneousCallingSupport, rspInfo.error = %s\n",
151           toString(radioRsp_config->rspInfo.error).c_str());
152 
153     // REQUEST_NOT_SUPPORTED is omitted here because users of the V3 HAL should implement this
154     // method and return at least an empty array
155     ASSERT_TRUE(CheckAnyOfErrors(
156             radioRsp_config->rspInfo.error,
157             {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
158             RadioError::MODEM_ERR}));
159 
160     if (radioRsp_config->rspInfo.error == RadioError ::NONE) {
161         // The size of enabledLogicalSLots should be 0 or a positive number:
162         EXPECT_GE(radioRsp_config->currentEnabledLogicalSlots.size(), 0);
163     }
164 }
165 
166 /*
167  * Test IRadioConfig.setPreferredDataModem() for the response returned.
168  */
TEST_P(RadioConfigTest,setPreferredDataModem)169 TEST_P(RadioConfigTest, setPreferredDataModem) {
170     if (telephony_flags::enforce_telephony_feature_mapping()) {
171         if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
172             GTEST_SKIP() << "Skipping setPreferredDataModem "
173                             "due to undefined FEATURE_TELEPHONY_DATA";
174         }
175     }
176 
177     serial = GetRandomSerialNumber();
178     ndk::ScopedAStatus res = radio_config->getPhoneCapability(serial);
179     ASSERT_OK(res);
180     EXPECT_EQ(std::cv_status::no_timeout, wait());
181     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
182     EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
183     ALOGI("getPhoneCapability, rspInfo.error = %s\n",
184           toString(radioRsp_config->rspInfo.error).c_str());
185 
186     ASSERT_TRUE(CheckAnyOfErrors(
187             radioRsp_config->rspInfo.error,
188             {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
189 
190     if (radioRsp_config->rspInfo.error != RadioError ::NONE) {
191         return;
192     }
193 
194     if (radioRsp_config->phoneCap.logicalModemIds.size() == 0) {
195         return;
196     }
197 
198     // We get phoneCapability. Send setPreferredDataModem command
199     serial = GetRandomSerialNumber();
200     uint8_t modemId = radioRsp_config->phoneCap.logicalModemIds[0];
201     res = radio_config->setPreferredDataModem(serial, modemId);
202 
203     ASSERT_OK(res);
204     EXPECT_EQ(std::cv_status::no_timeout, wait());
205     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
206     EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
207     ALOGI("setPreferredDataModem, rspInfo.error = %s\n",
208           toString(radioRsp_config->rspInfo.error).c_str());
209 
210     ASSERT_TRUE(CheckAnyOfErrors(
211             radioRsp_config->rspInfo.error,
212             {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR}));
213 }
214 
215 /*
216  * Test IRadioConfig.setPreferredDataModem() with invalid arguments.
217  */
TEST_P(RadioConfigTest,setPreferredDataModem_invalidArgument)218 TEST_P(RadioConfigTest, setPreferredDataModem_invalidArgument) {
219     if (telephony_flags::enforce_telephony_feature_mapping()) {
220         if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
221             GTEST_SKIP() << "Skipping setPreferredDataModem_invalidArgument "
222                             "due to undefined FEATURE_TELEPHONY_DATA";
223         }
224     }
225 
226     serial = GetRandomSerialNumber();
227     uint8_t modemId = -1;
228     ndk::ScopedAStatus res = radio_config->setPreferredDataModem(serial, modemId);
229 
230     ASSERT_OK(res);
231     EXPECT_EQ(std::cv_status::no_timeout, wait());
232     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
233     EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
234     ALOGI("setPreferredDataModem, rspInfo.error = %s\n",
235           toString(radioRsp_config->rspInfo.error).c_str());
236 
237     ASSERT_TRUE(CheckAnyOfErrors(radioRsp_config->rspInfo.error,
238                                  {RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE,
239                                   RadioError::INTERNAL_ERR}));
240 }
241 
242 /*
243  * Test IRadioConfig.setSimSlotsMapping() for the response returned.
244  */
TEST_P(RadioConfigTest,setSimSlotsMapping)245 TEST_P(RadioConfigTest, setSimSlotsMapping) {
246     if (telephony_flags::enforce_telephony_feature_mapping()) {
247         if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
248             GTEST_SKIP() << "Skipping setSimSlotsMapping "
249                             "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
250         }
251     }
252 
253     // get slot status and set SIM slots mapping based on the result.
254     updateSimSlotStatus();
255     if (radioRsp_config->rspInfo.error == RadioError::NONE) {
256         SlotPortMapping slotPortMapping;
257         // put invalid value at first and adjust by slotStatusResponse.
258         slotPortMapping.physicalSlotId = -1;
259         slotPortMapping.portId = -1;
260         std::vector<SlotPortMapping> slotPortMappingList = {slotPortMapping};
261         if (isDsDsEnabled() || isDsDaEnabled()) {
262             slotPortMappingList.push_back(slotPortMapping);
263         } else if (isTsTsEnabled()) {
264             slotPortMappingList.push_back(slotPortMapping);
265             slotPortMappingList.push_back(slotPortMapping);
266         }
267         for (size_t i = 0; i < radioRsp_config->simSlotStatus.size(); i++) {
268             ASSERT_TRUE(radioRsp_config->simSlotStatus[i].portInfo.size() > 0);
269             for (size_t j = 0; j < radioRsp_config->simSlotStatus[i].portInfo.size(); j++) {
270                 if (radioRsp_config->simSlotStatus[i].portInfo[j].portActive) {
271                     int32_t logicalSlotId =
272                             radioRsp_config->simSlotStatus[i].portInfo[j].logicalSlotId;
273                     // logicalSlotId should be 0 or positive numbers if the port
274                     // is active.
275                     EXPECT_GE(logicalSlotId, 0);
276                     // logicalSlotId should be less than the maximum number of
277                     // supported SIM slots.
278                     EXPECT_LT(logicalSlotId, slotPortMappingList.size());
279                     if (logicalSlotId >= 0 && logicalSlotId < slotPortMappingList.size()) {
280                         slotPortMappingList[logicalSlotId].physicalSlotId = i;
281                         if (radioRsp_config->simSlotStatus[i].supportedMepMode ==
282                                     MultipleEnabledProfilesMode::MEP_A1 ||
283                             radioRsp_config->simSlotStatus[i].supportedMepMode ==
284                                     MultipleEnabledProfilesMode::MEP_A2) {
285                             slotPortMappingList[logicalSlotId].portId = j + 1;
286                         } else {
287                             slotPortMappingList[logicalSlotId].portId = j;
288                         }
289                     }
290                 }
291             }
292         }
293 
294         // set SIM slots mapping
295         for (size_t i = 0; i < slotPortMappingList.size(); i++) {
296             // physicalSlotId and portId should be 0 or positive numbers for the
297             // input of setSimSlotsMapping.
298             EXPECT_GE(slotPortMappingList[i].physicalSlotId, 0);
299             EXPECT_GE(slotPortMappingList[i].portId, 0);
300         }
301         serial = GetRandomSerialNumber();
302         ndk::ScopedAStatus res = radio_config->setSimSlotsMapping(serial, slotPortMappingList);
303         ASSERT_OK(res);
304         EXPECT_EQ(std::cv_status::no_timeout, wait());
305         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
306         EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
307         ALOGI("setSimSlotsMapping, rspInfo.error = %s\n",
308               toString(radioRsp_config->rspInfo.error).c_str());
309         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_config->rspInfo.error, {RadioError::NONE}));
310 
311         // Give some time for modem to fully switch SIM configuration
312         sleep(MODEM_SET_SIM_SLOT_MAPPING_DELAY_IN_SECONDS);
313     }
314 }
315 
316 /*
317  * Test IRadioConfig.getSimSlotStatus() for the response returned.
318  */
319 
TEST_P(RadioConfigTest,checkPortInfoExistsAndPortActive)320 TEST_P(RadioConfigTest, checkPortInfoExistsAndPortActive) {
321     if (telephony_flags::enforce_telephony_feature_mapping()) {
322         if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
323             GTEST_SKIP() << "Skipping checkPortInfoExistsAndPortActive "
324                             "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
325         }
326     }
327 
328     serial = GetRandomSerialNumber();
329     ndk::ScopedAStatus res = radio_config->getSimSlotsStatus(serial);
330     ASSERT_OK(res);
331     ALOGI("getSimSlotsStatus, rspInfo.error = %s\n",
332           toString(radioRsp_config->rspInfo.error).c_str());
333     EXPECT_EQ(std::cv_status::no_timeout, wait());
334     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
335     EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
336     if (radioRsp_config->rspInfo.error == RadioError::NONE) {
337         uint8_t simCount = 0;
338         // check if cardState is present, portInfo size should be more than 0
339         for (const SimSlotStatus& slotStatusResponse : radioRsp_config->simSlotStatus) {
340             if (slotStatusResponse.cardState == CardStatus::STATE_PRESENT) {
341                 ASSERT_TRUE(slotStatusResponse.portInfo.size() > 0);
342                 for (const SimPortInfo& simPortInfo : slotStatusResponse.portInfo) {
343                     if (simPortInfo.portActive) {
344                         simCount++;
345                     }
346                 }
347             }
348         }
349         if (isSsSsEnabled()) {
350             EXPECT_EQ(1, simCount);
351         } else if (isDsDsEnabled() || isDsDaEnabled()) {
352             EXPECT_EQ(2, simCount);
353         } else if (isTsTsEnabled()) {
354             EXPECT_EQ(3, simCount);
355         }
356     }
357 }
358