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

Commit 924ebf2d authored by Lakshman Annadorai's avatar Lakshman Annadorai Committed by Automerger Merge Worker
Browse files

Update EmulatedUserHal to use UserHalHelper native library. am: 8eb03223 am: bde59e03

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

Change-Id: Iff961af8b7358d4fb274f2c0d45f753c48273a5e
parents d4918ea1 bde59e03
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -108,6 +108,9 @@ cc_library_static {
    srcs: [
        "impl/vhal_v2_0/EmulatedUserHal.cpp",
    ],
    whole_static_libs: [
        "android.hardware.automotive.vehicle@2.0-user-hal-helper-lib",
    ],
}

// Vehicle HAL Server reference impl lib
@@ -143,6 +146,7 @@ cc_library_static {
    ],
    whole_static_libs: [
        "android.hardware.automotive.vehicle@2.0-server-common-lib",
        "android.hardware.automotive.vehicle@2.0-user-hal-helper-lib",
    ],
    static_libs: [
        "android.hardware.automotive.vehicle@2.0-libproto-native",
+113 −109
Original line number Diff line number Diff line
@@ -15,10 +15,12 @@
 */
#define LOG_TAG "EmulatedUserHal"

#include "EmulatedUserHal.h"

#include <cutils/log.h>
#include <utils/SystemClock.h>

#include "EmulatedUserHal.h"
#include "UserHalHelper.h"

namespace android {
namespace hardware {
@@ -28,12 +30,35 @@ namespace V2_0 {

namespace impl {

constexpr int INITIAL_USER_INFO = static_cast<int>(VehicleProperty::INITIAL_USER_INFO);
constexpr int SWITCH_USER = static_cast<int>(VehicleProperty::SWITCH_USER);
constexpr int CREATE_USER = static_cast<int>(VehicleProperty::CREATE_USER);
constexpr int REMOVE_USER = static_cast<int>(VehicleProperty::REMOVE_USER);
constexpr int USER_IDENTIFICATION_ASSOCIATION =
        static_cast<int>(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);
namespace {

using android::base::Error;
using android::base::Result;

constexpr int32_t INITIAL_USER_INFO = static_cast<int32_t>(VehicleProperty::INITIAL_USER_INFO);
constexpr int32_t SWITCH_USER = static_cast<int32_t>(VehicleProperty::SWITCH_USER);
constexpr int32_t CREATE_USER = static_cast<int32_t>(VehicleProperty::CREATE_USER);
constexpr int32_t REMOVE_USER = static_cast<int32_t>(VehicleProperty::REMOVE_USER);
constexpr int32_t USER_IDENTIFICATION_ASSOCIATION =
        static_cast<int32_t>(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);

Result<int32_t> getRequestId(const VehiclePropValue& value) {
    if (value.value.int32Values.size() < 1) {
        return Error(static_cast<int>(StatusCode::INVALID_ARG))
               << "no int32values on " << toString(value);
    }
    return value.value.int32Values[0];
}

Result<SwitchUserMessageType> getSwitchUserMessageType(const VehiclePropValue& value) {
    if (value.value.int32Values.size() < 2) {
        return Error(static_cast<int>(StatusCode::INVALID_ARG))
               << "missing switch user message type " << toString(value);
    }
    return user_hal_helper::verifyAndCast<SwitchUserMessageType>(value.value.int32Values[1]);
}

}  // namespace

bool EmulatedUserHal::isSupported(int32_t prop) {
    switch (prop) {
@@ -48,7 +73,7 @@ bool EmulatedUserHal::isSupported(int32_t prop) {
    }
}

android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetProperty(
Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetProperty(
        const VehiclePropValue& value) {
    ALOGV("onSetProperty(): %s", toString(value).c_str());

@@ -65,12 +90,12 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetP
        case USER_IDENTIFICATION_ASSOCIATION:
            return onSetUserIdentificationAssociation(value);
        default:
            return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
            return Error(static_cast<int>(StatusCode::INVALID_ARG))
                   << "Unsupported property: " << toString(value);
    }
}

android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetProperty(
Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetProperty(
        const VehiclePropValue& value) {
    ALOGV("onGetProperty(%s)", toString(value).c_str());
    switch (value.prop) {
@@ -79,42 +104,41 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetP
        case CREATE_USER:
        case REMOVE_USER:
            ALOGE("onGetProperty(): %d is only supported on SET", value.prop);
            return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
                   << "only supported on SET";
            return Error(static_cast<int>(StatusCode::INVALID_ARG)) << "only supported on SET";
        case USER_IDENTIFICATION_ASSOCIATION:
            return onGetUserIdentificationAssociation(value);
        default:
            ALOGE("onGetProperty(): %d is not supported", value.prop);
            return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
                   << "not supported by User HAL";
            return Error(static_cast<int>(StatusCode::INVALID_ARG)) << "not supported by User HAL";
    }
}

android::base::Result<std::unique_ptr<VehiclePropValue>>
EmulatedUserHal::onGetUserIdentificationAssociation(const VehiclePropValue& value) {
    if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetUserIdentificationAssociation(
        const VehiclePropValue& value) {
    if (mSetUserIdentificationAssociationResponseFromCmd == nullptr) {
        return defaultUserIdentificationAssociation(value);
    }
    ALOGI("get(USER_IDENTIFICATION_ASSOCIATION): returning %s",
          toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
    auto newValue = std::unique_ptr<VehiclePropValue>(
            new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd));
    auto requestId = getRequestId(value);
    if (requestId.ok()) {
        // Must use the same requestId
        if (value.value.int32Values.size() > 0) {
            newValue->value.int32Values[0] = value.value.int32Values[0];
        newValue->value.int32Values[0] = *requestId;
    } else {
            ALOGE("get(USER_IDENTIFICATION_ASSOCIATION): no requestId on %s",
                  toString(value).c_str());
        ALOGE("get(USER_IDENTIFICATION_ASSOCIATION): no requestId on %s", toString(value).c_str());
    }
    return newValue;
}
    return defaultUserIdentificationAssociation(value);
}

android::base::Result<std::unique_ptr<VehiclePropValue>>
EmulatedUserHal::onSetInitialUserInfoResponse(const VehiclePropValue& value) {
    if (value.value.int32Values.size() == 0) {
        ALOGE("set(INITIAL_USER_INFO): no int32values, ignoring it: %s", toString(value).c_str());
        return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
               << "no int32values on " << toString(value);
Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetInitialUserInfoResponse(
        const VehiclePropValue& value) {
    auto requestId = getRequestId(value);
    if (!requestId.ok()) {
        ALOGE("Failed to get requestId on set(INITIAL_USER_INFO): %s",
              requestId.error().message().c_str());
        return requestId.error();
    }

    if (value.areaId != 0) {
@@ -124,40 +148,40 @@ EmulatedUserHal::onSetInitialUserInfoResponse(const VehiclePropValue& value) {
    }

    ALOGD("set(INITIAL_USER_INFO) called from Android: %s", toString(value).c_str());

    int32_t requestId = value.value.int32Values[0];
    if (mInitialUserResponseFromCmd != nullptr) {
        ALOGI("replying INITIAL_USER_INFO with lshal value:  %s",
              toString(*mInitialUserResponseFromCmd).c_str());
        return sendUserHalResponse(std::move(mInitialUserResponseFromCmd), requestId);
        return sendUserHalResponse(std::move(mInitialUserResponseFromCmd), *requestId);
    }

    // Returns default response
    auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
    updatedValue->prop = INITIAL_USER_INFO;
    updatedValue->timestamp = elapsedRealtimeNano();
    updatedValue->value.int32Values.resize(2);
    updatedValue->value.int32Values[0] = requestId;
    updatedValue->value.int32Values[1] = (int32_t)InitialUserInfoResponseAction::DEFAULT;

    auto updatedValue = user_hal_helper::toVehiclePropValue(InitialUserInfoResponse{
            .requestId = *requestId,
            .action = InitialUserInfoResponseAction::DEFAULT,
    });
    ALOGI("no lshal response; replying with InitialUserInfoResponseAction::DEFAULT: %s",
          toString(*updatedValue).c_str());

    return updatedValue;
}

android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetSwitchUserResponse(
Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetSwitchUserResponse(
        const VehiclePropValue& value) {
    if (value.value.int32Values.size() == 0) {
        ALOGE("set(SWITCH_USER): no int32values, ignoring it: %s", toString(value).c_str());
        return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
               << "no int32values on " << toString(value);
    auto requestId = getRequestId(value);
    if (!requestId.ok()) {
        ALOGE("Failed to get requestId on set(SWITCH_USER): %s",
              requestId.error().message().c_str());
        return requestId.error();
    }

    auto messageType = getSwitchUserMessageType(value);
    if (!messageType.ok()) {
        ALOGE("Failed to get messageType on set(SWITCH_USER): %s",
              messageType.error().message().c_str());
        return messageType.error();
    }

    if (value.areaId != 0) {
        if (value.value.int32Values.size() >= 2 &&
            static_cast<SwitchUserMessageType>(value.value.int32Values[1]) ==
                    SwitchUserMessageType::VEHICLE_REQUEST) {
        if (*messageType == SwitchUserMessageType::VEHICLE_REQUEST) {
            // User HAL can also request a user switch, so we need to check it first
            ALOGD("set(SWITCH_USER) called from lshal to emulate a vehicle request: %s",
                  toString(value).c_str());
@@ -170,48 +194,36 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetS
    }
    ALOGD("set(SWITCH_USER) called from Android: %s", toString(value).c_str());

    int32_t requestId = value.value.int32Values[0];
    if (mSwitchUserResponseFromCmd != nullptr) {
        ALOGI("replying SWITCH_USER with lshal value:  %s",
              toString(*mSwitchUserResponseFromCmd).c_str());
        return sendUserHalResponse(std::move(mSwitchUserResponseFromCmd), requestId);
        return sendUserHalResponse(std::move(mSwitchUserResponseFromCmd), *requestId);
    }

    if (value.value.int32Values.size() > 1) {
        auto messageType = static_cast<SwitchUserMessageType>(value.value.int32Values[1]);
        switch (messageType) {
            case SwitchUserMessageType::LEGACY_ANDROID_SWITCH:
                ALOGI("request is LEGACY_ANDROID_SWITCH; ignoring it");
                return {};
            case SwitchUserMessageType::ANDROID_POST_SWITCH:
                ALOGI("request is ANDROID_POST_SWITCH; ignoring it");
    if (*messageType == SwitchUserMessageType::LEGACY_ANDROID_SWITCH ||
        *messageType == SwitchUserMessageType::ANDROID_POST_SWITCH) {
        ALOGI("request is %s; ignoring it", toString(*messageType).c_str());
        return {};
            default:
                break;
        }
    }

    // Returns default response
    auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
    updatedValue->prop = SWITCH_USER;
    updatedValue->timestamp = elapsedRealtimeNano();
    updatedValue->value.int32Values.resize(3);
    updatedValue->value.int32Values[0] = requestId;
    updatedValue->value.int32Values[1] = (int32_t)SwitchUserMessageType::VEHICLE_RESPONSE;
    updatedValue->value.int32Values[2] = (int32_t)SwitchUserStatus::SUCCESS;

    auto updatedValue = user_hal_helper::toVehiclePropValue(SwitchUserResponse{
            .requestId = *requestId,
            .messageType = SwitchUserMessageType::VEHICLE_RESPONSE,
            .status = SwitchUserStatus::SUCCESS,
    });
    ALOGI("no lshal response; replying with VEHICLE_RESPONSE / SUCCESS: %s",
          toString(*updatedValue).c_str());

    return updatedValue;
}

android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetCreateUserResponse(
Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetCreateUserResponse(
        const VehiclePropValue& value) {
    if (value.value.int32Values.size() == 0) {
        ALOGE("set(CREATE_USER): no int32values, ignoring it: %s", toString(value).c_str());
        return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
               << "no int32values on " << toString(value);
    auto requestId = getRequestId(value);
    if (!requestId.ok()) {
        ALOGE("Failed to get requestId on set(CREATE_USER): %s",
              requestId.error().message().c_str());
        return requestId.error();
    }

    if (value.areaId != 0) {
@@ -221,33 +233,28 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetC
    }
    ALOGD("set(CREATE_USER) called from Android: %s", toString(value).c_str());

    int32_t requestId = value.value.int32Values[0];
    if (mCreateUserResponseFromCmd != nullptr) {
        ALOGI("replying CREATE_USER with lshal value:  %s",
              toString(*mCreateUserResponseFromCmd).c_str());
        return sendUserHalResponse(std::move(mCreateUserResponseFromCmd), requestId);
        return sendUserHalResponse(std::move(mCreateUserResponseFromCmd), *requestId);
    }

    // Returns default response
    auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue);
    updatedValue->prop = CREATE_USER;
    updatedValue->timestamp = elapsedRealtimeNano();
    updatedValue->value.int32Values.resize(2);
    updatedValue->value.int32Values[0] = requestId;
    updatedValue->value.int32Values[1] = (int32_t)CreateUserStatus::SUCCESS;

    auto updatedValue = user_hal_helper::toVehiclePropValue(CreateUserResponse{
            .requestId = *requestId,
            .status = CreateUserStatus::SUCCESS,
    });
    ALOGI("no lshal response; replying with SUCCESS: %s", toString(*updatedValue).c_str());

    return updatedValue;
}

android::base::Result<std::unique_ptr<VehiclePropValue>>
EmulatedUserHal::onSetUserIdentificationAssociation(const VehiclePropValue& value) {
    if (value.value.int32Values.size() == 0) {
        ALOGE("set(USER_IDENTIFICATION_ASSOCIATION): no int32values, ignoring it: %s",
              toString(value).c_str());
        return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG))
               << "no int32values on " << toString(value);
Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetUserIdentificationAssociation(
        const VehiclePropValue& value) {
    auto requestId = getRequestId(value);
    if (!requestId.ok()) {
        ALOGE("Failed to get requestId on set(USER_IDENTIFICATION_ASSOCIATION): %s",
              requestId.error().message().c_str());
        return requestId.error();
    }

    if (value.areaId != 0) {
@@ -258,28 +265,26 @@ EmulatedUserHal::onSetUserIdentificationAssociation(const VehiclePropValue& valu
    }
    ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from Android: %s", toString(value).c_str());

    int32_t requestId = value.value.int32Values[0];
    if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
        ALOGI("replying USER_IDENTIFICATION_ASSOCIATION with lshal value:  %s",
              toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
        // Not moving response so it can be used on GET requests
        auto copy = std::unique_ptr<VehiclePropValue>(
                new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd));
        return sendUserHalResponse(std::move(copy), requestId);
        return sendUserHalResponse(std::move(copy), *requestId);
    }

    // Returns default response
    return defaultUserIdentificationAssociation(value);
}

android::base::Result<std::unique_ptr<VehiclePropValue>>
EmulatedUserHal::defaultUserIdentificationAssociation(const VehiclePropValue& request) {
Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::defaultUserIdentificationAssociation(
        const VehiclePropValue& request) {
    // TODO(b/159498909): return a response with NOT_ASSOCIATED_ANY_USER for all requested types
    ALOGE("no lshal response for %s; replying with NOT_AVAILABLE", toString(request).c_str());
    return android::base::Error(static_cast<int>(StatusCode::NOT_AVAILABLE)) << "not set by lshal";
    return Error(static_cast<int>(StatusCode::NOT_AVAILABLE)) << "not set by lshal";
}

android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::sendUserHalResponse(
Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::sendUserHalResponse(
        std::unique_ptr<VehiclePropValue> response, int32_t requestId) {
    switch (response->areaId) {
        case 1:
@@ -293,17 +298,16 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::sendUs
        case 3:
            ALOGD("not generating a property change event because of lshal prop: %s",
                  toString(*response).c_str());
            return android::base::Error(static_cast<int>(StatusCode::NOT_AVAILABLE))
            return Error(static_cast<int>(StatusCode::NOT_AVAILABLE))
                   << "not generating a property change event because of lshal prop: "
                   << toString(*response);
        default:
            ALOGE("invalid action on lshal response: %s", toString(*response).c_str());
            return android::base::Error(static_cast<int>(StatusCode::INTERNAL_ERROR))
            return Error(static_cast<int>(StatusCode::INTERNAL_ERROR))
                   << "invalid action on lshal response: " << toString(*response);
    }

    ALOGD("updating property to: %s", toString(*response).c_str());

    return response;
}

+18 −17
Original line number Diff line number Diff line
@@ -36,22 +36,6 @@ static constexpr const char* kSeparator = "||";
static const size_t kNumFieldsPerUserInfo = 2;
static const size_t kNumFieldsPerSetAssociation = 2;

template <typename T>
Result<T> verifyAndCast(int32_t value) {
    T castValue = static_cast<T>(value);
    const auto iter = hidl_enum_range<T>();
    if (castValue < *iter.begin() || castValue > *std::prev(iter.end())) {
        return Error() << "Value " << value << " not in range [" << toString(*iter.begin()) << ", "
                       << toString(*std::prev(iter.end())) << "]";
    }
    for (const auto& v : hidl_enum_range<T>()) {
        if (castValue == v) {
            return castValue;
        }
    }
    return Error() << "Value " << value << " not in enum values";
}

Result<void> verifyPropValue(const VehiclePropValue& propValue, VehicleProperty vehicleProperty,
                             size_t minInt32Values) {
    auto prop = verifyAndCast<VehicleProperty>(propValue.prop);
@@ -154,6 +138,22 @@ Result<void> parseUserAssociations(const hidl_vec<int32_t>& int32Values, size_t

}  // namespace

template <typename T>
Result<T> verifyAndCast(int32_t value) {
    T castValue = static_cast<T>(value);
    const auto iter = hidl_enum_range<T>();
    if (castValue < *iter.begin() || castValue > *std::prev(iter.end())) {
        return Error() << "Value " << value << " not in range [" << toString(*iter.begin()) << ", "
                       << toString(*std::prev(iter.end())) << "]";
    }
    for (const auto& v : hidl_enum_range<T>()) {
        if (castValue == v) {
            return castValue;
        }
    }
    return Error() << "Value " << value << " not in enum values";
}

Result<InitialUserInfoRequest> toInitialUserInfoRequest(const VehiclePropValue& propValue) {
    auto ret = verifyPropValue(propValue, VehicleProperty::INITIAL_USER_INFO, 2);
    if (!ret.ok()) {
@@ -186,7 +186,8 @@ Result<SwitchUserRequest> toSwitchUserRequest(const VehiclePropValue& propValue)
    if (*messageType != SwitchUserMessageType::LEGACY_ANDROID_SWITCH &&
        *messageType != SwitchUserMessageType::ANDROID_SWITCH &&
        *messageType != SwitchUserMessageType::ANDROID_POST_SWITCH) {
        return Error() << "Invalid " << toString(*messageType) << " from Android System";
        return Error() << "Invalid " << toString(*messageType)
                       << " message type from Android System";
    }
    request.requestId = propValue.value.int32Values[0];
    request.messageType = *messageType;
+5 −0
Original line number Diff line number Diff line
@@ -31,6 +31,11 @@ namespace V2_0 {

namespace user_hal_helper {

// Verify whether the |value| can be casted to the type |T| and return the casted value on success.
// Otherwise, return the error.
template <typename T>
android::base::Result<T> verifyAndCast(int32_t value);

// Below functions parse VehiclePropValues to the respective User HAL request structs. On success,
// these functions return the User HAL struct. Otherwise, they return the error.
android::base::Result<InitialUserInfoRequest> toInitialUserInfoRequest(