Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78d2245b authored by Shuo Qian's avatar Shuo Qian Committed by Automerger Merge Worker
Browse files

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

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

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Id099b0cbc19a1be0c1084059bfdc7aca3d895c4e
parents bf10e12b 0c5fec28
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
@@ -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.
     *
+161 −0
Original line number Diff line number Diff line
@@ -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.
 */
+23 −0
Original line number Diff line number Diff line
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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;
+7 −3
Original line number Diff line number Diff line
@@ -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();
}