diff --git a/radio/config/1.1/Android.bp b/radio/config/1.1/Android.bp index 056510c647..151a0a348d 100644 --- a/radio/config/1.1/Android.bp +++ b/radio/config/1.1/Android.bp @@ -7,10 +7,10 @@ hidl_interface { enabled: true, }, srcs: [ + "types.hal", "IRadioConfig.hal", "IRadioConfigIndication.hal", "IRadioConfigResponse.hal", - "types.hal", ], interfaces: [ "android.hardware.radio.config@1.0", @@ -19,6 +19,7 @@ hidl_interface { ], types: [ "ModemInfo", + "ModemsConfig", "PhoneCapability", ], gen_java: true, diff --git a/radio/config/1.1/IRadioConfig.hal b/radio/config/1.1/IRadioConfig.hal index bc63339e26..7b0c6b61dd 100644 --- a/radio/config/1.1/IRadioConfig.hal +++ b/radio/config/1.1/IRadioConfig.hal @@ -19,6 +19,7 @@ package android.hardware.radio.config@1.1; import @1.0::IRadioConfig; import @1.1::IRadioConfigResponse; import @1.1::PhoneCapability; +import @1.1::ModemsConfig; /** * Note: IRadioConfig 1.1 is an intermediate layer between Android P and Android Q. @@ -56,4 +57,36 @@ interface IRadioConfig extends @1.0::IRadioConfig { * Response callback is IRadioConfigResponse.setPreferredDataModemResponse() */ oneway setPreferredDataModem(int32_t serial, uint8_t modemId); + + /** + * Set modems configurations by specifying the number of live modems (i.e modems that are + * enabled and actively working as part of a working telephony stack). + * + * Example: this interface can be used to switch to single/multi sim mode by specifying + * the number of live modems as 1, 2, etc + * + * Note: by setting the number of live modems in this API, that number of modems will + * subsequently get enabled/disabled + * + * @param serial serial number of request. + * @param modemsConfig ModemsConfig object including the number of live modems + * + * Response callback is IRadioResponse.setModemsConfigResponse() + */ + oneway setModemsConfig(int32_t serial, ModemsConfig modemsConfig); + + /** + * Get modems configurations. This interface is used to get modem configurations + * which includes the number of live modems (i.e modems that are + * enabled and actively working as part of a working telephony stack) + * + * Note: in order to get the overall number of modems available on the phone, + * refer to getPhoneCapability API + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getModemsConfigResponse() which + * will return <@1.1::ModemsConfig>. + */ + oneway getModemsConfig(int32_t serial); }; diff --git a/radio/config/1.1/IRadioConfigResponse.hal b/radio/config/1.1/IRadioConfigResponse.hal index 42a31b1a84..d42ff0627a 100644 --- a/radio/config/1.1/IRadioConfigResponse.hal +++ b/radio/config/1.1/IRadioConfigResponse.hal @@ -19,6 +19,7 @@ package android.hardware.radio.config@1.1; import @1.0::IRadioConfigResponse; import @1.1::PhoneCapability; import android.hardware.radio@1.0::RadioResponseInfo; +import @1.1::ModemsConfig; /** * Note: IRadioConfig 1.1 is an intermediate layer between Android P and Android Q. @@ -50,4 +51,27 @@ interface IRadioConfigResponse extends @1.0::IRadioConfigResponse { * RadioError:INVALID_ARGUMENTS */ oneway setPreferredDataModemResponse(RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + */ + oneway setModemsConfigResponse(RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param modemsConfig <@1.1::ModemsConfig> it defines all the modems' configurations + * at this time, only the number of live modems + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway getModemsConfigResponse(RadioResponseInfo info, ModemsConfig modemsConfig); }; diff --git a/radio/config/1.1/types.hal b/radio/config/1.1/types.hal index a7b9f867e7..89a4723773 100644 --- a/radio/config/1.1/types.hal +++ b/radio/config/1.1/types.hal @@ -61,3 +61,11 @@ struct PhoneCapability { */ vec logicalModemList; }; + +struct ModemsConfig { + /** + * variable to indicate the number of live modems i.e modems that are enabled + * and actively working as part of a working connectivity stack + */ + uint8_t numOfLiveModems; +}; \ No newline at end of file diff --git a/radio/config/1.1/vts/functional/Android.bp b/radio/config/1.1/vts/functional/Android.bp new file mode 100644 index 0000000000..de909a3691 --- /dev/null +++ b/radio/config/1.1/vts/functional/Android.bp @@ -0,0 +1,33 @@ +// +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_test { + name: "VtsHalRadioConfigV1_1TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "radio_config_hidl_hal_api.cpp", + "radio_config_hidl_hal_test.cpp", + "radio_config_response.cpp", + "VtsHalRadioConfigV1_1TargetTest.cpp", + ], + static_libs: [ + "RadioVtsTestUtilBase", + "android.hardware.radio.config@1.0", + "android.hardware.radio.config@1.1", + ], + header_libs: ["radio.util.header@1.0"], + test_suites: ["general-tests"], +} diff --git a/radio/config/1.1/vts/functional/VtsHalRadioConfigV1_1TargetTest.cpp b/radio/config/1.1/vts/functional/VtsHalRadioConfigV1_1TargetTest.cpp new file mode 100644 index 0000000000..2fc6b62345 --- /dev/null +++ b/radio/config/1.1/vts/functional/VtsHalRadioConfigV1_1TargetTest.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +int main(int argc, char** argv) { + ::testing::AddGlobalTestEnvironment(RadioConfigHidlEnvironment::Instance()); + ::testing::InitGoogleTest(&argc, argv); + RadioConfigHidlEnvironment::Instance()->init(&argc, argv); + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + return status; +} diff --git a/radio/config/1.1/vts/functional/radio_config_hidl_hal_api.cpp b/radio/config/1.1/vts/functional/radio_config_hidl_hal_api.cpp new file mode 100644 index 0000000000..a1639d8bb9 --- /dev/null +++ b/radio/config/1.1/vts/functional/radio_config_hidl_hal_api.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) + +/* + * Test IRadioConfig.getModemsConfig() + */ +TEST_F(RadioConfigHidlTest, getModemsConfig) { + serial = GetRandomSerialNumber(); + Return res = radioConfig->getModemsConfig(serial); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioConfigRsp->rspInfo.type); + EXPECT_EQ(serial, radioConfigRsp->rspInfo.serial); + ALOGI("getModemsConfig, rspInfo.error = %s\n", toString(radioConfigRsp->rspInfo.error).c_str()); + + ASSERT_TRUE(CheckAnyOfErrors(radioConfigRsp->rspInfo.error, + {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); +} + +/* + * Test IRadioConfig.setModemsConfig() + */ +TEST_F(RadioConfigHidlTest, setModemsConfig_invalidArgument) { + serial = GetRandomSerialNumber(); + ModemsConfig* mConfig = new ModemsConfig(); + Return res = radioConfig->setModemsConfig(serial, *mConfig); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioConfigRsp->rspInfo.type); + EXPECT_EQ(serial, radioConfigRsp->rspInfo.serial); + ALOGI("setModemsConfig, rspInfo.error = %s\n", toString(radioConfigRsp->rspInfo.error).c_str()); + + ASSERT_TRUE( + CheckAnyOfErrors(radioConfigRsp->rspInfo.error, + {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED})); +} + +/* + * Test IRadioConfig.setModemsConfig() + */ +TEST_F(RadioConfigHidlTest, setModemsConfig_goodRequest) { + serial = GetRandomSerialNumber(); + ModemsConfig* mConfig = new ModemsConfig(); + mConfig->numOfLiveModems = 1; + Return res = radioConfig->setModemsConfig(serial, *mConfig); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioConfigRsp->rspInfo.type); + EXPECT_EQ(serial, radioConfigRsp->rspInfo.serial); + ALOGI("setModemsConfig, rspInfo.error = %s\n", toString(radioConfigRsp->rspInfo.error).c_str()); + + ASSERT_TRUE(CheckAnyOfErrors(radioConfigRsp->rspInfo.error, + {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED})); +} diff --git a/radio/config/1.1/vts/functional/radio_config_hidl_hal_test.cpp b/radio/config/1.1/vts/functional/radio_config_hidl_hal_test.cpp new file mode 100644 index 0000000000..a8c257d8fc --- /dev/null +++ b/radio/config/1.1/vts/functional/radio_config_hidl_hal_test.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +void RadioConfigHidlTest::SetUp() { + radioConfig = ::testing::VtsHalHidlTargetTestBase::getService( + RadioConfigHidlEnvironment::Instance()->getServiceName( + hidl_string(RADIO_SERVICE_NAME))); + if (radioConfig == NULL) { + sleep(60); + radioConfig = ::testing::VtsHalHidlTargetTestBase::getService( + RadioConfigHidlEnvironment::Instance()->getServiceName( + hidl_string(RADIO_SERVICE_NAME))); + } + ASSERT_NE(nullptr, radioConfig.get()); + + radioConfigRsp = new (std::nothrow) RadioConfigResponse(*this); + ASSERT_NE(nullptr, radioConfigRsp.get()); + + count_ = 0; + + radioConfig->setResponseFunctions(radioConfigRsp, nullptr); + EXPECT_EQ(RadioResponseType::SOLICITED, radioConfigRsp->rspInfo.type); + EXPECT_EQ(serial, radioConfigRsp->rspInfo.serial); + EXPECT_EQ(RadioError::NONE, radioConfigRsp->rspInfo.error); +} + +/* + * Notify that the response message is received. + */ +void RadioConfigHidlTest::notify(int receivedSerial) { + std::unique_lock lock(mtx_); + if (serial == receivedSerial) { + count_++; + cv_.notify_one(); + } +} + +/* + * Wait till the response message is notified or till TIMEOUT_PERIOD. + */ +std::cv_status RadioConfigHidlTest::wait() { + std::unique_lock lock(mtx_); + + std::cv_status status = std::cv_status::no_timeout; + auto now = std::chrono::system_clock::now(); + while (count_ == 0) { + status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD)); + if (status == std::cv_status::timeout) { + return status; + } + } + count_--; + return status; +} \ No newline at end of file diff --git a/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h new file mode 100644 index 0000000000..1747ce8f24 --- /dev/null +++ b/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "vts_test_util.h" + +using namespace ::android::hardware::radio::config::V1_1; + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::radio::config::V1_0::SimSlotStatus; +using ::android::hardware::radio::V1_0::RadioResponseInfo; +using ::android::hardware::radio::V1_0::RadioResponseType; + +#define TIMEOUT_PERIOD 75 +#define RADIO_SERVICE_NAME "slot1" + +class RadioConfigHidlTest; + +/* Callback class for radio config response */ +class RadioConfigResponse : public IRadioConfigResponse { + protected: + RadioConfigHidlTest& parent; + + public: + RadioResponseInfo rspInfo; + + RadioConfigResponse(RadioConfigHidlTest& parent); + virtual ~RadioConfigResponse() = default; + + Return getSimSlotsStatusResponse( + const RadioResponseInfo& info, + const ::android::hardware::hidl_vec& slotStatus); + + Return setSimSlotsMappingResponse(const RadioResponseInfo& info); + + Return getPhoneCapabilityResponse(const RadioResponseInfo& info, + const PhoneCapability& phoneCapability); + + Return setPreferredDataModemResponse(const RadioResponseInfo& info); + + Return getModemsConfigResponse(const RadioResponseInfo& info, + const ModemsConfig& mConfig); + + Return setModemsConfigResponse(const RadioResponseInfo& info); +}; + +// Test environment for Radio HIDL HAL. +class RadioConfigHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { + public: + // get the test environment singleton + static RadioConfigHidlEnvironment* Instance() { + static RadioConfigHidlEnvironment* instance = new RadioConfigHidlEnvironment; + return instance; + } + virtual void registerTestServices() override { registerTestService(); } + + private: + RadioConfigHidlEnvironment() {} +}; + +// The main test class for Radio config HIDL. +class RadioConfigHidlTest : public ::testing::VtsHalHidlTargetTestBase { + protected: + std::mutex mtx_; + std::condition_variable cv_; + int count_; + + public: + virtual void SetUp() override; + + /* Used as a mechanism to inform the test about data/event callback */ + void notify(int receivedSerial); + + /* Test code calls this function to wait for response */ + std::cv_status wait(); + + void updateSimCardStatus(); + + /* Serial number for radio request */ + int serial; + + /* radio config service handle */ + sp radioConfig; + + /* radio config response handle */ + sp radioConfigRsp; +}; diff --git a/radio/config/1.1/vts/functional/radio_config_response.cpp b/radio/config/1.1/vts/functional/radio_config_response.cpp new file mode 100644 index 0000000000..8c9e4d75e6 --- /dev/null +++ b/radio/config/1.1/vts/functional/radio_config_response.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +// SimSlotStatus slotStatus; + +RadioConfigResponse::RadioConfigResponse(RadioConfigHidlTest& parent) : parent(parent) {} + +Return RadioConfigResponse::getSimSlotsStatusResponse( + const RadioResponseInfo& /* info */, + const ::android::hardware::hidl_vec& /* slotStatus */) { + return Void(); +} + +Return RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& /* info */) { + return Void(); +} + +Return RadioConfigResponse::getPhoneCapabilityResponse( + const RadioResponseInfo& /* info */, const PhoneCapability& /* phoneCapability */) { + return Void(); +} + +Return RadioConfigResponse::setPreferredDataModemResponse( + const RadioResponseInfo& /* info */) { + return Void(); +} + +Return RadioConfigResponse::getModemsConfigResponse(const RadioResponseInfo& /* info */, + const ModemsConfig& /* mConfig */) { + return Void(); +} + +Return RadioConfigResponse::setModemsConfigResponse(const RadioResponseInfo& /* info */) { + return Void(); +} \ No newline at end of file