Merge "Add emergencyDial_1_6 in the HAL to modify the multisim logic for pin lock" am: 0c5fec28d2

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1568866

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Id099b0cbc19a1be0c1084059bfdc7aca3d895c4e
This commit is contained in:
Shuo Qian 2021-02-08 23:31:11 +00:00 committed by Automerger Merge Worker
commit 78d2245b33
5 changed files with 254 additions and 4 deletions

View file

@ -18,9 +18,12 @@ package android.hardware.radio@1.6;
import @1.0::CdmaSmsMessage;
import @1.0::Dial;
import @1.0::GsmSmsMessage;
import @1.1::CardPowerState;
import @1.2::DataRequestReason;
import @1.4::EmergencyCallRouting;
import @1.4::EmergencyServiceCategory;
import @1.4::RadioAccessFamily;
import @1.5::IRadio;
import @1.5::AccessNetwork;
@ -374,6 +377,64 @@ interface IRadio extends @1.5::IRadio {
DataThrottlingAction dataThrottlingAction,
int64_t completionDurationMillis);
/**
* Initiate emergency voice call, with zero or more emergency service category(s), zero or
* more emergency Uniform Resource Names (URN), and routing information for handling the call.
* Android uses this request to make its emergency call instead of using @1.0::IRadio.dial
* if the 'address' in the 'dialInfo' field is identified as an emergency number by Android.
*
* In multi-sim scenario, if the emergency number is from a specific subscription, this radio
* request can still be sent out on the other subscription as long as routing is set to
* @1.4::EmergencyNumberRouting#EMERGENCY. This radio request will not be sent on an inactive
* (PIN/PUK locked) subscription unless both subscriptions are PIN/PUK locked. In this case,
* the request will be sent on the primary subscription.
*
* Some countries or carriers require some emergency numbers that must be handled with normal
* call routing if possible or emergency routing. 1) if the 'routing' field is specified as
* @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to
* use normal call routing to handle the call; if service cannot support normal routing, the
* implementation must use emergency routing to handle the call. 2) if 'routing' is specified
* as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to
* handle the call. 3) if 'routing' is specified as @1.4::EmergencyNumberRouting#UNKNOWN,
* Android does not know how to handle the call.
*
* If the dialed emergency number does not have a specified emergency service category, the
* 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed
* emergency number does not have specified emergency Uniform Resource Names, the 'urns' field
* is set to an empty list. If the underlying technology used to request emergency services
* does not support the emergency service category or emergency uniform resource names, the
* field 'categories' or 'urns' may be ignored.
*
* In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the
* emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's
* intent for this dial request is emergency call, and the modem must treat this as an actual
* emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know
* user's intent for this call.
*
* If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real
* emergency service; otherwise it's for a real emergency call request.
*
* Reference: 3gpp 22.101, Section 10 - Emergency Calls;
* 3gpp 23.167, Section 6 - Functional description;
* 3gpp 24.503, Section 5.1.6.8.1 - General;
* RFC 5031
*
* @param serial Serial number of request.
* @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial.
* @param categories bitfield<@1.4::EmergencyServiceCategory> the Emergency Service Category(s)
* of the call.
* @param urns the emergency Uniform Resource Names (URN)
* @param routing @1.4::EmergencyCallRouting the emergency call routing information.
* @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call
* is known.
* @param isTesting Flag indicating if this request is for testing purpose.
*
* Response function is IRadioResponse.emergencyDialResponse()
*/
oneway emergencyDial_1_6(int32_t serial, Dial dialInfo,
bitfield<EmergencyServiceCategory> categories, vec<string> urns,
EmergencyCallRouting routing, bool hasKnownUserIntentEmergency, bool isTesting);
/**
* Get which bands the modem's background scan is acting on.
*

View file

@ -411,6 +411,167 @@ TEST_P(RadioHidlTest_v1_6, setSimCardPower_1_6) {
}
}
/*
* Test IRadio.emergencyDial() for the response returned.
*/
TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6) {
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
}
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_0::Dial dialInfo;
dialInfo.address = hidl_string("911");
int categories = static_cast<int>(
::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED);
std::vector<hidl_string> urns = {""};
::android::hardware::radio::V1_4::EmergencyCallRouting routing =
::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN;
Return<void> res =
radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true);
ASSERT_OK(res);
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type);
EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial);
ALOGI("emergencyDial, rspInfo_v1_0.error = %s\n",
toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str());
::android::hardware::radio::V1_0::RadioError rspEmergencyDial =
radioRsp_v1_6->rspInfo_v1_0.error;
// In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
// or Emergency_Only.
if (isDsDsEnabled() || isTsTsEnabled()) {
serial = GetRandomSerialNumber();
radio_v1_6->getVoiceRegistrationState(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) ||
isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) {
EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
}
} else {
EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
}
// Give some time for modem to establish the emergency call channel.
sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
// Disconnect all the potential established calls to prevent them affecting other tests.
clearPotentialEstablishedCalls();
}
/*
* Test IRadio.emergencyDial() with specified service and its response returned.
*/
TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withServices) {
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
}
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_0::Dial dialInfo;
dialInfo.address = hidl_string("911");
int categories =
static_cast<int>(::android::hardware::radio::V1_4::EmergencyServiceCategory::AMBULANCE);
std::vector<hidl_string> urns = {"urn:service:sos.ambulance"};
::android::hardware::radio::V1_4::EmergencyCallRouting routing =
::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN;
Return<void> res =
radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true);
ASSERT_OK(res);
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type);
EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial);
ALOGI("emergencyDial_withServices, rspInfo_v1_0.error = %s\n",
toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str());
::android::hardware::radio::V1_0::RadioError rspEmergencyDial =
radioRsp_v1_6->rspInfo_v1_0.error;
// In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
// or Emergency_Only.
if (isDsDsEnabled() || isTsTsEnabled()) {
serial = GetRandomSerialNumber();
radio_v1_6->getVoiceRegistrationState(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) ||
isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) {
EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
}
} else {
EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
}
// Give some time for modem to establish the emergency call channel.
sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
// Disconnect all the potential established calls to prevent them affecting other tests.
clearPotentialEstablishedCalls();
}
/*
* Test IRadio.emergencyDial() with known emergency call routing and its response returned.
*/
TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withEmergencyRouting) {
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
}
serial = GetRandomSerialNumber();
::android::hardware::radio::V1_0::Dial dialInfo;
dialInfo.address = hidl_string("911");
int categories = static_cast<int>(
::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED);
std::vector<hidl_string> urns = {""};
::android::hardware::radio::V1_4::EmergencyCallRouting routing =
::android::hardware::radio::V1_4::EmergencyCallRouting::EMERGENCY;
Return<void> res =
radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true);
ASSERT_OK(res);
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type);
EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial);
ALOGI("emergencyDial_withEmergencyRouting, rspInfo_v1_0.error = %s\n",
toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str());
::android::hardware::radio::V1_0::RadioError rspEmergencyDial =
radioRsp_v1_6->rspInfo_v1_0.error;
// In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
// or Emergency_Only.
if (isDsDsEnabled() || isTsTsEnabled()) {
serial = GetRandomSerialNumber();
radio_v1_6->getVoiceRegistrationState(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) ||
isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) {
EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
}
} else {
EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
}
// Give some time for modem to establish the emergency call channel.
sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
// Disconnect all the potential established calls to prevent them affecting other tests.
clearPotentialEstablishedCalls();
}
/*
* Test IRadio.getCurrentCalls_1_6() for the response returned.
*/

View file

@ -74,6 +74,29 @@ std::cv_status RadioHidlTest_v1_6::wait() {
return status;
}
void RadioHidlTest_v1_6::clearPotentialEstablishedCalls() {
// Get the current call Id to hangup the established emergency call.
serial = GetRandomSerialNumber();
radio_v1_6->getCurrentCalls_1_6(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
// Hang up to disconnect the established call channels.
for (const ::android::hardware::radio::V1_6::Call& call : radioRsp_v1_6->currentCalls) {
serial = GetRandomSerialNumber();
radio_v1_6->hangup(serial, call.base.base.index);
ALOGI("Hang up to disconnect the established call channel: %d", call.base.base.index);
EXPECT_EQ(std::cv_status::no_timeout, wait());
// Give some time for modem to disconnect the established call channel.
sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME);
}
// Verify there are no more current calls.
serial = GetRandomSerialNumber();
radio_v1_6->getCurrentCalls_1_6(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
EXPECT_EQ(0, radioRsp_v1_6->currentCalls.size());
}
void RadioHidlTest_v1_6::updateSimCardStatus() {
serial = GetRandomSerialNumber();
radio_v1_6->getIccCardStatus(serial);

View file

@ -70,7 +70,8 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon
::android::hardware::radio::V1_6::RadioResponseInfo rspInfo;
// Call
hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
hidl_vec<::android::hardware::radio::V1_6::Call> currentCalls;
::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp;
// Sms
SendSmsResult sendSmsResult;

View file

@ -816,8 +816,11 @@ Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_2(
}
Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_2(
const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) {
const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) {
rspInfo_v1_0 = info;
voiceRegResp = voiceRegResponse;
parent_v1_6.notify(info.serial);
return Void();
}
@ -1210,8 +1213,9 @@ Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse_1_6(
Return<void> RadioResponse_v1_6::getCurrentCallsResponse_1_6(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& /*calls*/) {
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls) {
rspInfo = info;
currentCalls = calls;
parent_v1_6.notify(info.serial);
return Void();
}